From nobody Fri Dec 19 15:32:45 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 4dXs3y2bzRz6LtH6 for ; Fri, 19 Dec 2025 15:32:46 +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 4dXs3x6Q34z3b7x for ; Fri, 19 Dec 2025 15:32:45 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1766158365; 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=ENYOg8pcqxY6cFfxXHItY43Co0tN/r2reipM6I4wPpg=; b=Cq66dkDD3IgiHGYKX7nkF+XKFKxajJD4x9Y//mS/f/hDKK1NVF7SBhD3DidoTpuKYOv01a RhUucLKWRDPtj2KFuyseM5vbY7Ah1fStDWYGFtgBJAkf0O452yhz4MgnVelqWLXS4WwXf1 6DT/Hp1n2ZebS62WxyeiPDlgPy9a2dXyV1qDX3DiBr4wQ2LKTfl1FoDMq+xq9djwkEHERh ywsU/3ibuRcGMJtOC8jvE4gA7+vqmx89TW0uwE1HKv8TBmPkaqrNlYLIXSmBHWGxPfaUxv KSOh0kKIE8HNeSK4drwBBT9GHN4RB4xZcaCETKc7C1ia1TIqh6JSXgmMhQjO+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1766158365; 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=ENYOg8pcqxY6cFfxXHItY43Co0tN/r2reipM6I4wPpg=; b=eRZ5MwZy4eAiYnt7Lsff+9XZcz50pGghpwWZ/QtvHzFBHCmePMlvHVxvySBAellm+ICsIa Uc3C5W5AJIkkR0+B1IEY1vVG3kRaD3GACkN3yeLy/DNe1HOStG1lFZpfkPAKMpxw2iY5t+ a9qjqaSbmzsY8EicCWJ3ByFq9atzEeg7FPUILEhV4IlNNPYvCNN6V0lJXtxosYW0Glg1oO OeQ3wHAtCfAO0MvIywK2/kVMXFCPTJDLcZY7Ga8DqaXWSM4IEqRUs1T7EPVo/haCaoohjH tzB6vDd1cLpOpYz1851FKCoQDxS7yAjzBrivRAdqtUKV6fA3yochwb+NSJ2ARQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1766158365; a=rsa-sha256; cv=none; b=TtIF2Ehph0PHBsyAxrFkbxFK0PQkwkJNcQJX08iGqmFteHKYXTlHH+Liz1SZzIPexqNXQW XSB2ydE/IWPbqEPlXlI9JXVd1I80Q+0SNPuxI9r0MOVONvure5k7quV0rRJWl8mg+A9W4i hcnV7Mypl5JIUDtJTJi8BI35A4EDz9aNTEImZ1Dc7pdxlW5GXWvGJbuzbc6JD3Pg9PEeZH HPK5Qe1GtfJprif1sQSf/2C5i7XAOLzLXfPN5bUayf07tBvlXKL2JRqIJ0VKUgFkEWoifD js4JrSZXGt2pqseL+uc3KluOnEgm2V3fjl/mEwrqOAstbZS1FeYtzDRh+w+NFw== 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 4dXs3x5SFpzN6 for ; Fri, 19 Dec 2025 15:32:45 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 43543 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 19 Dec 2025 15:32:45 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: John Baldwin Subject: git: c7cc4706504e - stable/14 - 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/14 X-Git-Reftype: branch X-Git-Commit: c7cc4706504e268fd3ca2f3382aa3f58004b71c6 Auto-Submitted: auto-generated Date: Fri, 19 Dec 2025 15:32:45 +0000 Message-Id: <6945701d.43543.344bfddf@gitrepo.freebsd.org> The branch stable/14 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=c7cc4706504e268fd3ca2f3382aa3f58004b71c6 commit c7cc4706504e268fd3ca2f3382aa3f58004b71c6 Author: John Baldwin AuthorDate: 2025-12-10 15:30:31 +0000 Commit: John Baldwin CommitDate: 2025-12-19 15:19:41 +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 1a33a814c611..e244c09e7d1f 100644 --- a/sys/netlink/netlink_snl.h +++ b/sys/netlink/netlink_snl.h @@ -1040,6 +1040,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; @@ -1047,23 +1048,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); }