Skip to content

Commit 6def5fe

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 69f9a63 commit 6def5fe

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

11211121
switch (skb->protocol) {
11221122
case htons(ETH_P_IP):
1123-
sk->sk_family = AF_INET;
1124-
if (sizeof(struct iphdr) <= skb_headlen(skb)) {
1125-
sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
1126-
sk->sk_daddr = ip_hdr(skb)->daddr;
1123+
if (skb_headlen(skb) < sizeof(struct iphdr)) {
1124+
ret = -EINVAL;
1125+
goto out;
11271126
}
1127+
sk->sk_family = AF_INET;
1128+
sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
1129+
sk->sk_daddr = ip_hdr(skb)->daddr;
11281130
break;
11291131
#if IS_ENABLED(CONFIG_IPV6)
11301132
case htons(ETH_P_IPV6):
1131-
sk->sk_family = AF_INET6;
1132-
if (sizeof(struct ipv6hdr) <= skb_headlen(skb)) {
1133-
sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
1134-
sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
1133+
if (skb_headlen(skb) < sizeof(struct ipv6hdr)) {
1134+
ret = -EINVAL;
1135+
goto out;
11351136
}
1137+
sk->sk_family = AF_INET6;
1138+
sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
1139+
sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
11361140
break;
11371141
#endif
11381142
default:

0 commit comments

Comments
 (0)