* [PATCH net-next 0/2] net: dsa: mv88e6xxx: ethtool n-tuple follow ups
@ 2026-09-18 18:53 Jakub Kicinski
2026-09-18 18:53 ` [PATCH net-next 1/2] net: dsa: mv88e6xxx: check the port when reading back a policy rule Jakub Kicinski
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Jakub Kicinski @ 2026-09-18 18:53 UTC (permalink / raw)
To: davem
Cc: netdev, edumazet, pabeni, andrew+netdev, horms, olteanv,
Jakub Kicinski
Here are two small tweaks to the mv88e6xxx n-tuple filter handling
suggested by Sashiko when reviewing commit b1fffc273112 ("net: dsa:
mv88e6xxx: bound the policy rule dump by the caller's buffer size")
At the high level the problem is that the driver has shared rule
table but for some ops it doesn't check whether the rule operated
on belongs to the port on which the ethtool request was sent.
I initially thought that this could be intentional, but on closer
look I don't think it really works..
Sending for net-next, because this is AI-induced, build-tested-only
slop-code. The outcome is unlikely and results in mis-configuration,
no crashes.
Jakub Kicinski (2):
net: dsa: mv88e6xxx: check the port when reading back a policy rule
net: dsa: mv88e6xxx: check the port when deleting a policy rule
drivers/net/dsa/mv88e6xxx/chip.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
--
2.55.0
^ permalink raw reply [flat|nested] 6+ messages in thread* [PATCH net-next 1/2] net: dsa: mv88e6xxx: check the port when reading back a policy rule 2026-09-18 18:53 [PATCH net-next 0/2] net: dsa: mv88e6xxx: ethtool n-tuple follow ups Jakub Kicinski @ 2026-09-18 18:53 ` Jakub Kicinski 2026-09-21 18:55 ` netdev-bot+sashiko 2026-09-18 18:53 ` [PATCH net-next 2/2] net: dsa: mv88e6xxx: check the port when deleting " Jakub Kicinski 2026-09-22 11:40 ` [PATCH net-next 0/2] net: dsa: mv88e6xxx: ethtool n-tuple follow ups patchwork-bot+netdevbpf 2 siblings, 1 reply; 6+ messages in thread From: Jakub Kicinski @ 2026-09-18 18:53 UTC (permalink / raw) To: davem Cc: netdev, edumazet, pabeni, andrew+netdev, horms, olteanv, Jakub Kicinski, andrew, f.fainelli, vivien.didelot chip->policies is one IDR for the whole switch, so the location an ETHTOOL_GRXCLSRULE caller supplies can name a rule belonging to any port. mv88e6xxx_get_rxnfc() copies it out without looking at policy->port, which lets a user on one user port read the MAC address and VID of a policy an admin installed on another. ETHTOOL_GRXCLSRULE needs no CAP_NET_ADMIN. The GRXCLSRLCNT and GRXCLSRLALL arms of the same switch statement already filter on policy->port, which makes the GRXCLSRULE omission look unintentional. Nonetheless, changing this does carry some regression risk. Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- CC: andrew@lunn.ch CC: olteanv@gmail.com CC: f.fainelli@gmail.com CC: vivien.didelot@gmail.com --- drivers/net/dsa/mv88e6xxx/chip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 7f68a0c55802..daef7c78b860 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2457,7 +2457,7 @@ static int mv88e6xxx_get_rxnfc(struct dsa_switch *ds, int port, case ETHTOOL_GRXCLSRULE: err = -ENOENT; policy = idr_find(&chip->policies, fs->location); - if (policy) { + if (policy && policy->port == port) { memcpy(fs, &policy->fs, sizeof(*fs)); err = 0; } -- 2.55.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net-next 1/2] net: dsa: mv88e6xxx: check the port when reading back a policy rule 2026-09-18 18:53 ` [PATCH net-next 1/2] net: dsa: mv88e6xxx: check the port when reading back a policy rule Jakub Kicinski @ 2026-09-21 18:55 ` netdev-bot+sashiko 0 siblings, 0 replies; 6+ messages in thread From: netdev-bot+sashiko @ 2026-09-21 18:55 UTC (permalink / raw) To: kuba Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, olteanv, andrew, f.fainelli, vivien.didelot Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider. Critical: 0 · High: 0 · Medium: 1 · Low: 0 (1) 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). - [Medium] Missing `Fixes:` tag. Pre-existing issues: - [Low] SRXCLSRLDEL cross-port delete: mv88e6xxx_set_rxnfc()'s ETHTOOL_SRXCLSRLDEL arm looks up fs->location in the switch-wide… -- net: dsa: mv88e6xxx: check the port when reading back a policy rule This adds a policy->port == port test to the ETHTOOL_GRXCLSRULE arm of mv88e6xxx_get_rxnfc(), so a location belonging to another user port is no longer copied back to the caller. The GRXCLSRLCNT and GRXCLSRLALL arms of the same switch already filter on policy->port. > net: dsa: mv88e6xxx: check the port when reading back a policy rule > > chip->policies is one IDR for the whole switch, so the location an > ETHTOOL_GRXCLSRULE caller supplies can name a rule belonging to any port. > mv88e6xxx_get_rxnfc() copies it out without looking at policy->port, which > lets a user on one user port read the MAC address and VID of a policy an > admin installed on another. ETHTOOL_GRXCLSRULE needs no CAP_NET_ADMIN. [ ... ] > Signed-off-by: Jakub Kicinski <kuba@kernel.org> [Severity: Medium] Should this carry a Fixes: tag? git blame on the pre-patch GRXCLSRULE arm in mv88e6xxx_get_rxnfc(): policy = idr_find(&chip->policies, fs->location); if (policy) { memcpy(fs, &policy->fs, sizeof(*fs)); attributes those lines to da7dc87553046 ("net: dsa: mv88e6xxx: add RXNFC support"). The earlier fix to the same function, b1fffc273112e ("net: dsa: mv88e6xxx: bound the policy rule dump by the caller's buffer size"), already uses: Fixes: da7dc8755304 ("net: dsa: mv88e6xxx: add RXNFC support") Without that trailer, stable tooling has nothing to key on for the unprivileged cross-port read described above. The commit message says "changing this does carry some regression risk" -- is that hedge the reason the trailer was left out, and could that be stated explicitly? > diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c > index 8cf5681f5806..461167199a71 100644 > --- a/drivers/net/dsa/mv88e6xxx/chip.c > +++ b/drivers/net/dsa/mv88e6xxx/chip.c > @@ -2457,7 +2457,7 @@ static int mv88e6xxx_get_rxnfc(struct dsa_switch *ds, int port, > case ETHTOOL_GRXCLSRULE: > err = -ENOENT; > policy = idr_find(&chip->policies, fs->location); > - if (policy) { > + if (policy && policy->port == port) { > memcpy(fs, &policy->fs, sizeof(*fs)); > err = 0; > } [Severity: Low] This isn't a bug introduced by this patch, but the delete side of the same IDR has the identical missing check. In mv88e6xxx_set_rxnfc(): case ETHTOOL_SRXCLSRLDEL: err = -ENOENT; policy = idr_remove(&chip->policies, fs->location); if (policy) { policy->action = MV88E6XXX_POLICY_ACTION_NORMAL; err = mv88e6xxx_policy_apply(chip, port, policy); devm_kfree(chip->dev, policy); } A location owned by port A can be removed and freed while mv88e6xxx_policy_apply() is called with the caller's port B, so the hardware side effects (mv88e6xxx_port_db_load_purge() and port_set_policy()) are applied to the wrong port, and the "mapping still in use" loop filters on policy->port == port: if (action == MV88E6XXX_POLICY_ACTION_NORMAL) idr_for_each_entry(&chip->policies, policy, id) if (policy->port == port && policy->mapping == mapping && policy->action != action) return 0; This arm sits in the privileged default of dev_ethtool(), so CAP_NET_ADMIN is required to reach it. This one is already handled inside the same series -- the following patch, "net: dsa: mv88e6xxx: check the port when deleting a policy rule", adds the same policy->port == port test to the delete arm, so nothing remains at the end of the range. Noting it here only for completeness. -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260918185326.3940857-1-kuba%40kernel.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH net-next 2/2] net: dsa: mv88e6xxx: check the port when deleting a policy rule 2026-09-18 18:53 [PATCH net-next 0/2] net: dsa: mv88e6xxx: ethtool n-tuple follow ups Jakub Kicinski 2026-09-18 18:53 ` [PATCH net-next 1/2] net: dsa: mv88e6xxx: check the port when reading back a policy rule Jakub Kicinski @ 2026-09-18 18:53 ` Jakub Kicinski 2026-09-21 18:55 ` netdev-bot+sashiko 2026-09-22 11:40 ` [PATCH net-next 0/2] net: dsa: mv88e6xxx: ethtool n-tuple follow ups patchwork-bot+netdevbpf 2 siblings, 1 reply; 6+ messages in thread From: Jakub Kicinski @ 2026-09-18 18:53 UTC (permalink / raw) To: davem Cc: netdev, edumazet, pabeni, andrew+netdev, horms, olteanv, Jakub Kicinski, andrew, f.fainelli, vivien.didelot ETHTOOL_SRXCLSRLDEL removes the policy the location names out of the switch-wide IDR without checking which port owns it, then hands it to mv88e6xxx_policy_apply() along with the port the request arrived on. Deleting another port's rule therefore purges an ATU entry on and clears the policy register of the requesting port, while the owning port keeps its hardware policy - and, with the software object freed, no longer has a location that can be used to remove it. Initially I thought that we're just able to delete a rule from one port using another port as a handle. But if the reading of the code outlined above is correct, this is just borken, not a "feature" someone could depend on. Signed-off-by: Jakub Kicinski <kuba@kernel.org> --- CC: andrew@lunn.ch CC: olteanv@gmail.com CC: f.fainelli@gmail.com CC: vivien.didelot@gmail.com --- drivers/net/dsa/mv88e6xxx/chip.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index daef7c78b860..7b34cae9c542 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -2503,8 +2503,9 @@ static int mv88e6xxx_set_rxnfc(struct dsa_switch *ds, int port, break; case ETHTOOL_SRXCLSRLDEL: err = -ENOENT; - policy = idr_remove(&chip->policies, fs->location); - if (policy) { + policy = idr_find(&chip->policies, fs->location); + if (policy && policy->port == port) { + idr_remove(&chip->policies, fs->location); policy->action = MV88E6XXX_POLICY_ACTION_NORMAL; err = mv88e6xxx_policy_apply(chip, port, policy); devm_kfree(chip->dev, policy); -- 2.55.0 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH net-next 2/2] net: dsa: mv88e6xxx: check the port when deleting a policy rule 2026-09-18 18:53 ` [PATCH net-next 2/2] net: dsa: mv88e6xxx: check the port when deleting " Jakub Kicinski @ 2026-09-21 18:55 ` netdev-bot+sashiko 0 siblings, 0 replies; 6+ messages in thread From: netdev-bot+sashiko @ 2026-09-21 18:55 UTC (permalink / raw) To: kuba Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, olteanv, andrew, f.fainelli, vivien.didelot Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider. Critical: 0 · High: 0 · Medium: 1 (1) · 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). - [Medium] Missing `Fixes:` tag. Pre-existing issues: - [Medium] In the ETHTOOL_SRXCLSRLDEL path of mv88e6xxx_set_rxnfc() the policy object is unlinked from chip->policies (idr_remove(),… -- net: dsa: mv88e6xxx: check the port when deleting a policy rule This changes the ETHTOOL_SRXCLSRLDEL path in mv88e6xxx_set_rxnfc() to look the policy up with idr_find() and only remove it when policy->port matches the port the request arrived on, so one port can no longer be used as a handle to delete another port's rule. > diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c > index 461167199a71..70411d147677 100644 > --- a/drivers/net/dsa/mv88e6xxx/chip.c > +++ b/drivers/net/dsa/mv88e6xxx/chip.c > @@ -2503,8 +2503,9 @@ static int mv88e6xxx_set_rxnfc(struct dsa_switch *ds, int port, > break; > case ETHTOOL_SRXCLSRLDEL: > err = -ENOENT; > - policy = idr_remove(&chip->policies, fs->location); > - if (policy) { > + policy = idr_find(&chip->policies, fs->location); > + if (policy && policy->port == port) { > + idr_remove(&chip->policies, fs->location); [Severity: Medium] Should this carry a Fixes: tag? git blame of the pre-image of this hunk attributes the whole delete sequence to da7dc87553046 ("net: dsa: mv88e6xxx: add RXNFC support"), which went in for v5.4, so the broken cross-port delete exists in every stable tree since then. Without the trailer the stable tooling won't pick this up: Fixes: da7dc87553046 ("net: dsa: mv88e6xxx: add RXNFC support") > policy->action = MV88E6XXX_POLICY_ACTION_NORMAL; > err = mv88e6xxx_policy_apply(chip, port, policy); > devm_kfree(chip->dev, policy); [Severity: Medium] This is a pre-existing issue and not something this patch introduces, but while the delete path is being touched: should the idr_remove() and devm_kfree() be conditional on mv88e6xxx_policy_apply() succeeding? mv88e6xxx_policy_apply() can fail on a register/bus error, both in the ATU rewrite and in the policy register write: drivers/net/dsa/mv88e6xxx/chip.c:mv88e6xxx_policy_apply() { ... err = mv88e6xxx_port_db_load_purge(chip, port, addr, vid, state); if (err) return err; ... return chip->info->ops->port_set_policy(chip, port, mapping, action); } In that case the switch still has the ATU entry in MV88E6XXX_G1_ATU_DATA_STATE_{UC,MC}_STATIC_POLICY and/or still has the port's policy register mapping DA/SA to DISCARD, but the software object and its IDR location are already gone. Does that leave the rule unaddressable from userspace? ETHTOOL_GRXCLSRLALL no longer lists it, a retried ETHTOOL_SRXCLSRLDEL now returns -ENOENT because idr_find() returns NULL, and the still-programmed mapping is invisible to the in-use scan at the end of mv88e6xxx_policy_apply(): if (action == MV88E6XXX_POLICY_ACTION_NORMAL) idr_for_each_entry(&chip->policies, policy, id) if (policy->port == port && policy->mapping == mapping && policy->action != action) return 0; The freed id can also be handed out again by a later ETHTOOL_SRXCLSRLINS, so a new location would describe hardware programmed for a different MAC. Doing the idr_remove()/devm_kfree() only after mv88e6xxx_policy_apply() returns 0 would avoid this. -- Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260918185326.3940857-1-kuba%40kernel.org ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH net-next 0/2] net: dsa: mv88e6xxx: ethtool n-tuple follow ups 2026-09-18 18:53 [PATCH net-next 0/2] net: dsa: mv88e6xxx: ethtool n-tuple follow ups Jakub Kicinski 2026-09-18 18:53 ` [PATCH net-next 1/2] net: dsa: mv88e6xxx: check the port when reading back a policy rule Jakub Kicinski 2026-09-18 18:53 ` [PATCH net-next 2/2] net: dsa: mv88e6xxx: check the port when deleting " Jakub Kicinski @ 2026-09-22 11:40 ` patchwork-bot+netdevbpf 2 siblings, 0 replies; 6+ messages in thread From: patchwork-bot+netdevbpf @ 2026-09-22 11:40 UTC (permalink / raw) To: Jakub Kicinski Cc: davem, netdev, edumazet, pabeni, andrew+netdev, horms, olteanv Hello: This series was applied to netdev/net-next.git (main) by Paolo Abeni <pabeni@redhat.com>: On Fri, 18 Sep 2026 11:53:24 -0700 you wrote: > Here are two small tweaks to the mv88e6xxx n-tuple filter handling > suggested by Sashiko when reviewing commit b1fffc273112 ("net: dsa: > mv88e6xxx: bound the policy rule dump by the caller's buffer size") > > At the high level the problem is that the driver has shared rule > table but for some ops it doesn't check whether the rule operated > on belongs to the port on which the ethtool request was sent. > > [...] Here is the summary with links: - [net-next,1/2] net: dsa: mv88e6xxx: check the port when reading back a policy rule https://git.kernel.org/netdev/net-next/c/e3624f5eeac4 - [net-next,2/2] net: dsa: mv88e6xxx: check the port when deleting a policy rule https://git.kernel.org/netdev/net-next/c/242ebf4c5114 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-09-22 11:41 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-09-18 18:53 [PATCH net-next 0/2] net: dsa: mv88e6xxx: ethtool n-tuple follow ups Jakub Kicinski 2026-09-18 18:53 ` [PATCH net-next 1/2] net: dsa: mv88e6xxx: check the port when reading back a policy rule Jakub Kicinski 2026-09-21 18:55 ` netdev-bot+sashiko 2026-09-18 18:53 ` [PATCH net-next 2/2] net: dsa: mv88e6xxx: check the port when deleting " Jakub Kicinski 2026-09-21 18:55 ` netdev-bot+sashiko 2026-09-22 11:40 ` [PATCH net-next 0/2] net: dsa: mv88e6xxx: ethtool n-tuple follow ups patchwork-bot+netdevbpf
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox