NetBSD Problem Report #60832

From www@netbsd.org  Thu Oct  1 10:17:36 2026
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
	 key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
	 client-signature RSA-PSS (2048 bits) client-digest SHA256)
	(Client CN "mail.netbsd.org", Issuer "YR1" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 9C0A51A923B
	for <gnats-bugs@gnats.NetBSD.org>; Thu,  1 Oct 2026 10:17:36 +0000 (UTC)
Message-Id: <20261001101735.3F7B81A923C@mollari.NetBSD.org>
Date: Thu,  1 Oct 2026 10:17:35 +0000 (UTC)
From: kikadf.01@gmail.com
Reply-To: kikadf.01@gmail.com
To: gnats-bugs@NetBSD.org
Subject: AF_LOCAL stream: sendmsg() with SCM_RIGHTS silently drops data and descriptors but reports success
X-Send-Pr-Version: www-1.0
X-From4GNATS: "kikadf.01@gmail.com via gnats" <gnats-admin@NetBSD.org>

>Number:         60832
>Category:       kern
>Synopsis:       AF_LOCAL stream: sendmsg() with SCM_RIGHTS silently drops data and descriptors but reports success
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          pending-pullups
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Oct 01 10:20:00 +0000 2026
>Closed-Date:    
>Last-Modified:  Wed Oct 21 01:31:44 +0000 2026
>Originator:     Róbert Bagdán
>Release:        NetBSD-11 (same code in 10, current)
>Organization:
>Environment:
NetBSD yamato 11.0_STABLE NetBSD 11.0_STABLE (GENERIC) #0: Sun Aug  2 14:10:41 UTC 2026  mkrepro@mkrepro.NetBSD.org:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
In sys/kern/uipc_usrreq.c:unp_send(), the unp_internalize() can increase
the size of the control message. Later, this can cause sbappendcontrol() to fail
its space check if the resulting size is larger than the receiver's socket buffer.

However, when sbappendcontrol() fails, unp_send() does not set error.
As a result, unp_send() eventually returns 0, even though the message was not
appended to the receiver's socket buffer. Also, m is not freed in this case.

In unp_send()
https://github.com/NetBSD/src/blob/cc2030c15de6861749296c2498758dfdfc53eac5/sys/kern/uipc_usrreq.c#L473:

int error = 0;
....
		if (control) {
			if (sbappendcontrol(rcv, m, control) != 0)
				control = NULL;
		} else {
....
		if (control != NULL) {
			unp_dispose(control);
			m_freem(control);
		}
		break;
....
	return error;

This appears to cause the hangs in chromium on NetBSD.
Chromium's mojo ipc passes file descriptors over AF_LOCAL stream socketpairs. According to ktrace,
under load, a 2816-byte sendmsg() containing descriptors returned 2816, but the receiver received only
the last 768 bytes. The receiver then detected the stream as malformed and tore down the channel.
This results in repeated network service restarts, lost file descriptors, and stuck tabs.
>How-To-Repeat:
I have a claude test code for demonstrate the issue, if anyone is interested, I’ll attach it later.
>Fix:
As a workaround, increasing net.local.stream.recvspace to twice the sendspace value prevents the problem,
because sbappendcontrol() no longer fails its space check.

The same issue fixed in OpenBSD and FreeBSD.
FreeBSD didn't check sizes in sbappendcontrol_locked(): https://reviews.freebsd.org/D16515
OpenBSD's uipc_send return with error if sbappendcontrol() return with fail:
https://github.com/openbsd/src/commit/251befa78d72c4a99adcb183f912b556c978da4b

>Release-Note:

>Audit-Trail:
From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60832 CVS commit: src
Date: Thu, 1 Oct 2026 22:23:57 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Thu Oct  1 22:23:57 UTC 2026

 Modified Files:
 	src/distrib/sets/lists/debug: mi
 	src/distrib/sets/lists/tests: mi
 	src/tests/kernel: Makefile
 Added Files:
 	src/tests/kernel: t_fdpass.c

 Log Message:
 cmsg: Test edge case of fd-passing near buffer size.

 This test allows sendmsg to fail with ENOBUFS without blocking, and
 verifies that the fds are received if it succeeds.

 When passing file descriptors, sendmsg can fail with ENOBUFS it did
 not or would not block because _after_ the blocking criterion is
 tested in the AF-generic uipc_socket.c logic (essentially, whether
 the data length + control length would exceed the send buffer size),
 the control buffer is expanded on some architectures by converting
 each int file descriptor to a struct file pointer in the kernel, and
 then the buffer size is checked again in AF_LOCAL-specific logic when
 unp_send calls sbappendcontrol.

 Frankly I think this is a bad design, and sendmsg should just not
 fail for this reason if it has passed the blocking criterion: either

 (a) the AF_LOCAL-specific logic should count the user's control
     buffer size with ints rather than the the kernel's control buffer
     size with struct file pointers (which would mean the user can
     occupy a little more kernel memory than they could before, but
     it's limited by maxfiles/unp_rights_ratio times the difference in
     sizeof(int) and sizeof(struct file *) anyway); or

 (b) the AF-generic logic should count the kernel's control buffer
     size (which would mean sendmsg might block before data length +
     control length reaches sndbuf, from the user's perspective, so
     I'm inclined to do the other option).

 But it is _definitely_ wrong for sendmsg to report success when the
 receiver cannot possibly receive the fds, and _less_ wrong for
 sendmsg to report ENOBUFS in this case.

 PR kern/60832: AF_LOCAL stream: sendmsg() with SCM_RIGHTS silently
 drops data and descriptors but reports success


 To generate a diff of this commit:
 cvs rdiff -u -r1.520 -r1.521 src/distrib/sets/lists/debug/mi
 cvs rdiff -u -r1.1431 -r1.1432 src/distrib/sets/lists/tests/mi
 cvs rdiff -u -r1.102 -r1.103 src/tests/kernel/Makefile
 cvs rdiff -u -r0 -r1.1 src/tests/kernel/t_fdpass.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60832 CVS commit: src
Date: Thu, 1 Oct 2026 22:24:26 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Thu Oct  1 22:24:25 UTC 2026

 Modified Files:
 	src/sys/kern: uipc_usrreq.c
 	src/tests/kernel: t_fdpass.c

 Log Message:
 sendmsg(2): Report ENOBUFS instead of success on failure to pass fds.

 PR kern/60832: AF_LOCAL stream: sendmsg() with SCM_RIGHTS silently
 drops data and descriptors but reports success


 To generate a diff of this commit:
 cvs rdiff -u -r1.210 -r1.211 src/sys/kern/uipc_usrreq.c
 cvs rdiff -u -r1.1 -r1.2 src/tests/kernel/t_fdpass.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->needs-pullups
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Thu, 01 Oct 2026 22:25:56 +0000
State-Changed-Why:
fixed in HEAD, needs pullup-11, pullup-10 after testbed runs


From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60832 CVS commit: src/tests/kernel
Date: Fri, 2 Oct 2026 01:31:13 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Fri Oct  2 01:31:12 UTC 2026

 Modified Files:
 	src/tests/kernel: t_fdpass.c

 Log Message:
 sendmsg(2): Treat ENOBUFS on fd passing as a bug.

 PR kern/60832: AF_LOCAL stream: sendmsg() with SCM_RIGHTS silently
 drops data and descriptors but reports success


 To generate a diff of this commit:
 cvs rdiff -u -r1.2 -r1.3 src/tests/kernel/t_fdpass.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60832 CVS commit: src
Date: Fri, 2 Oct 2026 01:31:31 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Fri Oct  2 01:31:31 UTC 2026

 Modified Files:
 	src/sys/kern: uipc_socket2.c
 	src/tests/kernel: t_fdpass.c

 Log Message:
 sendmsg(2): Don't fail with ENOBUFS on fd passing.

 We don't fail with ENOBUFS if we're not fd-passing -- we just block
 or fail earlier on with EAGAIN; no reason to invent a new failure
 mode just for the fd-passing case.

 Whether we should have _any_ path that checks the receiving socket's
 receive buffer limit is another question, but it's silly for it to:
 1. apply _only_ when passing fds,
 2. trip only when the kernel internally expands the buffer, and/or
 3. fail with ENOBUFS instead of blocking or failing with EAGAIN.

 This change essentially matches FreeBSD's subversion r337328:

 commit 5b0480f2cca0a4a04f21055ed769be93f11348de
 Author: Mark Johnston <markj@FreeBSD.org>
 Date:   Sat Aug 4 20:26:54 2018 +0000

     Don't check rcv sockbuf limits when sending on a unix stream socket.

     sosend_generic() performs an initial comparison of the amount of data
     (including control messages) to be transmitted with the send buffer
     size. When transmitting on a unix socket, we then compare the amount
     of data being sent with the amount of space in the receive buffer size;
     if insufficient space is available, sbappendcontrol() returns an error
     and the data is lost.  This is easily triggered by sending control
     messages together with an amount of data roughly equal to the send
     buffer size, since the control message size may change in uipc_send()
     as file descriptors are internalized.

     Fix the problem by removing the space check in sbappendcontrol(),
     whose only consumer is the unix sockets code.  The stream sockets code
     uses the SB_STOP mechanism to ensure that senders will block if the
     receive buffer fills up.

     PR:             181741
     MFC after:      1 month
     Sponsored by:   The FreeBSD Foundation
     Differential Revision:  https://reviews.freebsd.org/D16515

 https://cgit.freebsd.org/src/commit/?id=5b0480f2cca0a4a04f21055ed769be93f11348de

 PR kern/60832: AF_LOCAL stream: sendmsg() with SCM_RIGHTS silently
 drops data and descriptors but reports success


 To generate a diff of this commit:
 cvs rdiff -u -r1.148 -r1.149 src/sys/kern/uipc_socket2.c
 cvs rdiff -u -r1.3 -r1.4 src/tests/kernel/t_fdpass.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60832 CVS commit: src/sys
Date: Fri, 2 Oct 2026 01:33:44 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Fri Oct  2 01:33:44 UTC 2026

 Modified Files:
 	src/sys/kern: uipc_socket2.c uipc_usrreq.c
 	src/sys/sys: socketvar.h

 Log Message:
 sbappendcontrol never fails; nix the return value indicating success.

 Cleanup which in principle changes the module ABI (I doubt there are
 any modules out there that actually use sbappendcontrol, though rump
 does use it across libraries) after:

 PR kren/60832: AF_LOCAL stream: sendmsg() with SCM_RIGHTS silently
 drops data and descriptors but reports success

 XXX kernel revbump due to API/ABI change -- not for pullup


 To generate a diff of this commit:
 cvs rdiff -u -r1.149 -r1.150 src/sys/kern/uipc_socket2.c
 cvs rdiff -u -r1.211 -r1.212 src/sys/kern/uipc_usrreq.c
 cvs rdiff -u -r1.172 -r1.173 src/sys/sys/socketvar.h

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Taylor R Campbell" <riastradh@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/60832 CVS commit: src/sys/sys
Date: Fri, 2 Oct 2026 04:32:24 +0000

 Module Name:	src
 Committed By:	riastradh
 Date:		Fri Oct  2 04:32:24 UTC 2026

 Modified Files:
 	src/sys/sys: param.h

 Log Message:
 sys/param.h: Welcome to 11.99.9!

 This version arises out of an abundance of caution in the slim chance
 that anything is affected by the change in the signature of
 sbappendcontrol to return void instead of a boolean indicating
 success or failure; the caller is now (and, really, was already)
 responsible for checking buffer sizes.

 PR kern/60832: AF_LOCAL stream: sendmsg() with SCM_RIGHTS silently
 drops data and descriptors but reports success


 To generate a diff of this commit:
 cvs rdiff -u -r1.747 -r1.748 src/sys/sys/param.h

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: needs-pullups->pending-pullups
State-Changed-By: riastradh@NetBSD.org
State-Changed-When: Wed, 21 Oct 2026 01:31:44 +0000
State-Changed-Why:
pullup-11 #547
pullup-10 #1392


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.51 2026/08/10 02:28:17 riastradh Exp $
$NetBSD: gnats_config.sh,v 1.10 2026/05/13 22:00:09 riastradh Exp $
Copyright © 1994-2026 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.