mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
bpf: Don't let lwt_in progs call into IPv6 when it is disabled
With ipv6.disable=1, inet6_init() returns before it registers any pernet subsystem. Thus net->ipv6.devconf_all and net->ipv6.seg6_data stay NULL. IS_ENABLED(CONFIG_IPV6) only says that the code is built in. bpf_lwt_input_reroute() and bpf_push_seg6_encap() call into IPv6, but do not test ipv6_mod_enabled(). An lwt_in prog also runs with ipv6.disable=1, and skb->protocol == htons(ETH_P_IPV6) does not prove that IPv6 is enabled. Thus the kernel dereferences NULL and crashes. Return -EAFNOSUPPORT before these calls if ipv6_mod_enabled() is false. BPF_LWT_REROUTE then drops an IPv6 skb. With IPv6 enabled nothing changes. The first Fixes tag is for bpf_push_seg6_encap(), which never had this test. The second tag is for bpf_lwt_input_reroute(). Until that commit it used ipv6_stub, which returned -EAFNOSUPPORT with ipv6.disable=1. Fixes:fe94cc290f("bpf: Add IPv6 Segment Routing helpers") Fixes:ad84b1eefe("bpf: remove ipv6_bpf_stub completely and use direct function calls") Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20261101190535.1454146-25-alexei.starovoitov@gmail.com
This commit is contained in:
parent
d9618a6196
commit
95f1d5e4ab
|
|
@ -6924,6 +6924,10 @@ static int bpf_push_seg6_encap(struct sk_buff *skb, u32 type, void *hdr, u32 len
|
|||
int err;
|
||||
struct ipv6_sr_hdr *srh = (struct ipv6_sr_hdr *)hdr;
|
||||
|
||||
/* With ipv6.disable=1 the netns has no seg6 data and no IPv6 tables. */
|
||||
if (!ipv6_mod_enabled())
|
||||
return -EAFNOSUPPORT;
|
||||
|
||||
if (!seg6_validate_srh(srh, len, false))
|
||||
return -EINVAL;
|
||||
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ static int bpf_lwt_input_reroute(struct sk_buff *skb)
|
|||
dev_put(dev);
|
||||
} else if (skb->protocol == htons(ETH_P_IPV6)) {
|
||||
skb_dst_drop(skb);
|
||||
if (IS_ENABLED(CONFIG_IPV6)) {
|
||||
if (ipv6_mod_enabled()) {
|
||||
ip6_route_input(skb);
|
||||
err = skb_dst(skb)->error;
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user