Re: [SECURITY] net/ncsi: Bound mac_cnt and vlan_cnt in ncsi_rsp_handler_gp() (ZERO-284)
From: Willy Tarreau <w@1wt.eu>
Date: 2026-10-09 08:02:18
Hello, Note, there's no need to Cc security@k.o when sending to public lists. On Fri, Oct 09, 2026 at 12:44:48PM +0530, Nikhil Agrawal wrote:
Hello Linux Kernel Security Team and NC-SI maintainers, I am Nikhil, a YC founder, and along with our security research team at Mettle Labs, we have been conducting systematic defensive code audits across the Linux networking subsystem. During our audit of the NC-SI (Network Controller Sideband Interface) stack, we uncovered a remote heap buffer overflow in `net/ncsi/ncsi-rsp.c` reachable from a compromised or malicious BMC sideband interface. Below are the technical findings, dataflow analysis, and a patch ready for upstream review. =================================================================== 1. Vulnerability Summary =================================================================== In `net/ncsi/ncsi-rsp.c`, `ncsi_rsp_handler_gp()` processes `GET_PARAMETERS` responses. The function parses MAC and VLAN filter lists from the response frame and copies them into driver arrays (`ncmf->addrs` and `ncvf->vids`). The buffers `ncmf->addrs` and `ncvf->vids` are allocated during `ncsi_rsp_handler_gc()` sized strictly from the counts returned in the `GET_CAPABILITIES` (GC) response. However, `ncsi_rsp_handler_gp()` uses `rsp->mac_cnt` and `rsp->vlan_cnt` from the subsequent `GET_PARAMETERS` response to drive its copy loops without verifying that these counts fit within the allocated buffer sizes. A malicious or compromised BMC responding on the sideband interface can provide `mac_cnt` or `vlan_cnt` values exceeding the allocated capacities (e.g. `mac_cnt = 255`), causing an out-of-bounds slab heap write of attacker-controlled MAC/VLAN data (~1500 bytes into kmalloc heap). =================================================================== 2. Affected Code & Root Cause =================================================================== Location: `net/ncsi/ncsi-rsp.c` (around line 892)static int ncsi_rsp_handler_gp(struct ncsi_request *nr) { ... for (i = 0; i < rsp->mac_cnt; i++) { pdata = (unsigned char *)rsp + 48 + i * 8; memcpy(&ncmf->addrs[i * ETH_ALEN], pdata, ETH_ALEN); } ... for (i = 0; i < rsp->vlan_cnt; i++) { pdata = (unsigned char *)rsp + 48 + rsp->mac_cnt * 8 + i * 4; ncvf->vids[i] = ntohs(*(__be16 *)pdata); }Because `ncmf->addrs` was allocated in `ncsi_rsp_handler_gc()` sized to `(uc_cnt + mc_cnt + mixed_cnt) * ETH_ALEN`, if `rsp->mac_cnt` exceeds this sum, `memcpy()` writes past the buffer boundary. Furthermore, filter bitmaps are fixed 64-bit masks (`u64`), so counts over 64 cause bitfield operations in `ncsi-manage.c` to walk past the u64 boundary. =================================================================== 3. Proposed Patch =================================================================== From: Nikhil Agrawal <redacted> Subject: [PATCH] net/ncsi: Bound mac_cnt and vlan_cnt in ncsi_rsp_handler_gp() In ncsi_rsp_handler_gp(), the driver copies MAC and VLAN filter entries from the GET_PARAMETERS response into allocated arrays (ncmf->addrs and ncvf->vids). The loop boundaries currently use the counts supplied in the response frame (rsp->mac_cnt and rsp->vlan_cnt) without bounding them against the buffer sizes allocated during ncsi_rsp_handler_gc(). If a response specifies more MAC or VLAN entries than were allocated, the loops overflow the slab buffers. Bound rsp->mac_cnt and rsp->vlan_cnt to the allocated filter capacities, and check for null buffers. Fixes: e6f449a37b9b ("net/ncsi: Add support for NCSI 1.1") Cc: stable@vger.kernel.org Reported-by: Mettle Labs Security Team <redacted> Signed-off-by: Nikhil Agrawal <redacted>
Same comments as for your other patches.
quoted hunk
--- net/ncsi/ncsi-rsp.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c index e1a2b3c..d4e5f6a 100644 --- a/net/ncsi/ncsi-rsp.c +++ b/net/ncsi/ncsi-rsp.c@@ -880,6 +880,14 @@ static int ncsi_rsp_handler_gp(struct ncsi_request *nr) return -EINVAL; ncmf = &nc->mac_filter; + if (!ncmf->addrs) + return -EINVAL; + if (rsp->mac_cnt > (ncmf->n_uc + ncmf->n_mc + ncmf->n_mixed)) + return -EINVAL; + + ncvf = &nc->vlan_filter; + if (rsp->vlan_cnt && (!ncvf->vids || rsp->vlan_cnt > ncvf->n_vids)) + return -EINVAL; for (i = 0; i < rsp->mac_cnt; i++) { pdata = (unsigned char *)rsp + 48 + i * 8;
Same space mangling that needs fixing.
-- =================================================================== 4. Coordination =================================================================== We adhere strictly to the Linux kernel 7-day coordinated disclosure policy. Please let us know if any further details or traces are needed.
Since you sent to a public list there's no disclosure involved.
Best regards, Nikhil Agrawal Mettle Labs mettlelabs.ai
Willy