Thread (1 message) 1 message, 1 author, 4d ago

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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help