soreceive() must not hold mutex when calling sblock().
authorbluhm <bluhm@openbsd.org>
Tue, 19 Dec 2023 01:11:21 +0000 (01:11 +0000)
committerbluhm <bluhm@openbsd.org>
Tue, 19 Dec 2023 01:11:21 +0000 (01:11 +0000)
In my recent commit I missed that sblock() may sleep while soreceive()
holds the incpb mutex.  Call pru_lock() after sblock().

Reported-by: syzbot+f79c896ec019553655a0@syzkaller.appspotmail.com
Reported-by: syzbot+08b6f1102e429b2d4f84@syzkaller.appspotmail.com
OK mvs@

sys/kern/uipc_socket.c

index 7a3062c..61d1ab7 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: uipc_socket.c,v 1.310 2023/12/18 13:11:20 bluhm Exp $ */
+/*     $OpenBSD: uipc_socket.c,v 1.311 2023/12/19 01:11:21 bluhm Exp $ */
 /*     $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $        */
 
 /*
@@ -832,13 +832,12 @@ bad:
                *mp = NULL;
 
        solock_shared(so);
-       pru_lock(so);
 restart:
        if ((error = sblock(so, &so->so_rcv, SBLOCKWAIT(flags))) != 0) {
-               pru_unlock(so);
                sounlock_shared(so);
                return (error);
        }
+       pru_lock(so);
 
        m = so->so_rcv.sb_mb;
 #ifdef SOCKET_SPLICE
@@ -908,7 +907,6 @@ restart:
                        sounlock_shared(so);
                        return (error);
                }
-               pru_lock(so);
                goto restart;
        }
 dontblock:
@@ -1181,6 +1179,7 @@ dontblock:
            (flags & MSG_EOR) == 0 &&
            (so->so_rcv.sb_state & SS_CANTRCVMORE) == 0) {
                sbunlock(so, &so->so_rcv);
+               pru_unlock(so);
                goto restart;
        }