aboutsummaryrefslogtreecommitdiff
path: root/src/core/socket.c
diff options
context:
space:
mode:
authorGarrett D'Amore <garrett@damore.org>2023-04-23 17:10:33 -0700
committerGarrett D'Amore <garrett@damore.org>2023-04-23 17:10:33 -0700
commitd38e633c2514463bb1f2e1f020f79429ca844730 (patch)
tree45e71ce997cd8e90e0c352323bc6b7ac8cfe0dc5 /src/core/socket.c
parent8bd3733fc234e9677068cfb4f2b50a35e4413eeb (diff)
downloadnng-d38e633c2514463bb1f2e1f020f79429ca844730.tar.gz
nng-d38e633c2514463bb1f2e1f020f79429ca844730.tar.bz2
nng-d38e633c2514463bb1f2e1f020f79429ca844730.zip
fixes #1657 Use after free in listener (data race)
Diffstat (limited to 'src/core/socket.c')
-rw-r--r--src/core/socket.c22
1 files changed, 21 insertions, 1 deletions
diff --git a/src/core/socket.c b/src/core/socket.c
index 1e7d978e..316f3603 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -9,6 +9,7 @@
//
#include "core/nng_impl.h"
+#include "list.h"
#include "sockimpl.h"
#include <stdio.h>
@@ -691,7 +692,6 @@ nni_sock_shutdown(nni_sock *sock)
while ((l = nni_list_first(&sock->s_listeners)) != NULL) {
nni_listener_hold(l);
- nni_list_node_remove(&l->l_node);
nni_mtx_unlock(&sock->s_mx);
nni_listener_close(l);
nni_mtx_lock(&sock->s_mx);
@@ -890,10 +890,17 @@ int
nni_sock_add_listener(nni_sock *s, nni_listener *l)
{
nni_sockopt *sopt;
+ int rv;
+
+ // grab a hold on the listener for the socket
+ if ((rv = nni_listener_hold(l)) != 0) {
+ return (rv);
+ }
nni_mtx_lock(&s->s_mx);
if (s->s_closing) {
nni_mtx_unlock(&s->s_mx);
+ nni_listener_rele(l);
return (NNG_ECLOSED);
}
@@ -917,6 +924,19 @@ nni_sock_add_listener(nni_sock *s, nni_listener *l)
return (0);
}
+void
+nni_sock_remove_listener(nni_listener *l)
+{
+ nni_sock *s = l->l_sock;
+ nni_mtx_lock(&s->s_mx);
+ NNI_ASSERT(nni_list_node_active(&l->l_node));
+ nni_list_node_remove(&l->l_node);
+ nni_mtx_unlock(&s->s_mx);
+
+ // also drop the hold from the socket
+ nni_listener_rele(l);
+}
+
int
nni_sock_add_dialer(nni_sock *s, nni_dialer *d)
{