diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2023-12-06 09:27:18 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2023-12-06 09:27:18 +0000 |
commit | d4cd916a714965c895affd7a0c32f4b68ecf568f (patch) | |
tree | b68f9681c2b0f80cfadd5467bd3179d308b13fdb | |
parent | fa1a6cf266f262f48ecbe7fcaf6c37eb1ef4b02b (diff) |
Protect socket receive buffer in IP multicast routing.
Since soreceive() runs in parallel for raw sockets, sbappendaddr()
has to be protected by inpcb mutex. This was missing in multicast
forwarding which is running with a combination of shared net lock
and kernel lock. soreceive() uses shared net lock and mutex per
inpcb. Grab mutex before sbappendaddr() in socket_send() and
socket6_send().
panic receive 1 reported by Jo Geraerts
OK mvs@ claudio@
-rw-r--r-- | sys/netinet/ip_mroute.c | 17 | ||||
-rw-r--r-- | sys/netinet6/ip6_mroute.c | 17 |
2 files changed, 24 insertions, 10 deletions
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index a667c90ccb2..e318493fcd0 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_mroute.c,v 1.139 2023/06/14 14:30:08 mvs Exp $ */ +/* $OpenBSD: ip_mroute.c,v 1.140 2023/12/06 09:27:17 bluhm Exp $ */ /* $NetBSD: ip_mroute.c,v 1.85 2004/04/26 01:31:57 matt Exp $ */ /* @@ -1048,11 +1048,18 @@ del_mfc(struct socket *so, struct mbuf *m) } int -socket_send(struct socket *s, struct mbuf *mm, struct sockaddr_in *src) +socket_send(struct socket *so, struct mbuf *mm, struct sockaddr_in *src) { - if (s != NULL) { - if (sbappendaddr(s, &s->so_rcv, sintosa(src), mm, NULL) != 0) { - sorwakeup(s); + if (so != NULL) { + struct inpcb *inp = sotoinpcb(so); + int ret; + + mtx_enter(&inp->inp_mtx); + ret = sbappendaddr(so, &so->so_rcv, sintosa(src), mm, NULL); + mtx_leave(&inp->inp_mtx); + + if (ret != 0) { + sorwakeup(so); return (0); } } diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 615c9fd07eb..5b02315f921 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_mroute.c,v 1.137 2023/06/14 14:30:08 mvs Exp $ */ +/* $OpenBSD: ip6_mroute.c,v 1.138 2023/12/06 09:27:17 bluhm Exp $ */ /* $NetBSD: ip6_mroute.c,v 1.59 2003/12/10 09:28:38 itojun Exp $ */ /* $KAME: ip6_mroute.c,v 1.45 2001/03/25 08:38:51 itojun Exp $ */ @@ -853,11 +853,18 @@ del_m6fc(struct socket *so, struct mf6cctl *mfccp) } int -socket6_send(struct socket *s, struct mbuf *mm, struct sockaddr_in6 *src) +socket6_send(struct socket *so, struct mbuf *mm, struct sockaddr_in6 *src) { - if (s) { - if (sbappendaddr(s, &s->so_rcv, sin6tosa(src), mm, NULL) != 0) { - sorwakeup(s); + if (so != NULL) { + struct inpcb *inp = sotoinpcb(so); + int ret; + + mtx_enter(&inp->inp_mtx); + ret = sbappendaddr(so, &so->so_rcv, sin6tosa(src), mm, NULL); + mtx_leave(&inp->inp_mtx); + + if (ret != 0) { + sorwakeup(so); return 0; } } |