aboutsummaryrefslogtreecommitdiff
path: root/src/protocol
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2020-05-24 16:20:13 -0700
committerGarrett D'Amore <garrett@damore.org>2020-05-25 06:56:08 -0700
commit79aed583c14424dcb737eafcdc5273cc4ed40d75 (patch)
tree170c4d4d461cc09fee9519fceebdeb8a15a86da4 /src/protocol
parent7af3747a3579eea07080df2693d89e2061520392 (diff)
downloadnng-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.c10
-rw-r--r--src/protocol/reqrep0/req.c2
-rw-r--r--src/protocol/survey0/respond.c10
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);