diff options
| author | Garrett D'Amore <garrett@damore.org> | 2017-01-07 22:45:58 -0800 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2017-01-07 22:45:58 -0800 |
| commit | 343faafe5cfc2ae990954e1de3c6010b82e81f89 (patch) | |
| tree | 3cb40639d056600d4e315c15e715c055935dc9bb /src/core/socket.c | |
| parent | cb01bb934be4432252c80d139682bfea23c3efa8 (diff) | |
| download | nng-343faafe5cfc2ae990954e1de3c6010b82e81f89.tar.gz nng-343faafe5cfc2ae990954e1de3c6010b82e81f89.tar.bz2 nng-343faafe5cfc2ae990954e1de3c6010b82e81f89.zip | |
More close race fixing.
Don't drop the lock in sock_close while holding the pipe reference.
I'm pretty sure this is responsible for the use-after-free race.
Diffstat (limited to 'src/core/socket.c')
| -rw-r--r-- | src/core/socket.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/src/core/socket.c b/src/core/socket.c index 6b4054e9..ad8e5703 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -61,6 +61,10 @@ nni_reaper(void *arg) nni_mtx_unlock(&sock->s_mx); // XXX: also publish event... + + // There should be no references left to this pipe. + // The various threads will have shutdown, except + // the threads that this waits for. nni_pipe_destroy(pipe); continue; } @@ -324,15 +328,20 @@ nni_sock_shutdown(nni_sock *sock) // the protocol a chance to flush its write side. Now its time // to be a little more insistent. - // Close the upper read queue immediately. This can happen + // Close the upper queues immediately. This can happen // safely while we hold the lock. nni_msgq_close(sock->s_urq); + nni_msgq_close(sock->s_uwq); - // Go through and schedule close on all pipes. + // For each pipe, close the underlying transport, and move it to + // deathrow (the reaplist). while ((pipe = nni_list_first(&sock->s_pipes)) != NULL) { - nni_mtx_unlock(&sock->s_mx); - nni_pipe_close(pipe); - nni_mtx_lock(&sock->s_mx); + if (pipe->p_tran_data != NULL) { + pipe->p_tran_ops.pipe_close(pipe->p_tran_data); + } + pipe->p_reap = 1; + nni_list_remove(&sock->s_pipes, pipe); + nni_list_append(&sock->s_reaps, pipe); } sock->s_sock_ops.sock_close(sock->s_data); |
