Skip to content

Commit 7410d11

Browse files
jamestiotioPaolo Abeni
authored andcommitted
macsec: fix promiscuity refcount leak in macsec_dev_open()
When a MACsec interface with IFF_PROMISC set is brought up on top of a device that has hardware offload enabled, macsec_dev_open() first calls dev_set_promiscuity(real_dev, 1) and then propagates the open to the offload device. If that propagation fails, the error path jumps to the clear_allmulti label, which only reverts allmulti and the unicast address. The promiscuity taken on the lower device is never dropped, so real_dev is left permanently stuck in promiscuous mode. Its promiscuity count can no longer be balanced from software. Add a clear_promisc label that drops the promiscuity reference and route the two offload failure paths to it. The dev_set_promiscuity() failure itself still jumps to clear_allmulti, since on that failure the count was not incremented. Fixes: 3cf3227 ("net: macsec: hardware offloading infrastructure") Cc: stable@vger.kernel.org Signed-off-by: James Raphael Tiovalen <jamestiotio@gmail.com> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Link: https://patch.msgid.link/20260705113629.187490-1-jamestiotio@gmail.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 389704e commit 7410d11

1 file changed

Lines changed: 5 additions & 2 deletions

File tree

drivers/net/macsec.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3615,19 +3615,22 @@ static int macsec_dev_open(struct net_device *dev)
36153615
ops = macsec_get_ops(netdev_priv(dev), &ctx);
36163616
if (!ops) {
36173617
err = -EOPNOTSUPP;
3618-
goto clear_allmulti;
3618+
goto clear_promisc;
36193619
}
36203620

36213621
ctx.secy = &macsec->secy;
36223622
err = macsec_offload(ops->mdo_dev_open, &ctx);
36233623
if (err)
3624-
goto clear_allmulti;
3624+
goto clear_promisc;
36253625
}
36263626

36273627
if (netif_carrier_ok(real_dev))
36283628
netif_carrier_on(dev);
36293629

36303630
return 0;
3631+
clear_promisc:
3632+
if (dev->flags & IFF_PROMISC)
3633+
dev_set_promiscuity(real_dev, -1);
36313634
clear_allmulti:
36323635
if (dev->flags & IFF_ALLMULTI)
36333636
dev_set_allmulti(real_dev, -1);

0 commit comments

Comments
 (0)