Re: [PATCH] selftests/bpf: Reject malformed IPv4/IPv6 skb test input

From: bot+bpf-ci

Date: Sun Mar 29 2026 - 09:25:43 EST


> diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c
> index 4cd6b3ea1815..92888af89743 100644
> --- a/net/bpf/test_run.c
> +++ b/net/bpf/test_run.c
> @@ -1135,6 +1135,25 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
> skb->protocol = eth_type_trans(skb, dev);
> skb_reset_network_header(skb);
>
> + switch (skb->protocol) {
> + case htons(ETH_P_IP):
> + if (skb_headlen(skb) < ETH_HLEN + sizeof(struct iphdr)) {

Should this threshold be sizeof(struct iphdr) rather than
ETH_HLEN + sizeof(struct iphdr)?

eth_type_trans() calls eth_skb_pull_mac() which does
skb_pull_inline(skb, ETH_HLEN), advancing skb->data past the
Ethernet header and reducing skb->len by ETH_HLEN. After that
pull, skb_headlen() no longer includes the Ethernet header bytes.

The existing code just below this new block uses the post-pull
value directly:

if (sizeof(struct iphdr) <= skb_headlen(skb)) {
sk->sk_rcv_saddr = ip_hdr(skb)->saddr;

With the current check, a 34-byte input (ETH_HLEN + sizeof(iphdr))
gives skb_headlen() == 20 after the pull, which fails the
20 < 14 + 20 comparison and is rejected even though it contains a
complete Ethernet and IPv4 header. The same issue applies to the
IPv6 case below.

> + ret = -EINVAL;
> + goto out;
> + }
> + break;
> +#if IS_ENABLED(CONFIG_IPV6)
> + case htons(ETH_P_IPV6):
> + if (skb_headlen(skb) < ETH_HLEN + sizeof(struct ipv6hdr)) {
> + ret = -EINVAL;
> + goto out;
> + }
> + break;
> +#endif

[ ... ]

This patch fixes a bug that has existed since bpf_prog_test_run_skb()
was first introduced. Should it carry a Fixes: tag?

Fixes: 1cf1cae963c2 ("bpf: introduce BPF_PROG_TEST_RUN command")


---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md

CI run summary: https://github.com/kernel-patches/bpf/actions/runs/23709695537