* [PATCH v2 net 1/4] llc: fix skb UAF and leaks on llc_mac_hdr_init() failure
2026-09-24 8:29 [PATCH v2 net 0/4] vlan: ensure sufficient headroom in vlan_dev_hard_header() Eric Dumazet
@ 2026-09-24 8:29 ` Eric Dumazet
2026-09-24 8:29 ` [PATCH v2 net 2/4] bridge: check llc_mac_hdr_init() return value in br_send_bpdu() Eric Dumazet
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Eric Dumazet @ 2026-09-24 8:29 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, edumazet, Eric Dumazet
In llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(), if llc_mac_hdr_init()
fails, kfree_skb(skb) is called instead of kfree_skb(nskb). This leaks
the newly allocated nskb, reads from the freed skb via LLC_I_GET_NR(pdu),
and double-frees skb when llc_conn_state_process() drops its reference.
In llc_sap_action_send_xid_r() and llc_sap_action_send_test_r(), nskb is
leaked if llc_mac_hdr_init() returns an error.
Free nskb in all three error paths.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Closes: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/llc/llc_c_ac.c | 2 +-
net/llc/llc_s_ac.c | 4 ++++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
index 724ecd741d4cf482d1768fd2e35342171ba1ecf2..1aa7fe28acddb2368ff0fce3cac5c2dab75c57a4 100644
--- a/net/llc/llc_c_ac.c
+++ b/net/llc/llc_c_ac.c
@@ -437,7 +437,7 @@ int llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(struct sock *sk,
if (likely(!rc))
llc_conn_send_pdu(sk, nskb);
else
- kfree_skb(skb);
+ kfree_skb(nskb);
}
if (rc) {
nr = LLC_I_GET_NR(pdu);
diff --git a/net/llc/llc_s_ac.c b/net/llc/llc_s_ac.c
index 98deee560373515007fba57463e5a5868650ff42..831998211b52eeaf70532f08d86e8a1eb8b03c1c 100644
--- a/net/llc/llc_s_ac.c
+++ b/net/llc/llc_s_ac.c
@@ -121,6 +121,8 @@ int llc_sap_action_send_xid_r(struct llc_sap *sap, struct sk_buff *skb)
rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
if (likely(!rc))
rc = dev_queue_xmit(nskb);
+ else
+ kfree_skb(nskb);
out:
return rc;
}
@@ -170,6 +172,8 @@ int llc_sap_action_send_test_r(struct llc_sap *sap, struct sk_buff *skb)
rc = llc_mac_hdr_init(nskb, mac_sa, mac_da);
if (likely(!rc))
rc = dev_queue_xmit(nskb);
+ else
+ kfree_skb(nskb);
out:
return rc;
}
--
2.56.0.rc1.310.g51773c2048-goog
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 net 2/4] bridge: check llc_mac_hdr_init() return value in br_send_bpdu()
2026-09-24 8:29 [PATCH v2 net 0/4] vlan: ensure sufficient headroom in vlan_dev_hard_header() Eric Dumazet
2026-09-24 8:29 ` [PATCH v2 net 1/4] llc: fix skb UAF and leaks on llc_mac_hdr_init() failure Eric Dumazet
@ 2026-09-24 8:29 ` Eric Dumazet
2026-09-24 10:25 ` Nikolay Aleksandrov
2026-09-24 8:29 ` [PATCH v2 net 3/4] net/sched: sch_teql: fix shadowed err in __teql_resolve() Eric Dumazet
` (2 subsequent siblings)
4 siblings, 1 reply; 7+ messages in thread
From: Eric Dumazet @ 2026-09-24 8:29 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, edumazet, Eric Dumazet, Nikolay Aleksandrov,
Ido Schimmel, bridge
If llc_mac_hdr_init() fails (for instance if the port device type does
not support LLC or dev_hard_header() fails), br_send_bpdu() should drop
the skb instead of resetting the mac header to the LLC payload and
transmitting a malformed frame.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Closes: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
Cc: Nikolay Aleksandrov <razor@blackwall.org>
Cc: Ido Schimmel <idosch@nvidia.com>
Cc: bridge@lists.linux.dev
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/bridge/br_stp_bpdu.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
index 74ec42ba1e7d086cbfde608c93f5fa24d6b4ed7b..21d092f5acbb81f1d0ccd80200cebdbda722f4bf 100644
--- a/net/bridge/br_stp_bpdu.c
+++ b/net/bridge/br_stp_bpdu.c
@@ -52,7 +52,10 @@ static void br_send_bpdu(struct net_bridge_port *p,
LLC_SAP_BSPAN, LLC_PDU_CMD);
llc_pdu_init_as_ui_cmd(skb);
- llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr);
+ if (llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr)) {
+ kfree_skb(skb);
+ return;
+ }
skb_reset_mac_header(skb);
--
2.56.0.rc1.310.g51773c2048-goog
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v2 net 2/4] bridge: check llc_mac_hdr_init() return value in br_send_bpdu()
2026-09-24 8:29 ` [PATCH v2 net 2/4] bridge: check llc_mac_hdr_init() return value in br_send_bpdu() Eric Dumazet
@ 2026-09-24 10:25 ` Nikolay Aleksandrov
0 siblings, 0 replies; 7+ messages in thread
From: Nikolay Aleksandrov @ 2026-09-24 10:25 UTC (permalink / raw)
To: Eric Dumazet, David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, edumazet, Ido Schimmel, bridge
On 24/09/2026 11:29, Eric Dumazet wrote:
> If llc_mac_hdr_init() fails (for instance if the port device type does
> not support LLC or dev_hard_header() fails), br_send_bpdu() should drop
> the skb instead of resetting the mac header to the LLC payload and
> transmitting a malformed frame.
>
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Closes: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
> Cc: Nikolay Aleksandrov <razor@blackwall.org>
> Cc: Ido Schimmel <idosch@nvidia.com>
> Cc: bridge@lists.linux.dev
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> ---
> net/bridge/br_stp_bpdu.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c
> index 74ec42ba1e7d086cbfde608c93f5fa24d6b4ed7b..21d092f5acbb81f1d0ccd80200cebdbda722f4bf 100644
> --- a/net/bridge/br_stp_bpdu.c
> +++ b/net/bridge/br_stp_bpdu.c
> @@ -52,7 +52,10 @@ static void br_send_bpdu(struct net_bridge_port *p,
> LLC_SAP_BSPAN, LLC_PDU_CMD);
> llc_pdu_init_as_ui_cmd(skb);
>
> - llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr);
> + if (llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr)) {
> + kfree_skb(skb);
> + return;
> + }
>
> skb_reset_mac_header(skb);
>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v2 net 3/4] net/sched: sch_teql: fix shadowed err in __teql_resolve()
2026-09-24 8:29 [PATCH v2 net 0/4] vlan: ensure sufficient headroom in vlan_dev_hard_header() Eric Dumazet
2026-09-24 8:29 ` [PATCH v2 net 1/4] llc: fix skb UAF and leaks on llc_mac_hdr_init() failure Eric Dumazet
2026-09-24 8:29 ` [PATCH v2 net 2/4] bridge: check llc_mac_hdr_init() return value in br_send_bpdu() Eric Dumazet
@ 2026-09-24 8:29 ` Eric Dumazet
2026-09-24 8:29 ` [PATCH v2 net 4/4] vlan: ensure sufficient headroom in vlan_dev_hard_header() Eric Dumazet
2026-09-24 18:10 ` [PATCH v2 net 0/4] " patchwork-bot+netdevbpf
4 siblings, 0 replies; 7+ messages in thread
From: Eric Dumazet @ 2026-09-24 8:29 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, edumazet, Eric Dumazet, Jamal Hadi Salim,
Jiri Pirko
__teql_resolve() declares an inner 'int err;' inside the
'if (neigh_event_send(n, skb_res) == 0)' block, shadowing the outer
'int err = 0;'. As a result, a negative return from dev_hard_header()
is written to the inner variable and __teql_resolve() still returns 0.
Remove the shadowed variable and set the outer err to -EINVAL when
dev_hard_header() returns a negative error.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Closes: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/sched/sch_teql.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index 9e52afc2d9808cba5a404dd9c1a6255fc7e5485d..409ce50cc0dbc7936582d5459c4c31c680177b3f 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -265,14 +265,11 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res,
}
if (neigh_event_send(n, skb_res) == 0) {
- int err;
char haddr[MAX_ADDR_LEN];
neigh_ha_snapshot(haddr, n, dev);
- err = dev_hard_header(skb, dev, ntohs(skb_protocol(skb, false)),
- haddr, NULL, skb->len);
-
- if (err < 0)
+ if (dev_hard_header(skb, dev, ntohs(skb_protocol(skb, false)),
+ haddr, NULL, skb->len) < 0)
err = -EINVAL;
} else {
err = (skb_res == NULL) ? -EAGAIN : 1;
--
2.56.0.rc1.310.g51773c2048-goog
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v2 net 4/4] vlan: ensure sufficient headroom in vlan_dev_hard_header()
2026-09-24 8:29 [PATCH v2 net 0/4] vlan: ensure sufficient headroom in vlan_dev_hard_header() Eric Dumazet
` (2 preceding siblings ...)
2026-09-24 8:29 ` [PATCH v2 net 3/4] net/sched: sch_teql: fix shadowed err in __teql_resolve() Eric Dumazet
@ 2026-09-24 8:29 ` Eric Dumazet
2026-09-24 18:10 ` [PATCH v2 net 0/4] " patchwork-bot+netdevbpf
4 siblings, 0 replies; 7+ messages in thread
From: Eric Dumazet @ 2026-09-24 8:29 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Paolo Abeni
Cc: Simon Horman, netdev, edumazet, Eric Dumazet, Zixuan Chai,
Hangbin Liu
Callers that only reserve ETH_HLEN or less (such as llc_alloc_frame()),
or skbs allocated before dynamic device/headroom changes (e.g. toggling
VLAN_FLAG_REORDER_HDR or bonding/team switching slaves), can reach
vlan_dev_hard_header() with insufficient headroom and trigger
skb_under_panic().
Use skb_cow_head() in vlan_dev_hard_header() when VLAN_FLAG_REORDER_HDR
is not set to ensure sufficient headroom for the VLAN header(s) and the
underlying device hard header.
Use READ_ONCE() to read dev->hard_header_len and dev->needed_headroom as
they can be updated concurrently under RTNL (e.g. in
vlan_transfer_features()) while vlan_dev_hard_header() runs locklessly on
the transmit path. Also avoid LL_RESERVED_SPACE(dev) here so that the
extra HH_DATA_MOD alignment padding does not trigger unnecessary
pskb_expand_head() reallocations on inner stacked VLAN devices after the
outer VLAN header has been pushed.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Zixuan Chai <petalzu987@gmail.com>
Closes: https://lore.kernel.org/netdev/cover.1789987105.git.petalzu987@gmail.com/
Link: https://lore.kernel.org/netdev/179022851638.2160803.1808206741379444999@kernel.org/
Cc: Hangbin Liu <liuhangbin@gmail.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/8021q/vlan_dev.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 2859cbac3f266b7c4e3f44f41280d33ab69c5270..c949c6a829456c2f75d6c514b35a85ff64c493d8 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -55,6 +55,11 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev,
int rc;
if (!(vlan->flags & VLAN_FLAG_REORDER_HDR)) {
+ unsigned int hlen = READ_ONCE(dev->hard_header_len) +
+ READ_ONCE(dev->needed_headroom);
+
+ if (skb_cow_head(skb, hlen) < 0)
+ return -ENOMEM;
vhdr = skb_push(skb, VLAN_HLEN);
vlan_tci = vlan->vlan_id;
--
2.56.0.rc1.310.g51773c2048-goog
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v2 net 0/4] vlan: ensure sufficient headroom in vlan_dev_hard_header()
2026-09-24 8:29 [PATCH v2 net 0/4] vlan: ensure sufficient headroom in vlan_dev_hard_header() Eric Dumazet
` (3 preceding siblings ...)
2026-09-24 8:29 ` [PATCH v2 net 4/4] vlan: ensure sufficient headroom in vlan_dev_hard_header() Eric Dumazet
@ 2026-09-24 18:10 ` patchwork-bot+netdevbpf
4 siblings, 0 replies; 7+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-09-24 18:10 UTC (permalink / raw)
To: Eric Dumazet; +Cc: davem, kuba, pabeni, horms, netdev, edumazet
Hello:
This series was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:
On Thu, 24 Sep 2026 08:29:47 +0000 you wrote:
> Callers that only reserve ETH_HLEN or less, or skbs allocated before
> dynamic device/headroom changes (such as toggling VLAN_FLAG_REORDER_HDR
> or bonding/team switching slaves), can reach vlan_dev_hard_header() with
> insufficient headroom and trigger skb_under_panic().
>
> When vlan_dev_hard_header() returns -ENOMEM upon skb_cow_head() failure,
> a few callers of dev_hard_header() / llc_mac_hdr_init() had pre-existing
> error-handling bugs:
>
> [...]
Here is the summary with links:
- [v2,net,1/4] llc: fix skb UAF and leaks on llc_mac_hdr_init() failure
https://git.kernel.org/netdev/net/c/72f9dd522f8d
- [v2,net,2/4] bridge: check llc_mac_hdr_init() return value in br_send_bpdu()
https://git.kernel.org/netdev/net/c/ac704ff08e51
- [v2,net,3/4] net/sched: sch_teql: fix shadowed err in __teql_resolve()
https://git.kernel.org/netdev/net/c/907b978e82cb
- [v2,net,4/4] vlan: ensure sufficient headroom in vlan_dev_hard_header()
https://git.kernel.org/netdev/net/c/cd5dd68267c4
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] 7+ messages in thread