Skip to content

Commit 8042240

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 afdc851 commit 8042240

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
@@ -1057,19 +1057,23 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
10571057

10581058
switch (skb->protocol) {
10591059
case htons(ETH_P_IP):
1060-
sk->sk_family = AF_INET;
1061-
if (sizeof(struct iphdr) <= skb_headlen(skb)) {
1062-
sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
1063-
sk->sk_daddr = ip_hdr(skb)->daddr;
1060+
if (skb_headlen(skb) < sizeof(struct iphdr)) {
1061+
ret = -EINVAL;
1062+
goto out;
10641063
}
1064+
sk->sk_family = AF_INET;
1065+
sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
1066+
sk->sk_daddr = ip_hdr(skb)->daddr;
10651067
break;
10661068
#if IS_ENABLED(CONFIG_IPV6)
10671069
case htons(ETH_P_IPV6):
1068-
sk->sk_family = AF_INET6;
1069-
if (sizeof(struct ipv6hdr) <= skb_headlen(skb)) {
1070-
sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
1071-
sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
1070+
if (skb_headlen(skb) < sizeof(struct ipv6hdr)) {
1071+
ret = -EINVAL;
1072+
goto out;
10721073
}
1074+
sk->sk_family = AF_INET6;
1075+
sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
1076+
sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
10731077
break;
10741078
#endif
10751079
default:

0 commit comments

Comments
 (0)