Skip to content

Commit 1f882c4

Browse files
ahjf-07gregkh
authored andcommitted
bpf: reject short IPv4/IPv6 inputs in bpf_prog_test_run_skb
[ Upstream commit 12bec2b ] bpf_prog_test_run_skb() calls eth_type_trans() first and then uses skb->protocol to initialize sk family and address fields for the test run. For IPv4 and IPv6 packets, it may access ip_hdr(skb) or ipv6_hdr(skb) even when the provided test input only contains an Ethernet header. Reject the input earlier if the Ethernet frame carries IPv4/IPv6 EtherType but the L3 header is too short. Fold the IPv4/IPv6 header length checks into the existing protocol switch and return -EINVAL before accessing the network headers. Fixes: fa5cb54 ("bpf: Setup socket family and addresses in bpf_prog_test_run_skb") Reported-by: syzbot+619b9ef527f510a57cfc@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=619b9ef527f510a57cfc Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com> Link: https://lore.kernel.org/r/20260408034623.180320-2-sun.jian.kdev@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent d554209 commit 1f882c4

1 file changed

Lines changed: 12 additions & 8 deletions

File tree

net/bpf/test_run.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1061,19 +1061,23 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
10611061

10621062
switch (skb->protocol) {
10631063
case htons(ETH_P_IP):
1064-
sk->sk_family = AF_INET;
1065-
if (sizeof(struct iphdr) <= skb_headlen(skb)) {
1066-
sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
1067-
sk->sk_daddr = ip_hdr(skb)->daddr;
1064+
if (skb_headlen(skb) < sizeof(struct iphdr)) {
1065+
ret = -EINVAL;
1066+
goto out;
10681067
}
1068+
sk->sk_family = AF_INET;
1069+
sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
1070+
sk->sk_daddr = ip_hdr(skb)->daddr;
10691071
break;
10701072
#if IS_ENABLED(CONFIG_IPV6)
10711073
case htons(ETH_P_IPV6):
1072-
sk->sk_family = AF_INET6;
1073-
if (sizeof(struct ipv6hdr) <= skb_headlen(skb)) {
1074-
sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
1075-
sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
1074+
if (skb_headlen(skb) < sizeof(struct ipv6hdr)) {
1075+
ret = -EINVAL;
1076+
goto out;
10761077
}
1078+
sk->sk_family = AF_INET6;
1079+
sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
1080+
sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
10771081
break;
10781082
#endif
10791083
default:

0 commit comments

Comments
 (0)