Netdev List
 help / color / mirror / Atom feed
* [PATCH v2 net 0/4] vlan: ensure sufficient headroom in vlan_dev_hard_header()
@ 2026-09-24  8:29 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
                   ` (4 more replies)
  0 siblings, 5 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

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:

- Patch 1 fixes a UAF/double-free of skb and leak of nskb in
  llc_conn_ac_resend_i_xxx_x_set_0_or_send_rr(), as well as nskb leaks in
  llc_sap_action_send_xid_r() and llc_sap_action_send_test_r() when
  llc_mac_hdr_init() fails.
- Patch 2 checks the return value of llc_mac_hdr_init() in br_send_bpdu()
  and frees the skb on error.
- Patch 3 removes a shadowed 'int err;' variable in __teql_resolve() so
  negative errors from dev_hard_header() are properly returned as -EINVAL.
- Patch 4 uses 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.

v2:
 - Add patches 1-3 to fix pre-existing error handling in llc, bridge, and
   sch_teql when dev_hard_header() fails (Sashiko).
 - Use READ_ONCE() when reading dev->hard_header_len and
   dev->needed_headroom in vlan_dev_hard_header(), and explain why
   LL_RESERVED_SPACE(dev) is not used here (Hangbin Liu, Sashiko).
 - Link to v1: https://lore.kernel.org/netdev/20260922113924.3165190-1-edumazet@google.com/

Eric Dumazet (4):
  llc: fix skb UAF and leaks on llc_mac_hdr_init() failure
  bridge: check llc_mac_hdr_init() return value in br_send_bpdu()
  net/sched: sch_teql: fix shadowed err in __teql_resolve()
  vlan: ensure sufficient headroom in vlan_dev_hard_header()

 net/8021q/vlan_dev.c     | 5 +++++
 net/bridge/br_stp_bpdu.c | 5 ++++-
 net/llc/llc_c_ac.c       | 2 +-
 net/llc/llc_s_ac.c       | 4 ++++
 net/sched/sch_teql.c     | 7 ++-----
 5 files changed, 16 insertions(+), 7 deletions(-)

-- 
2.56.0.rc1.310.g51773c2048-goog


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

* [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

* [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 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

* 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

end of thread, other threads:[~2026-09-24 18:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 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
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

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