From nobody Fri Dec 19 15:32:19 2025 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4dXs3R5fVrz6LtcY for ; Fri, 19 Dec 2025 15:32:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4dXs3R2R38z3Yn8 for ; Fri, 19 Dec 2025 15:32:19 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1766158339; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=0SMmZUPhAFEm5MKy9NRogdBCJNhOYq6j2v2eQvS7HEw=; b=bje8AAPm0UeibebDyQrwB4PehzzOg9MccGi5aT9jRne9YOnO4SJeCK2XRcxK7wbvhFjZfn H2akVysB0v5s+lVx4FsN41hzh+Jwxw2CUesICPp7uA8xjTASdoMQweEyl55TKmu9VXrCv2 +XDLuXxuSv1XvkMrn/paDjIgYk5W/GO9BZlYj8qPXa9i0zZ4IE6vbx0dy6rbkTTKYd0d6a o0DvwbNHH7eE9Rn5PYPa4Al54hcpqsdKs5r6iXIDNJOKW4MR+JEMYD7MzT1ZcvwbZkIh06 jtXg8j79Tos0t2aMAZdBE8G90S3TpZ+6oj5EF+4/RCnHq0gmPz9T4ispYihbLQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1766158339; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=0SMmZUPhAFEm5MKy9NRogdBCJNhOYq6j2v2eQvS7HEw=; b=R5lPf/hbJDqssrplk53FWDCO5ct4VjW9U0+tc4qsT8jdLHWuzt1N/IHByz5xdxHPQ1xeCV K0mlS6j7x54n8LoKY8H0qwTs9/EbpHDvKABGKQEip7I4XeboQSbnnrDP4QtwV8kQWBl8oC 777AwoWpXSROS/TNa/JwEJZ7ulS8WRlIz3FDaQbGOzFyC2br6E9E4oJtaDMWZ63iMbpqPX QYblCdVD0PEK+yw7KHktFCpfGiXf9VaIzBVuZdHvGtARO5R35zX/eBx5rFS4Gs165kpj1I YQzAa2Sum2eZ+vjxIWMkJRRuVvpb93aW5FAmTVFi/EXEEDwUHBQ+Yy78V1ztEw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1766158339; a=rsa-sha256; cv=none; b=XMvwqFeDW89WEg9/GuxSx1Tau4olHMrI7ZR2lLNsNqjcU156/KfWlkRQGXtsnmovWcUK4k Z4Wg3LRZaLdv97MFyR/0nqbDLiA3Vmt1uphokKr4yTSiOxiKrZzR8G8wSBodtmCDCQBxX6 yKCfPvNOb8f29UD/LaWPifWAbwoGqKAzX8d7lWzlvn3aotkBDzBZMS+vUPvhX3KJmyAqOz pnj5eJw74JvvoAARxtKg8l0Pthd7IB9TK5bSGXC8Q3aWbvbL4NWnyjNkyR9i5W8biu6xxG eW/0auRBxL8a+WVr4gbsHCAO1ou7AoKgxhrQpeC1EuCijtjq7BE6fq/Zn8YrWA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4dXs3R225vzHP for ; Fri, 19 Dec 2025 15:32:19 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 4490e by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 19 Dec 2025 15:32:19 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: John Baldwin Subject: git: 11b309c0a717 - stable/15 - netlink: Don't overwrite existing data in a linear buffer in snl_writer List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: jhb X-Git-Repository: src X-Git-Refname: refs/heads/stable/15 X-Git-Reftype: branch X-Git-Commit: 11b309c0a717bce634ca6acc8e1c4260810aae9b Auto-Submitted: auto-generated Date: Fri, 19 Dec 2025 15:32:19 +0000 Message-Id: <69457003.4490e.5ea5929a@gitrepo.freebsd.org> The branch stable/15 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=11b309c0a717bce634ca6acc8e1c4260810aae9b commit 11b309c0a717bce634ca6acc8e1c4260810aae9b Author: John Baldwin AuthorDate: 2025-12-10 15:30:31 +0000 Commit: John Baldwin CommitDate: 2025-12-19 15:19:44 +0000 netlink: Don't overwrite existing data in a linear buffer in snl_writer First, a bit of background on some of the data structures netlink uses to manage data associated with a netlink connection. - struct linear_buffer contains a single virtually-contiguous buffer of bytes. Regions of this buffer are suballocated via lb_allocz() which uses a simple "bump" where the buffer is split into an allocated region at the start and a free region at the end. Each allocation "bumps" the boundary (lb->offset) forward by the allocation size. Individual allocations are not freed. Instead, the entire buffer is freed once all of the allocations are no longer in use. Linear buffers also contain an embedded link to permit chaining buffers together. - snl_state contains various state for a netlink connection including a chain of linear buffers. This chain of linear buffers can contain allocations for netlink messages as well as other ancillary data buffers such as socket address structures. The chain of linear buffers are freed once the connection is torn down. - snl_writer is used to construct a message written on a netlink connection. It contains a single virtually-contiguous buffer (nw->base) allocated from the associated snl_state's linear buffer chain. The buffer distinguishes between the amount of space reserved from the underlying allocator (nw->size) and the current message length actually written (nw->offset). As new chunks of data (e.g. netlink attributes) are added to the write buffer, the buffer is grown by snl_realloc_msg_buffer by reallocating a larger buffer from the associated snl_state and copying over the current message data to the new buffer. Commit 0c511bafdd5b309505c13c8dc7c6816686d1e103 aimed to fix two bugs in snl_realloc_msg_buffer. The first bug is that snl_realloc_msg_buffer originally failed to update nw->size after growing the buffer which could result in spurious re-allocations when growing in the future. It also probably could eventually lead to overflowing the buffer since each reallocation request was just adding the new bytes needed for a chunk to the original 'nw->size' while 'nw->offset' kept growing. Eventually the new 'nw->offset' would be larger than 'nw->size + sz' causing routines like snl_reserve_msg_data_raw() to return an out-of-bounds pointer. The second change in this commit I think was trying to fix the buffer overflows due to 'nw->size' being wrong, but instead introduced a new set of bugs. The second change ignored the returned pointer from snl_allocz() and instead assumed it could use all of the currently-allocated data in the current linear buffer. This is only ok if the only data in the linear buffer chain for the associated snl_state is the snl_writer's message buffer. If there is any other data allocated from the snl_state, it could be earlier in the current linear buffer, so resetting new_base to nw->ss->lb->base can result in overwriting that other data. The second change was also over-allocating storage from the underlying chain of linear buffers (e.g. a writer allocation of 256 followed by 512 would end up using the first 512 bytes, but 768 bytes would be reserved in the underlying linear buffer). To fix, revert the second change keeping only the fix for 'nw->size' being wrong. Reviewed by: igoro, markj Fixes: 0c511bafdd5b ("netlink: fix snl_writer and linear_buffer re-allocation logic") Sponsored by: AFRL, DARPA Differential Revision: https://reviews.freebsd.org/D54148 (cherry picked from commit 255af72c8059b0117db646f82efa2e4848fa7570) --- sys/netlink/netlink_snl.h | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h index ca1169d24b91..429dae767c47 100644 --- a/sys/netlink/netlink_snl.h +++ b/sys/netlink/netlink_snl.h @@ -1072,6 +1072,7 @@ static inline bool snl_realloc_msg_buffer(struct snl_writer *nw, size_t sz) { uint32_t new_size = nw->size * 2; + char *new_base; while (new_size < nw->size + sz) new_size *= 2; @@ -1079,23 +1080,20 @@ snl_realloc_msg_buffer(struct snl_writer *nw, size_t sz) if (nw->error) return (false); - if (snl_allocz(nw->ss, new_size) == NULL) { + new_base = snl_allocz(nw->ss, new_size); + if (new_base == NULL) { nw->error = true; return (false); } - nw->size = new_size; - void *new_base = nw->ss->lb->base; - if (new_base != nw->base) { - memcpy(new_base, nw->base, nw->offset); - if (nw->hdr != NULL) { - int hdr_off = (char *)(nw->hdr) - nw->base; + memcpy(new_base, nw->base, nw->offset); + if (nw->hdr != NULL) { + int hdr_off = (char *)(nw->hdr) - nw->base; - nw->hdr = (struct nlmsghdr *) - (void *)((char *)new_base + hdr_off); - } - nw->base = (char *)new_base; + nw->hdr = (struct nlmsghdr *)(void *)(new_base + hdr_off); } + nw->base = new_base; + nw->size = new_size; return (true); }