mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] net: ncsi: clamp filter table counts in GP response handling
@ 2026-10-02 10:17 Vamsi Krishna Kattamuri
  2026-10-02 10:24 ` netdev-bot+sinfo
  0 siblings, 1 reply; 5+ messages in thread
From: Vamsi Krishna Kattamuri @ 2026-10-02 10:17 UTC (permalink / raw)
  To: netdev, sam
  Cc: fercerpav, davem, edumazet, kuba, pabeni, horms, gwshan, joel,
	linux-kernel, stable

ncsi_rsp_handler_gp() iterates over the MAC address and VLAN filter
tables using the counts from the Get Parameters response itself,
rsp->mac_cnt and rsp->vlan_cnt.  The arrays it writes into, however,
were allocated by the Get Controller Capabilities handler from the
independent rsp->uc_cnt, rsp->mc_cnt, rsp->mixed_cnt and rsp->vlan_cnt
fields.

A malicious or buggy NCSI device can therefore report contradictory
counts in the two responses - for example a GC response advertising
a single unicast address filter followed by a GP response with
mac_cnt = 255.  The GP handler then memcpy()s 255 MAC addresses into
the 6-byte kzalloc()ed buffer, a heap out-of-bounds write of roughly
1.5KB of device-controlled data, and the same applies to vlan_cnt
versus the vids[] array.

The loop indices are additionally used as bit numbers for
set_bit()/clear_bit() on the u64 filter bitmaps, so any count larger
than 64 writes out-of-bounds bits into struct ncsi_channel.

Clamp both loops to the number of entries actually allocated for the
channel and to the capacity of the bitmap word, mirroring the
validation the SVF and SMA handlers already apply to their indices.

Fixes: 138635cc27c9 ("net/ncsi: NCSI response packet handler")
Cc: stable@vger.kernel.org
Signed-off-by: Vamsi Krishna Kattamuri <kattamurivamsikrishna17@gmail.com>
---
 net/ncsi/ncsi-rsp.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
index fbd84bc8026a..fa1ed405dfbb 100644
--- a/net/ncsi/ncsi-rsp.c
+++ b/net/ncsi/ncsi-rsp.c
@@ -883,7 +883,9 @@ static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
 	ncmf = &nc->mac_filter;
 	spin_lock_irqsave(&nc->lock, flags);
 	bitmap = &ncmf->bitmap;
-	for (i = 0; i < rsp->mac_cnt; i++, pdata += 6) {
+	for (i = 0; i < rsp->mac_cnt &&
+	     i < ncmf->n_uc + ncmf->n_mc + ncmf->n_mixed &&
+	     i < sizeof(ncmf->bitmap) * 8; i++, pdata += 6) {
 		if (!(enable & (0x1 << i)))
 			clear_bit(i, bitmap);
 		else
@@ -898,7 +900,8 @@ static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
 	ncvf = &nc->vlan_filter;
 	bitmap = &ncvf->bitmap;
 	spin_lock_irqsave(&nc->lock, flags);
-	for (i = 0; i < rsp->vlan_cnt; i++, pdata += 2) {
+	for (i = 0; i < rsp->vlan_cnt && i < ncvf->n_vids &&
+	     i < sizeof(ncvf->bitmap) * 8; i++, pdata += 2) {
 		if (!(enable & (0x1 << i)))
 			clear_bit(i, bitmap);
 		else
-- 
2.47.3

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] net: ncsi: clamp filter table counts in GP response handling
  2026-10-02 10:17 [PATCH] net: ncsi: clamp filter table counts in GP response handling Vamsi Krishna Kattamuri
@ 2026-10-02 10:24 ` netdev-bot+sinfo
  0 siblings, 0 replies; 5+ messages in thread
From: netdev-bot+sinfo @ 2026-10-02 10:24 UTC (permalink / raw)
  To: Vamsi Krishna Kattamuri
  Cc: netdev, sam, fercerpav, davem, edumazet, kuba, pabeni, horms,
	gwshan, joel, linux-kernel, stable

Hi!

This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:

 - How the issue was discovered, e.g. hit in production, hit during
   development, syzbot report, manual code inspection, LLM or static
   analysis tool scan.

 - Whether the issue was actually triggered, or is only theoretical
   (e.g. found by code inspection). If it was triggered please include
   the symptoms, like the stack trace or error messages.

Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.

The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] net: ncsi: clamp filter table counts in GP response handling
  2026-09-28 18:59 Vamsi Krishna Kattamuri
  2026-09-28 19:05 ` netdev-bot+sinfo
@ 2026-10-01 22:01 ` netdev-bot+sashiko
  1 sibling, 0 replies; 5+ messages in thread
From: netdev-bot+sashiko @ 2026-10-01 22:01 UTC (permalink / raw)
  To: kattamurivamsikrishna17
  Cc: netdev, sam, fercerpav, davem, edumazet, kuba, pabeni, horms,
	gwshan, joel, linux-kernel, stable

Thank you for your contribution! Sashiko AI review found 4 potential
issue(s) to consider.

Critical: 0 · High: 2 (1) · Medium: 2 (2) · Low: 0

If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).

- [High] The fix is incomplete, and the commit message is wrong about the
  SVF/SMA handlers.
- [High] The new limits in ncsi_rsp_handler_gp() assume n_uc+n_mc+n_mixed
  and n_vids always describe the buffers behind ncmf->addrs and…
- [Medium] The new limit on the MAC loop in ncsi_rsp_handler_gp()
  (net/ncsi/ncsi-rsp.c:886-888) also limits how far the wire cursor…
- [Medium] ncsi_rsp_handler_gp() now reads n_uc+n_mc+n_mixed and n_vids
  under nc->lock as the size of ncmf->addrs / ncvf->vids.

Pre-existing issues:
- [High] This problem wasn't introduced by this patch, but the loops it
  changes still read past the end of the received GP response.
- [Medium] This problem wasn't introduced by this patch, but the new
  limit of 64 (sizeof(bitmap)*8) does not match the width of the on-wire…
- [Medium] This problem wasn't introduced by this patch, but
  ncsi_rsp_handler_gc() (net/ncsi/ncsi-rsp.c:816 and 823) assigns new…

--

net: ncsi: clamp filter table counts in GP response handling

This patch bounds the MAC and VLAN filter table loops in
ncsi_rsp_handler_gp(). The new bounds are the entry counts allocated by the
Get Capabilities handler and the width of the u64 filter bitmaps. The goal
is to stop a device that reports inconsistent GC and GP counts from causing
heap out-of-bounds writes and out-of-bounds bit operations.

> diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
> index fbd84bc8026a..fa1ed405dfbb 100644
> --- a/net/ncsi/ncsi-rsp.c
> +++ b/net/ncsi/ncsi-rsp.c
> @@ -883,7 +883,9 @@ static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
>  	ncmf = &nc->mac_filter;
>  	spin_lock_irqsave(&nc->lock, flags);
>  	bitmap = &ncmf->bitmap;
> -	for (i = 0; i < rsp->mac_cnt; i++, pdata += 6) {
> +	for (i = 0; i < rsp->mac_cnt &&
> +	     i < ncmf->n_uc + ncmf->n_mc + ncmf->n_mixed &&
> +	     i < sizeof(ncmf->bitmap) * 8; i++, pdata += 6) {

[Severity: Medium]
When this loop exits early, is pdata still inside the MAC table when the
VLAN loop starts?

In the GP response the VLAN tag table starts at
rsp + 48 + rsp->mac_cnt * 6. With this change, pdata only moves forward for
the MAC entries that are actually stored.

Take the example from the commit message: GC advertises one unicast filter
and GP reports mac_cnt = 255. The MAC loop stops after one entry and leaves
pdata at rsp + 54. The VLAN loop then runs:

	ncvf->vids[i] = ntohs(*(__be16 *)pdata);

so it stores MAC table bytes as VLAN IDs. The enable bits still come from
the correctly located rsp->vlan_enable.

Those bogus vids[] values are used later:

  set_one_vid() skips a VID it already finds in vids[], so a real VID may
  never be programmed

  clear_one_vid() sends SVF commands for the bogus VIDs

  NCSI_CMD_PKG_INFO reports them to userspace

Could the patch limit only the number of stored entries, and reset the
cursor before the VLAN loop? For example:

	pdata = (unsigned char *)rsp + 48 + rsp->mac_cnt * ETH_ALEN;

[Severity: High]
This bound assumes that n_uc + n_mc + n_mixed always describes the buffer
behind ncmf->addrs. The commit message calls it "the number of entries
actually allocated". Does that hold when a later GC allocation fails?

ncsi_rsp_handler_gc() stores the allocation result before it updates the
counts:

	nc->mac_filter.addrs = kzalloc(size, GFP_ATOMIC);
	if (!nc->mac_filter.addrs)
		return -ENOMEM;
	nc->mac_filter.n_uc = rsp->uc_cnt;
	...
	nc->vlan_filter.vids = kcalloc(rsp->vlan_cnt,
				       sizeof(*nc->vlan_filter.vids),
				       GFP_ATOMIC);
	if (!nc->vlan_filter.vids)
		return -ENOMEM;

Suppose a first GC succeeds and a second GC for the same channel hits a
GFP_ATOMIC failure. Then addrs or vids is NULL, but the old non-zero counts
are still there.

A second GC can come from NCSI_CMD_SEND_CMD, because ncsi_send_cmd_nl()
sets nca.type = hdr->type. It can also come from a device that answers any
pending request with a GC-type response, because ncsi_rcv_rsp() chooses the
handler from the response type.

The next GP response passes the new bound and runs either:

	memcpy(&ncmf->addrs[i * ETH_ALEN], pdata, ETH_ALEN);

or:

	ncvf->vids[i] = ntohs(*(__be16 *)pdata);

through a NULL base in softirq context. clear_one_vid() and set_one_vid()
would dereference the NULL vids pointer in the same way.

Could ncsi_rsp_handler_gc() allocate into local variables and install the
new pointers and counts together only on success? Resetting the counts to
zero on failure would also work.

[Severity: Medium]
Does nc->lock keep the count and the buffer consistent here?

The new bound reads n_uc + n_mc + n_mixed (and n_vids in the VLAN loop)
under nc->lock. The only writer, ncsi_rsp_handler_gc(), does not take
nc->lock. It also updates in two steps: it installs the new buffer first
and writes the counts afterwards.

ncsi_rcv_rsp() releases ndp->lock before it calls nrh->handler(). So
nothing in NCSI stops the GC and GP handlers from running at the same time.

Suppose GC and GP responses for the same channel are handled at the same
time on different CPUs. Can GP read the old, larger count together with the
new, smaller addrs buffer? That would give the same heap out-of-bounds
memcpy() this patch is trying to prevent.

In practice NCSI frames probably arrive on one RX queue, which would
serialize them, but nothing guarantees that. Would it help for
ncsi_rsp_handler_gc() to publish the pointers and counts together under
nc->lock?

>  		if (!(enable & (0x1 << i)))

[Severity: Medium]
This isn't a bug introduced by this patch, but the new limit of
sizeof(ncmf->bitmap) * 8 is wider than the enable fields.

Here enable holds rsp->mac_enable, which is 8 bits. In the VLAN loop it
holds ntohs(rsp->vlan_enable), which is 16 bits. The test is an int shift:

	if (!(enable & (0x1 << i)))

For MAC i >= 8 and VLAN i >= 16 there is no enable bit on the wire, so
those entries are always cleared.

Indexes 32 to 63 can still be reached when both the GC and GP counts are
above 32. For those, 0x1 << i is undefined behaviour (UBSAN
shift-out-of-bounds). On x86 the shift count wraps, so bits can be set
wrongly.

The same shift ran for i up to 254 before this patch. Would a limit based
on the enable field widths (8 for MAC, 16 for VLAN) avoid it?

>  			clear_bit(i, bitmap);
>  		else
> @@ -898,7 +900,8 @@ static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
>  	ncvf = &nc->vlan_filter;
>  	bitmap = &ncvf->bitmap;
>  	spin_lock_irqsave(&nc->lock, flags);
> -	for (i = 0; i < rsp->vlan_cnt; i++, pdata += 2) {
> +	for (i = 0; i < rsp->vlan_cnt && i < ncvf->n_vids &&
> +	     i < sizeof(ncvf->bitmap) * 8; i++, pdata += 2) {

[Severity: High]
The commit message says:

  "so any count larger than 64 writes out-of-bounds bits into struct
  ncsi_channel"

and:

  "mirroring the validation the SVF and SMA handlers already apply to their
  indices"

Does this patch fully close that problem?

The 64-bit limit is only added to the two GP loops. The root cause seems to
be ncsi_rsp_handler_gc(), which stores the device-supplied counts without
limiting them to the u64 bitmap:

	nc->vlan_filter.bitmap = U64_MAX;
	nc->vlan_filter.n_vids = rsp->vlan_cnt;

vlan_cnt can be up to 255, and uc_cnt + mc_cnt + mixed_cnt can be up to
765.

On every channel configuration, the ncsi_dev_state_config_clear_vids state
calls clear_one_vid() in net/ncsi/ncsi-manage.c repeatedly until it returns
-1:

	index = find_first_bit(bitmap, ncf->n_vids);
	...
	vid = ncf->vids[index];

	clear_bit(index, bitmap);
	ncf->vids[index] = 0;

With n_vids > 64, once the 64 real bits are cleared, find_first_bit() keeps
scanning into the next member, the u16 *vids pointer. Can clear_bit() then
clear bits in that kernel pointer, and the next line write through the
corrupted pointer? The only trigger needed is a GC response with
vlan_cnt > 64.

The same mismatch between the count and the bitmap width seems to exist in
these places:

  set_one_vid(): find_first_zero_bit() and set_bit() are bounded only by
  n_vids

  ncsi_rsp_handler_svf(): cmd->index is checked only against ncf->n_vids
  before set_bit()/test_and_clear_bit(cmd->index - 1, bitmap)

  ncsi_rsp_handler_sma(): cmd->index is checked only against
  n_uc + n_mc + n_mixed before set_bit()/clear_bit(cmd->index - 1, bitmap)

  ncsi_write_channel_info(): find_next_bit(&ncf->bitmap, ncf->n_vids, ...)
  reads past the u64

With NCSI_CMD_SEND_CMD, userspace chooses the SVF/SMA index, so the checks
the commit message mirrors have the same gap.

Would it be better to clamp or reject the counts in ncsi_rsp_handler_gc(),
so that n_vids is at most 64 and the MAC total is at most 64? Then the
sizeof(bitmap) * 8 limits in the GP loops would not be needed.

[Severity: High]
This isn't a bug introduced by this patch, but these loops can still read
past the end of the received GP response.

GP is registered as a variable-length response:

	{ NCSI_PKT_RSP_GP,     -1, ncsi_rsp_handler_gp      },

so ncsi_rcv_rsp() does:

	payload = nrh->payload;
	if (payload < 0)
		payload = ntohs(hdr->length);
	ret = ncsi_validate_rsp_pkt(nr, payload);

As a result, the ntohs(h->common.length) != payload check in
ncsi_validate_rsp_pkt() can never fail. The checksum is then read at an
offset the device controls, with no check against skb->len:

	pchecksum = (__be32 *)((void *)(h + 1) + ALIGN(payload, 4) - 4);

That offset can be up to about 64KB past the header.

Nothing in net/ncsi calls pskb_may_pull() or checks skb->len for
responses. So ncsi_rsp_handler_gp() reads 48 bytes plus 6 per MAC entry and
2 per VLAN entry from skb_network_header(). Only the device-supplied counts
limit how far it reads.

A short GP frame with large counts would copy bytes from beyond the frame
into ncmf->addrs and ncvf->vids[]. VIDs whose enable bits are set are later
reported by ncsi_write_channel_info() through NCSI_CMD_PKG_INFO, which
needs no privilege.

Should the response length be checked against the skb before the handler
walks these tables?

[Severity: Medium]
This is a pre-existing issue, but ncsi_rsp_handler_gc() leaks the previous
nc->mac_filter.addrs and nc->vlan_filter.vids buffers when a channel gets
more than one GC response:

	nc->mac_filter.addrs = kzalloc(size, GFP_ATOMIC);
	...
	nc->vlan_filter.vids = kcalloc(rsp->vlan_cnt,
	...

Neither old buffer is freed before it is overwritten. The only kfree() of
these pointers is in ncsi_remove_channel().

A repeated GC can come from:

  NCSI_CMD_SEND_CMD

  a device sending a GC-type response to any pending request

  a re-probe, where ncsi_add_channel() returns the existing channel

Should the old buffers be freed when they are replaced?

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/CAANnmVAicVNhy8fMUaFJ_N%2Bb4DnbwpYi1MOL4yMVisix1WCX4w%40mail.gmail.com

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] net: ncsi: clamp filter table counts in GP response handling
  2026-09-28 18:59 Vamsi Krishna Kattamuri
@ 2026-09-28 19:05 ` netdev-bot+sinfo
  2026-10-01 22:01 ` netdev-bot+sashiko
  1 sibling, 0 replies; 5+ messages in thread
From: netdev-bot+sinfo @ 2026-09-28 19:05 UTC (permalink / raw)
  To: Vamsi Krishna Kattamuri
  Cc: netdev, sam, fercerpav, davem, edumazet, kuba, pabeni, horms,
	gwshan, joel, linux-kernel, stable

Hi!

This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:

 - How the issue was discovered, e.g. hit in production, hit during
   development, syzbot report, manual code inspection, LLM or static
   analysis tool scan.

 - Whether the issue was actually triggered, or is only theoretical
   (e.g. found by code inspection). If it was triggered please include
   the symptoms, like the stack trace or error messages.

Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.

The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH] net: ncsi: clamp filter table counts in GP response handling
@ 2026-09-28 18:59 Vamsi Krishna Kattamuri
  2026-09-28 19:05 ` netdev-bot+sinfo
  2026-10-01 22:01 ` netdev-bot+sashiko
  0 siblings, 2 replies; 5+ messages in thread
From: Vamsi Krishna Kattamuri @ 2026-09-28 18:59 UTC (permalink / raw)
  To: netdev, sam
  Cc: fercerpav, davem, edumazet, kuba, pabeni, horms, gwshan, joel,
	linux-kernel, stable

ncsi_rsp_handler_gp() iterates over the MAC address and VLAN filter
tables using the counts from the Get Parameters response itself,
rsp->mac_cnt and rsp->vlan_cnt.  The arrays it writes into, however,
were allocated by the Get Controller Capabilities handler from the
independent rsp->uc_cnt, rsp->mc_cnt, rsp->mixed_cnt and rsp->vlan_cnt
fields.

A malicious or buggy NCSI device can therefore report contradictory
counts in the two responses - for example a GC response advertising
a single unicast address filter followed by a GP response with
mac_cnt = 255.  The GP handler then memcpy()s 255 MAC addresses into
the 6-byte kzalloc()ed buffer, a heap out-of-bounds write of roughly
1.5KB of device-controlled data, and the same applies to vlan_cnt
versus the vids[] array.

The loop indices are additionally used as bit numbers for
set_bit()/clear_bit() on the u64 filter bitmaps, so any count larger
than 64 writes out-of-bounds bits into struct ncsi_channel.

Clamp both loops to the number of entries actually allocated for the
channel and to the capacity of the bitmap word, mirroring the
validation the SVF and SMA handlers already apply to their indices.

Fixes: 138635cc27c9 ("net/ncsi: NCSI response packet handler")
Cc: stable@vger.kernel.org
Signed-off-by: Vamsi Krishna Kattamuri <kattamurivamsikrishna17@gmail.com>
---
 net/ncsi/ncsi-rsp.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/net/ncsi/ncsi-rsp.c b/net/ncsi/ncsi-rsp.c
index fbd84bc8026a..fa1ed405dfbb 100644
--- a/net/ncsi/ncsi-rsp.c
+++ b/net/ncsi/ncsi-rsp.c
@@ -883,7 +883,9 @@ static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
 	ncmf = &nc->mac_filter;
 	spin_lock_irqsave(&nc->lock, flags);
 	bitmap = &ncmf->bitmap;
-	for (i = 0; i < rsp->mac_cnt; i++, pdata += 6) {
+	for (i = 0; i < rsp->mac_cnt &&
+	     i < ncmf->n_uc + ncmf->n_mc + ncmf->n_mixed &&
+	     i < sizeof(ncmf->bitmap) * 8; i++, pdata += 6) {
 		if (!(enable & (0x1 << i)))
 			clear_bit(i, bitmap);
 		else
@@ -898,7 +900,8 @@ static int ncsi_rsp_handler_gp(struct ncsi_request *nr)
 	ncvf = &nc->vlan_filter;
 	bitmap = &ncvf->bitmap;
 	spin_lock_irqsave(&nc->lock, flags);
-	for (i = 0; i < rsp->vlan_cnt; i++, pdata += 2) {
+	for (i = 0; i < rsp->vlan_cnt && i < ncvf->n_vids &&
+	     i < sizeof(ncvf->bitmap) * 8; i++, pdata += 2) {
 		if (!(enable & (0x1 << i)))
 			clear_bit(i, bitmap);
 		else
-- 
2.47.3

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-02 10:24 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-02 10:17 [PATCH] net: ncsi: clamp filter table counts in GP response handling Vamsi Krishna Kattamuri
2026-10-02 10:24 ` netdev-bot+sinfo
  -- strict thread matches above, loose matches on Subject: below --
2026-09-28 18:59 Vamsi Krishna Kattamuri
2026-09-28 19:05 ` netdev-bot+sinfo
2026-10-01 22:01 ` netdev-bot+sashiko

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®