Netdev List
 help / color / mirror / Atom feed
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
To: Jamal Hadi Salim <jhs@mojatatu.com>,
	 Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Cc: netdev@vger.kernel.org,  Jiri Pirko <jiri@resnulli.us>,
	 Victor Nogueira <victor@mojatatu.com>,
	 "David S . Miller" <davem@davemloft.net>,
	 Eric Dumazet <edumazet@kernel.org>,
	 Jakub Kicinski <kuba@kernel.org>,
	 Paolo Abeni <pabeni@redhat.com>,
	 Simon Horman <horms@kernel.org>,
	 Martin Varghese <martin.varghese@nokia.com>,
	 Pravin B Shelar <pshelar@ovn.org>,  Vega <vega@nebusec.ai>,
	 John Hurley <john.hurley@netronome.com>,
	 Willem de Bruijn <willemb@google.com>,
	 stable@vger.kernel.org
Subject: Re: [PATCH net v2 2/6] net/sched: act_mpls: pull the inner Ethernet header after POP
Date: Fri, 23 Oct 2026 18:50:38 -0400	[thread overview]
Message-ID: <willemdebruijn.kernel.30ca6285209f7@gmail.com> (raw)
In-Reply-To: <CAM0EoMmwNCHVNW0=Z_JWX_ZcT5Y1po1GRVScddOsevEvL8D-6w@mail.gmail.com>

Jamal Hadi Salim wrote:
> On Fri, Oct 23, 2026 at 12:09 PM Willem de Bruijn
> <willemdebruijn.kernel@gmail.com> wrote:
> >
> > Jamal Hadi Salim wrote:
> > > The issue:
> > > act_mpls POP can leave the inner Ethernet header in a page fragment after
> > > skb_mpls_pop(), either on an L3 device (mac_len == 0) or chained after
> > > act_vlan POP_ETH.  A following eth_type_trans() can then BUG in
> > > __skb_pull().
> > >
> > > The Fix:
> > > After the pop, if the original MAC header is shorter than ETH_HLEN, pull
> > > the inner Ethernet header into the linear area and drop only when
> > > pskb_may_pull(skb, ETH_HLEN) fails.  skb_mpls_pop() does nothing when the
> > > skb was not MPLS, so no separate state is needed.
> > >
> > > Conditions to recreate the bug:
> > > - egress tc filter on lo: action vlan pop_eth action mpls pop
> > >   (chained), or on an L3 device where mac_len == 0.
> > > - AF_PACKET SOCK_RAW with PACKET_VNET_HDR, hdr_len=28, and a non-linear
> > >   eth / mpls / inner-eth frame.
> > > - The inner header is in page frags; a following eth_type_trans() can BUG
> > >   in __skb_pull().
> > >
> > > Fixes: 2a2ea50870ba ("net: sched: add mpls manipulation actions to TC")
> > > Reported-by: Vega <vega@nebusec.ai>
> > > Link: https://lore.kernel.org/r/40fe2d7dfce13411bfbe9271c0f7c54fb7e88e3b.1782548651.git.bronzed_45_vested@icloud.com/
> > > Link: https://lore.kernel.org/netdev/CAL4WiiqSMdYQYeeW0Fk_GK6ekR4xiS4zPrGKrbB9wZknpqf1-w@mail.gmail.com/
> > > Cc: stable@vger.kernel.org
> > > Suggested-by: Jakub Kicinski <kuba@kernel.org>
> > > Suggested-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
> > > Suggested-by: Eric Dumazet <edumazet@kernel.org>
> > > Reviewed-by: Victor Nogueira <victor@mojatatu.com>
> > > Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
> > > ---
> > >  net/sched/act_mpls.c | 2 ++
> > >  1 file changed, 2 insertions(+)
> > >
> > > diff --git a/net/sched/act_mpls.c b/net/sched/act_mpls.c
> > > index 4ea8b2e08c3a..5363bca892fb 100644
> > > --- a/net/sched/act_mpls.c
> > > +++ b/net/sched/act_mpls.c
> > > @@ -79,6 +79,8 @@ TC_INDIRECT_SCOPE int tcf_mpls_act(struct sk_buff *skb,
> > >               if (skb_mpls_pop(skb, p->tcfm_proto, mac_len,
> > >                                skb->dev && skb->dev->type == ARPHRD_ETHER))
> > >                       goto drop;
> > > +             if (mac_len < ETH_HLEN && !pskb_may_pull(skb, ETH_HLEN))
> > > +                     goto drop;
> >
> > Is this first condition needed?
> >
> 
> That was me conjecturing from Eric saying in v1 "...the check can only
> matter when the original MAC header is short.."
> Since i have to send a v3 (Thanks Eric;->) I will remove it
> 
> > More importantly, can it hide a bug?
> >
> 
> What kind of bug?

Two kinds. One, if original mac_len is larger, gets popped and the
resultant packet is still too short for ETH_HLEN afterwards.

But this can probably not happen, as skb_mpls_pop only pops one MPLS
tag.

What this patch tries to ensure is that the subsequent Ethernet
header is linear.

The second potential bug is this assumption that after the MPLS tag
lies an Ethernet header. Is that a valid assumption? Or could we drop
a valid packet with smaller header.

My LLM raised similar points and says it better than I could:

  1. Missing protocol check: tcf_mpls_act handles popping MPLS to arbitrary inner protocols (ETH_P_IP, ETH_P_IPV6, ETH_P_MPLS_UC, ETH_P_TEB).
  Requiring ETH_HLEN (14 bytes) unconditionally when mac_len < ETH_HLEN drops valid non-Ethernet packets shorter than 14 bytes (e.g. popping
  an outer label to reveal a 4-byte inner label stack entry on an L3 path or after pop_eth). Pulling ETH_HLEN only applies when popping to
  Ethernet / TEB (p->tcfm_proto == htons(ETH_P_TEB)), exactly as done in patch 5 for Open vSwitch (pop_mpls).
  2. Gating on mac_len < ETH_HLEN: mac_len here is the pre-pop outer MAC length. pskb_may_pull is already a no-op if the linear buffer is
  sufficient; gating on pre-pop mac_len is unnecessary and risks skipping the pull when mac_len >= ETH_HLEN even if the revealed header is in
  fragments.
  3. Downstream metadata invariant: Popping to ETH_P_TEB exposes an inner Ethernet header at skb->data, but skb_mpls_pop leaves skb->mac_len
  at 0 and resets the network header to 0 (skb_network_offset(skb) == 0). Downstream actions such as act_mirred (with patch 3's
  skb_network_offset(skb) < dev->min_header_len check) will treat the packet as headerless and drop it, causing regressions in L2VPN
  forwarding (tc_mpls_l2vpn.sh). When popping to TEB, the L2 MAC header boundaries (mac_len and network header offset) need to be properly
  established.
  ──────
  ### Summary of comments:

  • Patch 2/6: Missing inner protocol check (p->tcfm_proto == htons(ETH_P_TEB)) before pulling ETH_HLEN; drops non-Ethernet payloads < 14
  bytes.
  • Patch 2/6: Unsound pre-pop mac_len < ETH_HLEN gate.
  • Patch 2/6: Incomplete header bookkeeping (mac_len and network header offset) on TEB pop breaks subsequent redirect actions (act_mirred).*



  parent reply	other threads:[~2026-10-23 22:50 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-23 11:59 [PATCH net v2 0/6] net: pull short linear Ethernet headers before eth_type_trans() Jamal Hadi Salim
2026-10-23 11:59 ` [PATCH net v2 1/6] net/sched: act_vlan: pull the inner Ethernet header after POP_ETH Jamal Hadi Salim
2026-10-23 11:59   ` [PATCH net v2 2/6] net/sched: act_mpls: pull the inner Ethernet header after POP Jamal Hadi Salim
2026-10-23 11:59     ` [PATCH net v2 3/6] net/sched: act_mirred: reject redirects without a link-layer header Jamal Hadi Salim
2026-10-23 11:59       ` [PATCH net v2 4/6] net/sched: act_ife: do not consume the inner header on egress Jamal Hadi Salim
2026-10-23 11:59         ` [PATCH net v2 5/6] net: openvswitch: ensure a linear inner Ethernet header on TEB pop Jamal Hadi Salim
2026-10-23 11:59           ` [PATCH net v2 6/6] net: openvswitch: ensure a linear inner Ethernet header on NSH pop Jamal Hadi Salim
2026-10-23 18:17             ` Aaron Conole
2026-10-23 18:17           ` [PATCH net v2 5/6] net: openvswitch: ensure a linear inner Ethernet header on TEB pop Aaron Conole
2026-10-23 13:05         ` [PATCH net v2 4/6] net/sched: act_ife: do not consume the inner header on egress Eric Dumazet
2026-10-23 13:17       ` [PATCH net v2 3/6] net/sched: act_mirred: reject redirects without a link-layer header Eric Dumazet
2026-10-23 13:30         ` Jamal Hadi Salim
2026-10-23 13:01     ` [PATCH net v2 2/6] net/sched: act_mpls: pull the inner Ethernet header after POP Eric Dumazet
2026-10-23 16:09     ` Willem de Bruijn
2026-10-23 18:09       ` Jamal Hadi Salim
2026-10-23 19:22         ` Jamal Hadi Salim
2026-10-23 22:50         ` Willem de Bruijn [this message]
2026-10-23 23:46           ` Jamal Hadi Salim
2026-10-24  9:54             ` Jamal Hadi Salim
2026-10-24 16:14               ` Willem de Bruijn
2026-10-25  8:55                 ` Jamal Hadi Salim
2026-10-25 19:36                   ` Jamal Hadi Salim
2026-10-25 19:39                     ` Jamal Hadi Salim
2026-10-25 20:50                       ` Jamal Hadi Salim
2026-10-26  9:41                         ` Jamal Hadi Salim
2026-10-23 13:00   ` [PATCH net v2 1/6] net/sched: act_vlan: pull the inner Ethernet header after POP_ETH Eric Dumazet
2026-10-23 19:28 ` [PATCH net v2 0/6] net: pull short linear Ethernet headers before eth_type_trans() Jakub Kicinski
2026-10-23 20:49   ` Jamal Hadi Salim
2026-10-23 21:30     ` Jamal Hadi Salim

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=willemdebruijn.kernel.30ca6285209f7@gmail.com \
    --to=willemdebruijn.kernel@gmail.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=jhs@mojatatu.com \
    --cc=jiri@resnulli.us \
    --cc=john.hurley@netronome.com \
    --cc=kuba@kernel.org \
    --cc=martin.varghese@nokia.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=pshelar@ovn.org \
    --cc=stable@vger.kernel.org \
    --cc=vega@nebusec.ai \
    --cc=victor@mojatatu.com \
    --cc=willemb@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox