Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 May 2025 22:52:51 GMT
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: c44d6f43a68f - main - unix/stream: provide uipc_cantrcvmore()
Message-ID:  <202505232252.54NMqp9f050688@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by glebius:

URL: https://cgit.FreeBSD.org/src/commit/?id=c44d6f43a68f6bb39b92df85c5ba90a9b0feee15

commit c44d6f43a68f6bb39b92df85c5ba90a9b0feee15
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-05-12 18:12:09 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-05-23 22:04:38 +0000

    unix/stream: provide uipc_cantrcvmore()
    
    and use it the pr_shutdown method.  While unix/dgram can still use generic
    socket socantrcvmore(), the stream versions need a specific one.  This fixes
    a panic reported by syzkaller.  While here inline unp_shutdown() into
    uipc_shutdown().
    
    Reported-by:    syzbot+86c18f0886f70a3509c6@syzkaller.appspotmail.com
---
 sys/kern/uipc_usrreq.c | 52 +++++++++++++++++++++++++++-----------------------
 1 file changed, 28 insertions(+), 24 deletions(-)

diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c
index a855c47d2e5a..0f730cf9424b 100644
--- a/sys/kern/uipc_usrreq.c
+++ b/sys/kern/uipc_usrreq.c
@@ -299,7 +299,6 @@ static int	unp_connectat(int, struct socket *, struct sockaddr *,
 static void	unp_connect2(struct socket *, struct socket *, bool);
 static void	unp_disconnect(struct unpcb *unp, struct unpcb *unp2);
 static void	unp_dispose(struct socket *so);
-static void	unp_shutdown(struct unpcb *);
 static void	unp_drop(struct unpcb *);
 static void	unp_gc(__unused void *, int);
 static void	unp_scan(struct mbuf *, void (*)(struct filedescent **, int));
@@ -1341,6 +1340,18 @@ uipc_wakeup(struct socket *so)
 	SOCK_RECVBUF_UNLOCK(so);
 }
 
+static void
+uipc_cantrcvmore(struct socket *so)
+{
+
+	SOCK_RECVBUF_LOCK(so);
+	so->so_rcv.sb_state |= SBS_CANTRCVMORE;
+	if (so->so_rcv.uxst_peer != NULL)
+		uipc_wakeup(so);
+	else
+		SOCK_RECVBUF_UNLOCK(so);
+}
+
 static int
 uipc_soreceive_stream_or_seqpacket(struct socket *so, struct sockaddr **psa,
     struct uio *uio, struct mbuf **mp0, struct mbuf **controlp, int *flagsp)
@@ -2646,18 +2657,28 @@ uipc_shutdown(struct socket *so, enum shutdown_how how)
 
 	switch (how) {
 	case SHUT_RD:
-		socantrcvmore(so);
+		if (so->so_type == SOCK_DGRAM)
+			socantrcvmore(so);
+		else
+			uipc_cantrcvmore(so);
 		unp_dispose(so);
 		break;
 	case SHUT_RDWR:
-		socantrcvmore(so);
+		if (so->so_type == SOCK_DGRAM)
+			socantrcvmore(so);
+		else
+			uipc_cantrcvmore(so);
 		unp_dispose(so);
 		/* FALLTHROUGH */
 	case SHUT_WR:
-		UNP_PCB_LOCK(unp);
-		socantsendmore(so);
-		unp_shutdown(unp);
-		UNP_PCB_UNLOCK(unp);
+		if (so->so_type == SOCK_DGRAM) {
+			socantsendmore(so);
+		} else {
+			UNP_PCB_LOCK(unp);
+			if (unp->unp_conn != NULL)
+				uipc_cantrcvmore(unp->unp_conn->unp_socket);
+			UNP_PCB_UNLOCK(unp);
+		}
 	}
 	wakeup(&so->so_timeo);
 
@@ -3380,23 +3401,6 @@ SYSCTL_PROC(_net_local_seqpacket, OID_AUTO, pcblist,
     (void *)(intptr_t)SOCK_SEQPACKET, 0, unp_pcblist, "S,xunpcb",
     "List of active local seqpacket sockets");
 
-static void
-unp_shutdown(struct unpcb *unp)
-{
-	struct unpcb *unp2;
-	struct socket *so;
-
-	UNP_PCB_LOCK_ASSERT(unp);
-
-	unp2 = unp->unp_conn;
-	if ((unp->unp_socket->so_type == SOCK_STREAM ||
-	    (unp->unp_socket->so_type == SOCK_SEQPACKET)) && unp2 != NULL) {
-		so = unp2->unp_socket;
-		if (so != NULL)
-			socantrcvmore(so);
-	}
-}
-
 static void
 unp_drop(struct unpcb *unp)
 {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202505232252.54NMqp9f050688>