aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2018-04-17 15:38:06 -0700
committerGarrett D'Amore <garrett@damore.org>2018-04-17 15:38:06 -0700
commit40542e7af0f5003d7ad67876ea580a59174031ca (patch)
tree445a74310977383993b12eb4ead7fdabd042d0d7
parent45f3f141850a0ac07c31906748752571652683df (diff)
downloadnng-40542e7af0f5003d7ad67876ea580a59174031ca.tar.gz
nng-40542e7af0f5003d7ad67876ea580a59174031ca.tar.bz2
nng-40542e7af0f5003d7ad67876ea580a59174031ca.zip
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.
-rw-r--r--src/protocol/reqrep0/rep.c26
1 files changed, 16 insertions, 10 deletions
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);