From nobody Fri Dec 19 16:55:55 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 4dXtvv5z7tz6M2nm for ; Fri, 19 Dec 2025 16:55:55 +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 4dXtvv4Hdjz3rck for ; Fri, 19 Dec 2025 16:55:55 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1766163355; 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=TyFz3NLdWtdDyKS2cAJ/BBycbwHxrZ91DbVhTrVkjVg=; b=frADOmYlaTDZz2mxcIItY3WillzGlseErwmIft6VAbD4QqgQ6SvyNGaowbtn6A+XEt5PXV RSJyyPy8ZXjK6ab9GZxqDZRR2mQmTk+jAwCBqlRtZCnNh73RGkcNxefb+Ebm3kMu6K3oUt XFYoPSSq7D686WzQbPGE6LgEHDM5DSRjFJqQ+o2l1r3QuIiapGaWwgk/Kl5nCq5OJTSOA6 eYHnYa3/8LPJ/FFpoI+s7gwnmpDdAypto3R550Kovs7dx81cmTWXNgkhGv++00Sj9K4je1 uPzLfioY4anjToR4hiKPfMuC6hzl1N85CV+crrjWsspXAayo1/jyINRJ0cPl9A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1766163355; 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=TyFz3NLdWtdDyKS2cAJ/BBycbwHxrZ91DbVhTrVkjVg=; b=v9VxzNf1NI85uiroGBZKlKJYS/Xx2BNCyJPHfFB2C9C/9Pa4aekVxHih8nibYBusu7jPPM V2ly2P9DDgNTjC46276Kt2lv/OKnVbfgdFGxb/Rztd2lsuS9zZI2UFFH1QA1Xh8Bvn7x8s M3M3de5e0wxvVAbO2hFdKFulWnoCVDWsfgX38UhOEMaRicSpEoP7DK3Tq9hetSscGgB//+ RlDKR4oBo8u0DODdACNaTwFd2DCfKc/9aP0yXjjII/VkpkehwibGyB/fVBxATQcFIoMZcY nZfRYNj6piIEt1WhxgBXpsvfaP3oQ5lAC3ZdrEUUHjgX5hJhwyLMdUGchiCivw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1766163355; a=rsa-sha256; cv=none; b=WSV7CkwQO4Gj9vb1gcpCeDeM4zjxk/aDYs5pPSfUHojsj8HUoiCIJ3MB7lY4Fi1e+OFV9q iVZ1lzPBxRrSAJv6ve93rPyRUSQ+NVTGoZkcSJnRyF6NqnTi5RUkKg/vUIfjwtW8cI4FM2 DPRShNaLIIVybAicNFBF5CmGPzW0Pk0iPmiXsfViY1vHqjW10KFOuCxdC6lWjeA1aZKEsJ PP0USMgA1DPeil9QYCCrqaEa00H+5G7h9HkTsVuxgwsy9G/wGuXmhECkevSR8aWHPylGuu yGvYGvey6hCEeTF3nQGpTbXaQrXCxygAyK7+PsLVWRPpkBi7GlRSdIMDhqH3pg== 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 4dXtvv3jvpz2Lh for ; Fri, 19 Dec 2025 16:55:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id c545 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Fri, 19 Dec 2025 16:55:55 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: John Baldwin Subject: git: 33bc1fb48e32 - stable/13 - 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/13 X-Git-Reftype: branch X-Git-Commit: 33bc1fb48e32bba89535d6814850a9e98e2658d5 Auto-Submitted: auto-generated Date: Fri, 19 Dec 2025 16:55:55 +0000 Message-Id: <6945839b.c545.4a3996af@gitrepo.freebsd.org> The branch stable/13 has been updated by jhb: URL: https://cgit.FreeBSD.org/src/commit/?id=33bc1fb48e32bba89535d6814850a9e98e2658d5 commit 33bc1fb48e32bba89535d6814850a9e98e2658d5 Author: John Baldwin AuthorDate: 2025-12-10 15:30:31 +0000 Commit: John Baldwin CommitDate: 2025-12-19 16:55:36 +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 8c31c5d31671..1ddaf0787369 100644 --- a/sys/netlink/netlink_snl.h +++ b/sys/netlink/netlink_snl.h @@ -707,6 +707,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; @@ -714,23 +715,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 = new_base; + nw->hdr = (struct nlmsghdr *)(void *)(new_base + hdr_off); } + nw->base = new_base; + nw->size = new_size; return (true); }