From: Leon Hwang <leon.hwang@linux.dev>
To: sashiko-reviews@lists.linux.dev
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf 1/2] bpf: Update transport_header when encapsulating UDP tunnel in lwt
Date: Wed, 27 May 2026 21:40:00 +0800 [thread overview]
Message-ID: <f28e47a3-11fd-4fc1-b248-4c1c8d0902e0@linux.dev> (raw)
In-Reply-To: <20260525150010.CDEBA1F000E9@smtp.kernel.org>
On 2026/5/25 23:00, sashiko-bot@kernel.org wrote:
[...]
>> diff --git a/net/core/lwt_bpf.c b/net/core/lwt_bpf.c
>> index f71ef82a5f3d3..cbb2803367c6d 100644
>> --- a/net/core/lwt_bpf.c
>> +++ b/net/core/lwt_bpf.c
>> @@ -637,6 +637,10 @@ int bpf_lwt_push_ip_encap(struct sk_buff *skb, void *hdr, u32 len, bool ingress)
>> if (ingress)
>> skb_postpush_rcsum(skb, iph, len);
>> skb_reset_network_header(skb);
>> + if (ipv4 && iph->protocol == IPPROTO_UDP /* UDP tunnel */)
>> + skb_set_transport_header(skb, skb_network_offset(skb) + iph->ihl * 4);
>
> [Severity: High]
> Can a concurrent modification to the BPF-provided header cause an
> out-of-bounds transport header offset?
>
> The hdr pointer passed to bpf_lwt_push_ip_encap() can point to concurrently
> mutable memory such as a BPF map value. Reading iph->protocol and iph->ihl
> directly from hdr here, after length validation has already occurred,
> appears to introduce a Time-of-Check to Time-of-Use race condition.
>
> If a concurrent modification changes iph->ihl, the calculated transport
> header could point well past the end of the pushed IP header. For small
> SKBs, this could cause skb_transport_header to point out-of-bounds into
> skb_shared_info.
>
> Would it be safer to perform these reads after copying the header into the
> SKB, using the copied, stable values instead?
>
Agreed.
Will move skb_set_transport_header() after memcpy().
> [Severity: Critical]
> This is a pre-existing issue and was not introduced by the patch under
> review, but is there a missing validation for the minimum IPv4 header
> length before ip_fast_csum() is called?
>
> Earlier in the function, the length validation checks:
>
> if (unlikely(len < iph->ihl * 4))
> return -EINVAL;
>
> If a BPF program provides an IP header with ihl = 0, the check len < 0
> evaluates to false because len is at least 20.
>
> Later, ip_fast_csum() is called with ihl = 0. On architectures like MIPS,
> the ip_fast_csum() implementation reads 16 bytes and then uses a loop:
>
> do { ... word++ } while (word != stop);
>
> where stop = iph + ihl. If ihl = 0, stop is physically behind word,
> causing the loop to endlessly increment through the address space until
> it page faults.
>
> Does this code need a check to ensure iph->ihl >= 5?
>
I'm not sure about this case.
But, can update "len < iph->ihl * 4" to
"iph->ihl < 5 || len < iph->ihl * 4".
> [Severity: Medium]
> Does this code verify that the packet length actually contains the full UDP
> header?
>
> This updates the transport header for UDP tunnels based solely on the IP
> protocol, but it doesn't seem to validate that len actually encompasses
> the full struct udphdr.
>
> If an IP header is pushed with IPPROTO_UDP but a truncated length (like
> len = 20), the transport header is set to the end of the IP header. A NIC
> driver might then attempt to parse the subsequent memory as a UDP header,
> which could lead to broken offloads or out-of-bounds reads.
>
Agreed.
Will check len must include UDP header.
Thanks,
Leon
>> + else if (!ipv4 && ((struct ipv6hdr *)hdr)->nexthdr == NEXTHDR_UDP /* UDP tunnel */)
>> + skb_set_transport_header(skb, skb_network_offset(skb) + sizeof(struct ipv6hdr));
>> memcpy(skb_network_header(skb), hdr, len);
>> bpf_compute_data_pointers(skb);
>> skb_clear_hash(skb);
>
next prev parent reply other threads:[~2026-05-27 13:40 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-25 14:26 [PATCH bpf 0/2] bpf: Update transport_header when encapsulating UDP tunnel in lwt Leon Hwang
2026-05-25 14:26 ` [PATCH bpf 1/2] " Leon Hwang
2026-05-25 15:00 ` sashiko-bot
2026-05-27 13:40 ` Leon Hwang [this message]
2026-05-25 14:26 ` [PATCH bpf 2/2] selftests/bpf: Add tests to verify the fix of encapsulating VxLAN " Leon Hwang
2026-05-25 15:17 ` sashiko-bot
2026-05-27 13:40 ` Leon Hwang
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=f28e47a3-11fd-4fc1-b248-4c1c8d0902e0@linux.dev \
--to=leon.hwang@linux.dev \
--cc=bpf@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.