mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net v4] net/openvswitch: check Ethernet header length in  key_extract()
@ 2026-07-25  4:31 Cen Zhang (Microsoft)
  2026-07-27  9:21 ` Eelco Chaudron
  2026-07-27 18:01 ` Ilya Maximets
  0 siblings, 2 replies; 4+ messages in thread
From: Cen Zhang (Microsoft) @ 2026-07-25  4:31 UTC (permalink / raw)
  To: aconole, echaudro, i.maximets, davem, edumazet, kuba, pabeni, horms
  Cc: netdev, dev, linux-kernel, AutonomousCodeSecurity, tgopinath,
	kys, blbllhy

When a packet arrives on an ARPHRD_NONE device (e.g. TUN),
ovs_flow_key_extract() trusts the user-provided skb->protocol field: if
it is ETH_P_TEB, the packet is classified as MAC_PROTO_ETHERNET and
key_extract() is called without ensuring the skb has ETH_HLEN (14) bytes
of linear data. key_extract() unconditionally pulls 2 * ETH_ALEN bytes
for MAC addresses and parse_ethertype() pulls 2 more, either of which
triggers a kernel BUG in __skb_pull() when the linear area is too small.

  kernel BUG at include/linux/skbuff.h:2848!
  RIP: 0010:key_extract+0xa7e/0xd90 net/openvswitch/flow.c:933
  ovs_flow_key_extract+0x419/0xa70
  ovs_vport_receive+0x222/0x390
  netdev_frame_hook+0x3e0/0x630
  tun_get_user+0x2d0c/0x38e0

Fixed by calling check_header() in key_extract() before accessing the
Ethernet header.

Fixes: 217ac77a3c25 ("openvswitch: allow L3 netdev ports")
Reported-by: AutonomousCodeSecurity@microsoft.com
Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com>
---
v4: Update documentation and move variables into the Ethernet block.
v3: Use check_header() per review, fix format issue.
v2: Moved the check into key_extract() per Ilya Maximets.
Link: https://lore.kernel.org/all/20260721143602.64677-1-blbllhy@gmail.com

 net/openvswitch/flow.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 66366982f604..8ad0be37a65a 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -889,8 +889,6 @@ static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
  * Ethernet header
  * @key: output flow key
  *
- * The caller must ensure that skb->len >= ETH_HLEN.
- *
  * Initializes @skb header fields as follows:
  *
  *    - skb->mac_header: the L2 header.
@@ -910,8 +908,6 @@ static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
  */
 static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
 {
-	struct ethhdr *eth;
-
 	/* Flags are always used as part of stats */
 	key->tp.flags = 0;
 
@@ -926,6 +922,12 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
 		skb_reset_network_header(skb);
 		key->eth.type = skb->protocol;
 	} else {
+		struct ethhdr *eth;
+		int err = check_header(skb, ETH_HLEN);
+
+		if (unlikely(err))
+			return err;
+
 		eth = eth_hdr(skb);
 		ether_addr_copy(key->eth.src, eth->h_source);
 		ether_addr_copy(key->eth.dst, eth->h_dest);
-- 
2.53.0


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

* Re: [PATCH net v4] net/openvswitch: check Ethernet header length in key_extract()
  2026-07-25  4:31 [PATCH net v4] net/openvswitch: check Ethernet header length in key_extract() Cen Zhang (Microsoft)
@ 2026-07-27  9:21 ` Eelco Chaudron
  2026-07-27 18:01 ` Ilya Maximets
  1 sibling, 0 replies; 4+ messages in thread
From: Eelco Chaudron @ 2026-07-27  9:21 UTC (permalink / raw)
  To: Cen Zhang (Microsoft)
  Cc: aconole, i.maximets, davem, edumazet, kuba, pabeni, horms,
	netdev, dev, linux-kernel, AutonomousCodeSecurity, tgopinath,
	kys



On 25 Jul 2026, at 6:31, Cen Zhang (Microsoft) wrote:

> When a packet arrives on an ARPHRD_NONE device (e.g. TUN),
> ovs_flow_key_extract() trusts the user-provided skb->protocol field: if
> it is ETH_P_TEB, the packet is classified as MAC_PROTO_ETHERNET and
> key_extract() is called without ensuring the skb has ETH_HLEN (14) bytes
> of linear data. key_extract() unconditionally pulls 2 * ETH_ALEN bytes
> for MAC addresses and parse_ethertype() pulls 2 more, either of which
> triggers a kernel BUG in __skb_pull() when the linear area is too small.
>
>   kernel BUG at include/linux/skbuff.h:2848!
>   RIP: 0010:key_extract+0xa7e/0xd90 net/openvswitch/flow.c:933
>   ovs_flow_key_extract+0x419/0xa70
>   ovs_vport_receive+0x222/0x390
>   netdev_frame_hook+0x3e0/0x630
>   tun_get_user+0x2d0c/0x38e0
>
> Fixed by calling check_header() in key_extract() before accessing the
> Ethernet header.
>
> Fixes: 217ac77a3c25 ("openvswitch: allow L3 netdev ports")
> Reported-by: AutonomousCodeSecurity@microsoft.com
> Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com>
> ---
> v4: Update documentation and move variables into the Ethernet block.
> v3: Use check_header() per review, fix format issue.
> v2: Moved the check into key_extract() per Ilya Maximets.
> Link: https://lore.kernel.org/all/20260721143602.64677-1-blbllhy@gmail.com

Thanks for sending out a v4 with my comments fixed. The change looks good to me.

Reviewed-by:  Eelco Chaudron <echaudro@redhat.com>


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

* Re: [PATCH net v4] net/openvswitch: check Ethernet header length in key_extract()
  2026-07-25  4:31 [PATCH net v4] net/openvswitch: check Ethernet header length in key_extract() Cen Zhang (Microsoft)
  2026-07-27  9:21 ` Eelco Chaudron
@ 2026-07-27 18:01 ` Ilya Maximets
  2026-07-30 21:53   ` Cen Zhang (Microsoft)
  1 sibling, 1 reply; 4+ messages in thread
From: Ilya Maximets @ 2026-07-27 18:01 UTC (permalink / raw)
  To: Cen Zhang (Microsoft),
	aconole, echaudro, i.maximets, davem, edumazet, kuba, pabeni,
	horms
  Cc: netdev, dev, linux-kernel, AutonomousCodeSecurity, tgopinath, kys

On 7/25/26 6:31 AM, Cen Zhang (Microsoft) wrote:
> When a packet arrives on an ARPHRD_NONE device (e.g. TUN),
> ovs_flow_key_extract() trusts the user-provided skb->protocol field: if
> it is ETH_P_TEB, the packet is classified as MAC_PROTO_ETHERNET and
> key_extract() is called without ensuring the skb has ETH_HLEN (14) bytes
> of linear data. key_extract() unconditionally pulls 2 * ETH_ALEN bytes
> for MAC addresses and parse_ethertype() pulls 2 more, either of which
> triggers a kernel BUG in __skb_pull() when the linear area is too small.
> 
>   kernel BUG at include/linux/skbuff.h:2848!
>   RIP: 0010:key_extract+0xa7e/0xd90 net/openvswitch/flow.c:933
>   ovs_flow_key_extract+0x419/0xa70
>   ovs_vport_receive+0x222/0x390
>   netdev_frame_hook+0x3e0/0x630
>   tun_get_user+0x2d0c/0x38e0
> 
> Fixed by calling check_header() in key_extract() before accessing the
> Ethernet header.
> 
> Fixes: 217ac77a3c25 ("openvswitch: allow L3 netdev ports")
> Reported-by: AutonomousCodeSecurity@microsoft.com
> Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com>
> ---
> v4: Update documentation and move variables into the Ethernet block.
> v3: Use check_header() per review, fix format issue.
> v2: Moved the check into key_extract() per Ilya Maximets.
> Link: https://lore.kernel.org/all/20260721143602.64677-1-blbllhy@gmail.com
> 
>  net/openvswitch/flow.c | 10 ++++++----
>  1 file changed, 6 insertions(+), 4 deletions(-)
> 
> diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
> index 66366982f604..8ad0be37a65a 100644
> --- a/net/openvswitch/flow.c
> +++ b/net/openvswitch/flow.c
> @@ -889,8 +889,6 @@ static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
>   * Ethernet header
>   * @key: output flow key
>   *
> - * The caller must ensure that skb->len >= ETH_HLEN.
> - *
>   * Initializes @skb header fields as follows:
>   *
>   *    - skb->mac_header: the L2 header.
> @@ -910,8 +908,6 @@ static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
>   */
>  static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
>  {
> -	struct ethhdr *eth;
> -
>  	/* Flags are always used as part of stats */
>  	key->tp.flags = 0;
>  
> @@ -926,6 +922,12 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
>  		skb_reset_network_header(skb);
>  		key->eth.type = skb->protocol;
>  	} else {
> +		struct ethhdr *eth;
> +		int err = check_header(skb, ETH_HLEN);

Please, use the reverse x-mass tree ordering for variable declaration,
i.e. lines longest to shortest.  In this particular case, just move
the initialization to a separate line:

		struct ethhdr *eth;
		int err;

		err = check_header(skb, ETH_HLEN);
		if (unlikely(err)) ...

Otherwise, LGTM.



Sashiko reports two pre-existing issues that are not related to this patch:

1. Potential use of uninitialized bits of the key during lookup if the
   code takes the positive branch of the if statement, since the addresses
   remain uninitialized in the flow key structure.

   There should be no functional issues, as those bits will be bitwise
   ANDed with zeroes form the mask before the lookup in most cases, and
   in case of L3 key comparison with the L2 flow where the addresses
   will not be zero, the key must not match anyway due to prior mismatch
   on the eth protocol.  However, it is possible that KASAN will not be
   happy with these operations producing warnings.  I'll try to take a
   closer look at this one.  The zeroing out of the key was previously
   removed for performance reasons, since it doesn't affect flow matching.
   But having KASAN splats is also not great and potentially dangerous.

2. There is an unlikely case where ovs_flow_key_update() might fail,
   which would cause skb leak on failure of recirc() or ct() actions.
   I'm not really sure if this condition is reachable in practice as it
   requires parsing to fail on a packet that we previously successfully
   parsed and then modified.  But should be fixed nevertheless.
   I'll send a separate small patch set for this.

Best regards, Ilya Maximets.

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

* Re: [PATCH net v4] net/openvswitch: check Ethernet header length in key_extract()
  2026-07-27 18:01 ` Ilya Maximets
@ 2026-07-30 21:53   ` Cen Zhang (Microsoft)
  0 siblings, 0 replies; 4+ messages in thread
From: Cen Zhang (Microsoft) @ 2026-07-30 21:53 UTC (permalink / raw)
  To: i.maximets
  Cc: AutonomousCodeSecurity, aconole, blbllhy, davem, dev, echaudro,
	edumazet, horms, kuba, kys, linux-kernel, netdev, pabeni,
	tgopinath

Thanks for the reviews, Eelco and Ilya. Sorry for the delayed response;
I was tied up with other work over the past few days.

I'll send v5 shortly.

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

end of thread, other threads:[~2026-07-30 21:53 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-25  4:31 [PATCH net v4] net/openvswitch: check Ethernet header length in key_extract() Cen Zhang (Microsoft)
2026-07-27  9:21 ` Eelco Chaudron
2026-07-27 18:01 ` Ilya Maximets
2026-07-30 21:53   ` Cen Zhang (Microsoft)

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

all inboxes | Powered by JetHome®