From 40542e7af0f5003d7ad67876ea580a59174031ca Mon Sep 17 00:00:00 2001 From: Garrett D'Amore Date: Tue, 17 Apr 2018 15:38:06 -0700 Subject: fixes #355 Possible use after free in REP While here I've added some code that should help us backtrack on a crash, by linking back to the pipe from the context when we are queued on that pipes sendq. I'm not sure if we've ever seen these or not, but it could explain certain infrequent crashes we think we've seen. --- src/protocol/reqrep0/rep.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'src/protocol/reqrep0') diff --git a/src/protocol/reqrep0/rep.c b/src/protocol/reqrep0/rep.c index e512c18b..e18675ee 100644 --- a/src/protocol/reqrep0/rep.c +++ b/src/protocol/reqrep0/rep.c @@ -42,8 +42,9 @@ struct rep0_ctx { size_t btrace_size; int ttl; uint32_t pipe_id; - nni_aio * saio; // send aio - nni_aio * raio; // recv aio + rep0_pipe * spipe; // send pipe + nni_aio * saio; // send aio + nni_aio * raio; // recv aio nni_list_node sqnode; nni_list_node rqnode; }; @@ -83,8 +84,11 @@ rep0_ctx_close(void *arg) nni_mtx_lock(&s->lk); ctx->closed = true; if ((aio = ctx->saio) != NULL) { - nni_msg *msg; - nni_list_node_remove(&ctx->sqnode); + nni_msg * msg; + rep0_pipe *pipe = ctx->spipe; + ctx->saio = NULL; + ctx->spipe = NULL; + nni_list_remove(&pipe->sendq, ctx); msg = nni_aio_get_msg(aio); nni_msg_free(msg); nni_aio_finish_error(aio, NNG_ECLOSED); @@ -214,7 +218,8 @@ rep0_ctx_send(void *arg, nni_aio *aio) return; } if (p->busy) { - ctx->saio = aio; + ctx->saio = aio; + ctx->spipe = p; nni_list_append(&p->sendq, ctx); nni_mtx_unlock(&s->lk); return; @@ -412,11 +417,12 @@ rep0_pipe_send_cb(void *arg) } nni_list_remove(&p->sendq, ctx); - aio = ctx->saio; - ctx->saio = NULL; - p->busy = true; - msg = nni_aio_get_msg(aio); - len = nni_msg_len(msg); + aio = ctx->saio; + ctx->saio = NULL; + ctx->spipe = NULL; + p->busy = true; + msg = nni_aio_get_msg(aio); + len = nni_msg_len(msg); nni_aio_set_msg(aio, NULL); nni_aio_set_msg(p->aio_send, msg); nni_pipe_send(p->pipe, p->aio_send); -- cgit v1.2.3-70-g09d2