mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2026-09-22 09:34:56 +02:00
bpf: reject short IPv4/IPv6 inputs in bpf_prog_test_run_skb
[ Upstream commit12bec2bd4b] 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:fa5cb548ce("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>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
61a9b216ca
commit
0a04db240e
+12
-8
@@ -1031,19 +1031,23 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr,
|
||||
|
||||
switch (skb->protocol) {
|
||||
case htons(ETH_P_IP):
|
||||
sk->sk_family = AF_INET;
|
||||
if (sizeof(struct iphdr) <= skb_headlen(skb)) {
|
||||
sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
|
||||
sk->sk_daddr = ip_hdr(skb)->daddr;
|
||||
if (skb_headlen(skb) < sizeof(struct iphdr)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
sk->sk_family = AF_INET;
|
||||
sk->sk_rcv_saddr = ip_hdr(skb)->saddr;
|
||||
sk->sk_daddr = ip_hdr(skb)->daddr;
|
||||
break;
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
case htons(ETH_P_IPV6):
|
||||
sk->sk_family = AF_INET6;
|
||||
if (sizeof(struct ipv6hdr) <= skb_headlen(skb)) {
|
||||
sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
|
||||
sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
|
||||
if (skb_headlen(skb) < sizeof(struct ipv6hdr)) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
sk->sk_family = AF_INET6;
|
||||
sk->sk_v6_rcv_saddr = ipv6_hdr(skb)->saddr;
|
||||
sk->sk_v6_daddr = ipv6_hdr(skb)->daddr;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user