diff options
author | Igor Sysoev <igor@sysoev.ru> | 2018-02-08 16:51:49 +0300 |
---|---|---|
committer | Igor Sysoev <igor@sysoev.ru> | 2018-02-08 16:51:49 +0300 |
commit | 11d5206866f88740f29fd42b060fc3152b764ae4 (patch) | |
tree | 1922add400dfef631e1a0132b0014e1e80bed88e /src/nxt_router.c | |
parent | 0d032c10369ffa9489a274e5a887009bbad24e49 (diff) | |
download | unit-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.c | 14 |
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); } } |