summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2026-03-15 13:41:52 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2026-03-25 13:10:41 +0300
commit4172a7901cf43fe1cc63ef7a2ef33735ff7b7d13 (patch)
tree5c57d2568be36aaa500bc6b8ce78c7fc3e065b76 /drivers
parentbb081fd37f8312651140d7429557258afe51693d (diff)
downloadlinux-4172a7901cf43fe1cc63ef7a2ef33735ff7b7d13.tar.xz
bonding: prevent potential infinite loop in bond_header_parse()
[ Upstream commit b7405dcf7385445e10821777143f18c3ce20fa04 ] bond_header_parse() can loop if a stack of two bonding devices is setup, because skb->dev always points to the hierarchy top. Add new "const struct net_device *dev" parameter to (struct header_ops)->parse() method to make sure the recursion is bounded, and that the final leaf parse method is called. Fixes: 950803f72547 ("bonding: fix type confusion in bond_setup_by_slave()") Signed-off-by: Eric Dumazet <edumazet@google.com> Reviewed-by: Jiayuan Chen <jiayuan.chen@shopee.com> Tested-by: Jiayuan Chen <jiayuan.chen@shopee.com> Cc: Jay Vosburgh <jv@jvosburgh.net> Cc: Andrew Lunn <andrew+netdev@lunn.ch> Link: https://patch.msgid.link/20260315104152.1436867-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/firewire/net.c5
-rw-r--r--drivers/net/bonding/bond_main.c8
2 files changed, 8 insertions, 5 deletions
diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
index 6d6446713539..e82945408955 100644
--- a/drivers/firewire/net.c
+++ b/drivers/firewire/net.c
@@ -257,9 +257,10 @@ static void fwnet_header_cache_update(struct hh_cache *hh,
memcpy((u8 *)hh->hh_data + HH_DATA_OFF(FWNET_HLEN), haddr, net->addr_len);
}
-static int fwnet_header_parse(const struct sk_buff *skb, unsigned char *haddr)
+static int fwnet_header_parse(const struct sk_buff *skb, const struct net_device *dev,
+ unsigned char *haddr)
{
- memcpy(haddr, skb->dev->dev_addr, FWNET_ALEN);
+ memcpy(haddr, dev->dev_addr, FWNET_ALEN);
return FWNET_ALEN;
}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index e8e261e0cb4e..106cfe732a15 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1497,9 +1497,11 @@ static int bond_header_create(struct sk_buff *skb, struct net_device *bond_dev,
return ret;
}
-static int bond_header_parse(const struct sk_buff *skb, unsigned char *haddr)
+static int bond_header_parse(const struct sk_buff *skb,
+ const struct net_device *dev,
+ unsigned char *haddr)
{
- struct bonding *bond = netdev_priv(skb->dev);
+ struct bonding *bond = netdev_priv(dev);
const struct header_ops *slave_ops;
struct slave *slave;
int ret = 0;
@@ -1509,7 +1511,7 @@ static int bond_header_parse(const struct sk_buff *skb, unsigned char *haddr)
if (slave) {
slave_ops = READ_ONCE(slave->dev->header_ops);
if (slave_ops && slave_ops->parse)
- ret = slave_ops->parse(skb, haddr);
+ ret = slave_ops->parse(skb, slave->dev, haddr);
}
rcu_read_unlock();
return ret;