aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2024-12-30 23:25:13 -0800
committerGarrett D'Amore <garrett@damore.org>2024-12-30 23:27:03 -0800
commit5f7a9fe784f3d4074b9c6ad750f05f29966097ef (patch)
treefb7e3d673e924022274789b65310ec32085637f1
parente183d733b4c3a658c011f1e3c06fbbd03b5e97db (diff)
downloadnng-5f7a9fe784f3d4074b9c6ad750f05f29966097ef.tar.gz
nng-5f7a9fe784f3d4074b9c6ad750f05f29966097ef.tar.bz2
nng-5f7a9fe784f3d4074b9c6ad750f05f29966097ef.zip
pipes: fix crash caused by use after free race in rejectiontcp-dialer-local-test
-rw-r--r--src/core/socket.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/core/socket.c b/src/core/socket.c
index d0c18744..81786907 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -1528,16 +1528,21 @@ nni_pipe_add(nni_pipe *p)
// nni_pipe_start attempts to start the pipe, adding it to the socket and
// endpoints and calling callbacks, etc. The pipe should already have finished
-// any negotiation needed at the transport layer.
+// any negotiation needed at the transport layer. Note carefully that the pipe
+// may be destroyed before this function returns, as a result of work done by
+// this function.
void
nni_pipe_start(nni_pipe *p)
{
+ // exactly one of these must be set.
+ NNI_ASSERT(p->p_listener == NULL || p->p_dialer == NULL);
+ NNI_ASSERT(p->p_listener != NULL || p->p_dialer != NULL);
+
+ // NB: starting the pipe can actually cause the pipe
+ // to be deallocated before this returns (if it is rejected)
if (p->p_listener) {
- NNI_ASSERT(p->p_dialer == NULL);
listener_start_pipe(p->p_listener, p);
- }
- if (p->p_dialer) {
- NNI_ASSERT(p->p_listener == NULL);
+ } else if (p->p_dialer) {
dialer_start_pipe(p->p_dialer, p);
}
}