git: a80bbc4e9597 - main - netlink: refuse a send(2) that is larger than socket buffer

From: Gleb Smirnoff <glebius_at_FreeBSD.org>
Date: Fri, 28 Feb 2025 23:46:33 UTC
The branch main has been updated by glebius:

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

commit a80bbc4e9597530b91735ebf366a2a62dc27a8d8
Author:     Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-02-28 23:39:15 +0000
Commit:     Gleb Smirnoff <glebius@FreeBSD.org>
CommitDate: 2025-02-28 23:39:15 +0000

    netlink: refuse a send(2) that is larger than socket buffer
    
    The Netlink RFC doesn't say that explicitly, but general discussion seems
    to state that a single netlink message shall be delivered in a single
    send(2) to the socket.  So, if a single message doesn't fit into buffer it
    is clear EMSGSIZE.  The RFC is unclear if application is allowed to send
    several smaller messages with a single syscall potentially overflowing the
    buffer and whether kernel should accept any of them.  At the moment, no
    legit application does that.  So, decision was taken not to overload
    nl_sosend() with a message parsing logic and deny any oversized write.
    
    Reported-by:    syzbot+eb5db60d36b005dbccf5@syzkaller.appspotmail.com
---
 sys/netlink/netlink_domain.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/sys/netlink/netlink_domain.c b/sys/netlink/netlink_domain.c
index a7ceae687d86..74b46114716e 100644
--- a/sys/netlink/netlink_domain.c
+++ b/sys/netlink/netlink_domain.c
@@ -568,6 +568,9 @@ nl_sosend(struct socket *so, struct sockaddr *addr, struct uio *uio,
 	if (__predict_false(uio->uio_resid < sizeof(struct nlmsghdr)))
 		return (ENOBUFS);		/* XXXGL: any better error? */
 
+	if (__predict_false(uio->uio_resid > sb->sb_hiwat))
+		return (EMSGSIZE);
+
 	error = SOCK_IO_SEND_LOCK(so, SBLOCKWAIT(flags));
 	if (error)
 		return (error);