summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_router.c
diff options
context:
space:
mode:
authorIgor Sysoev <igor@sysoev.ru>2018-02-08 16:51:49 +0300
committerIgor Sysoev <igor@sysoev.ru>2018-02-08 16:51:49 +0300
commit11d5206866f88740f29fd42b060fc3152b764ae4 (patch)
tree1922add400dfef631e1a0132b0014e1e80bed88e /src/nxt_router.c
parent0d032c10369ffa9489a274e5a887009bbad24e49 (diff)
downloadunit-11d5206866f88740f29fd42b060fc3152b764ae4.tar.gz
unit-11d5206866f88740f29fd42b060fc3152b764ae4.tar.bz2
Router: fixed freed memory access race condition.
Diffstat (limited to 'src/nxt_router.c')
-rw-r--r--src/nxt_router.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/src/nxt_router.c b/src/nxt_router.c
index e8003c11..e9e2685e 100644
--- a/src/nxt_router.c
+++ b/src/nxt_router.c
@@ -2502,7 +2502,6 @@ nxt_router_listen_socket_release(nxt_task_t *task, nxt_socket_conf_t *skcf)
static void
nxt_router_conf_release(nxt_task_t *task, nxt_socket_conf_joint_t *joint)
{
- nxt_bool_t exit;
nxt_socket_conf_t *skcf;
nxt_router_conf_t *rtcf;
nxt_event_engine_t *engine;
@@ -2516,6 +2515,13 @@ nxt_router_conf_release(nxt_task_t *task, nxt_socket_conf_joint_t *joint)
nxt_queue_remove(&joint->link);
+ /*
+ * The joint content can not be safely used after the critical
+ * section protected by the spinlock because its memory pool may
+ * be already destroyed by another thread.
+ */
+ engine = joint->engine;
+
skcf = joint->socket_conf;
rtcf = skcf->router_conf;
lock = &rtcf->router->lock;
@@ -2541,10 +2547,6 @@ nxt_router_conf_release(nxt_task_t *task, nxt_socket_conf_joint_t *joint)
/* TODO remove engine->port */
/* TODO excude from connected ports */
- /* The joint content can be used before memory pool destruction. */
- engine = joint->engine;
- exit = (engine->shutdown && nxt_queue_is_empty(&engine->joints));
-
if (rtcf != NULL) {
nxt_debug(task, "old router conf is destroyed");
@@ -2553,7 +2555,7 @@ nxt_router_conf_release(nxt_task_t *task, nxt_socket_conf_joint_t *joint)
nxt_mp_destroy(rtcf->mem_pool);
}
- if (exit) {
+ if (engine->shutdown && nxt_queue_is_empty(&engine->joints)) {
nxt_thread_exit(task->thread);
}
}