Subject: Re: [syzbot] [net?] WARNING in mpls_gso_segment

From: Florian Westphal <[email-masked]>
Date: Thu, 22 Feb 2024 13:23:24 +0100

Eric Dumazet <[email-masked]> wrote:
> I guess we should try this, or perhaps understand why
> skb->encapsulation might not be set,
> or why skb_inner_network_header(skb) is not set at this point.

syz repro injects data via packet socket, skb passed down stack
has ->protocol set to NSH (0x894f), gso type is SKB_GSO_UDP | SKB_GSO_DODGY.

This gets passed down to skb_mac_gso_segment(), which sees NSH as ptype
callback.

nsh_gso_segment() retrieves next type:

        proto = tun_p_to_eth_p(nsh_hdr(skb)->np);

... which is mpls (TUN_P_MPLS_UC), it then updates
skb->protocol.  This calls back into skb_mac_gso_segment() which
sees MPLS as ptype callback, we then end up in mpls_gso_segment()
without any inner headers set (skb->encapsulation is not set,
inner header offsets are 0) and mpls_gso_segment() attempts to pull
negative header size off the skb.

I don't see anything that could be done earlier in the stack about this.

As far as I understand NSH assumes its only called from openvswitch
and MPLS GSO code only via Openvswitch or mpls_iptunnel, but its
reachable by other means.

But skb_mac_gso_segment() doesn't have any info on the originator
to know if it can call into nsh or mpls 'as intended'.

So I'd guess best solution is to explicitly check for negative
header size, plus a comment that explains how this could happen.