NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

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



>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:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Oct 01 10:20:00 +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@localhost:/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




Home | Main Index | Thread Index | Old Index