Protect socket receive buffer in IP multicast routing.
authorbluhm <bluhm@openbsd.org>
Wed, 6 Dec 2023 09:27:17 +0000 (09:27 +0000)
committerbluhm <bluhm@openbsd.org>
Wed, 6 Dec 2023 09:27:17 +0000 (09:27 +0000)
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@

sys/netinet/ip_mroute.c
sys/netinet6/ip6_mroute.c

index a667c90..e318493 100644 (file)
@@ -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);
                }
        }
index 615c9fd..5b02315 100644 (file)
@@ -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;
                }
        }