git: f5923578eb67 - main - sockets: repair sctp_peeloff(2)

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Fri, 06 Feb 2026 18:54:27 UTC
The branch main has been updated by glebius:

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

commit f5923578eb67c6363e4575c107d3be3180ac9371
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2026-02-06 18:51:38 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2026-02-06 18:53:59 +0000

    sockets: repair sctp_peeloff(2)
    
    The shim function soattach() may be passed a non-listening socket by SCTP.
    
    NB: the change makes soattach() more hairy, but long term plan is that
    this function goes away.
    
    PR:     293010
    Fixes:  64f7e3c9c178ab35cb1f8fdf791aec74ede6f6b2
---
 sys/kern/uipc_socket.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c
index 73ac2c6efc4e..8b5d1f504e80 100644
--- a/sys/kern/uipc_socket.c
+++ b/sys/kern/uipc_socket.c
@@ -905,7 +905,11 @@ sodealloc(struct socket *so)
  * normal socket(2) syscall it is the pr_attach that calls soreserve(), even
  * for protocols that don't yet do PR_SOCKBUF.  In case of accepted connection
  * it is our shim that calls soreserve() and the hiwat values are taken from
- * the parent socket.
+ * the parent socket.  The SCTP's sopeeloff() hands us a non-listening parent
+ * socket.
+ *
+ * This whole shim should go away when all major protocols fully manage their
+ * socket buffers.
  */
 static int
 soattach(struct socket *so, int proto, struct thread *td, struct socket *head)
@@ -921,8 +925,10 @@ soattach(struct socket *so, int proto, struct thread *td, struct socket *head)
 		so->so_snd.sb_mtx = &so->so_snd_mtx;
 		so->so_rcv.sb_mtx = &so->so_rcv_mtx;
 	}
-	if (head == NULL || (error = soreserve(so, head->sol_sbsnd_hiwat,
-	    head->sol_sbrcv_hiwat)) == 0)
+	if (head == NULL || (error = soreserve(so,
+	    SOLISTENING(head) ? head->sol_sbsnd_hiwat : head->so_snd.sb_hiwat,
+	    SOLISTENING(head) ? head->sol_sbrcv_hiwat : head->so_rcv.sb_hiwat))
+	    == 0)
 		error = so->so_proto->pr_attach(so, proto, td);
 	if (error != 0 && (so->so_proto->pr_flags & PR_SOCKBUF) == 0) {
 		mtx_destroy(&so->so_snd_mtx);