diff options
| author | Garrett D'Amore <garrett@damore.org> | 2020-05-24 16:20:13 -0700 |
|---|---|---|
| committer | Garrett D'Amore <garrett@damore.org> | 2020-05-25 06:56:08 -0700 |
| commit | 79aed583c14424dcb737eafcdc5273cc4ed40d75 (patch) | |
| tree | 170c4d4d461cc09fee9519fceebdeb8a15a86da4 /src/protocol | |
| parent | 7af3747a3579eea07080df2693d89e2061520392 (diff) | |
| download | nng-79aed583c14424dcb737eafcdc5273cc4ed40d75.tar.gz nng-79aed583c14424dcb737eafcdc5273cc4ed40d75.tar.bz2 nng-79aed583c14424dcb737eafcdc5273cc4ed40d75.zip | |
fixes #1241 SIGSEGV in RepReq's rep0 recv - use after free
This also affects the respondent protocol. Examination of the other
protocols did not turn up any evidence of the same issue.
Diffstat (limited to 'src/protocol')
| -rw-r--r-- | src/protocol/reqrep0/rep.c | 10 | ||||
| -rw-r--r-- | src/protocol/reqrep0/req.c | 2 | ||||
| -rw-r--r-- | src/protocol/survey0/respond.c | 10 |
3 files changed, 22 insertions, 0 deletions
diff --git a/src/protocol/reqrep0/rep.c b/src/protocol/reqrep0/rep.c index d0cc0d55..e750ef56 100644 --- a/src/protocol/reqrep0/rep.c +++ b/src/protocol/reqrep0/rep.c @@ -59,6 +59,7 @@ struct rep0_pipe { nni_list_node rnode; // receivable list linkage nni_list sendq; // contexts waiting to send bool busy; + bool closed; }; static void @@ -331,6 +332,7 @@ rep0_pipe_close(void *arg) nni_aio_close(&p->aio_recv); nni_mtx_lock(&s->lk); + p->closed = true; if (nni_list_active(&s->recvpipes, p)) { // We are no longer "receivable". nni_list_remove(&s->recvpipes, p); @@ -530,6 +532,14 @@ rep0_pipe_recv_cb(void *arg) nni_mtx_lock(&s->lk); + if (p->closed) { + // If we are closed, then we can't return data. + nni_aio_set_msg(&p->aio_recv, NULL); + nni_mtx_unlock(&s->lk); + nni_msg_free(msg); + return; + } + if ((ctx = nni_list_first(&s->recvq)) == NULL) { // No one waiting to receive yet, holding pattern. nni_list_append(&s->recvpipes, p); diff --git a/src/protocol/reqrep0/req.c b/src/protocol/reqrep0/req.c index cb716941..0112f835 100644 --- a/src/protocol/reqrep0/req.c +++ b/src/protocol/reqrep0/req.c @@ -311,6 +311,8 @@ req0_recv_cb(void *arg) // Schedule another receive while we are processing this. nni_mtx_lock(&s->mtx); + + // NB: If close was called, then this will just abort. nni_pipe_recv(p->pipe, &p->aio_recv); // Look for a context to receive it. diff --git a/src/protocol/survey0/respond.c b/src/protocol/survey0/respond.c index 580aa743..b414c189 100644 --- a/src/protocol/survey0/respond.c +++ b/src/protocol/survey0/respond.c @@ -63,6 +63,7 @@ struct resp0_pipe { nni_pipe * npipe; resp0_sock * psock; bool busy; + bool closed; uint32_t id; nni_list sendq; // contexts waiting to send nni_aio aio_send; @@ -336,6 +337,7 @@ resp0_pipe_close(void *arg) nni_aio_close(&p->aio_recv); nni_mtx_lock(&s->mtx); + p->closed = true; while ((ctx = nni_list_first(&p->sendq)) != NULL) { nni_aio *aio; nni_msg *msg; @@ -522,6 +524,14 @@ resp0_pipe_recv_cb(void *arg) len = nni_msg_header_len(msg); nni_mtx_lock(&s->mtx); + + if (p->closed) { + // If pipe was closed, we just abandon the data from it. + nni_aio_set_msg(&p->aio_recv, NULL); + nni_mtx_unlock(&s->mtx); + nni_msg_free(msg); + return; + } if ((ctx = nni_list_first(&s->recvq)) == NULL) { // No one blocked in recv, stall. nni_list_append(&s->recvpipes, p); |
