From: Sasha Levin Date: Tue, 18 Feb 2025 12:30:05 +0000 (-0500) Subject: Fixes for 6.1 X-Git-Tag: v6.1.129~50^2~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0ed9b1daf84c51092cb5bf5bc9a5b824d9410926;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.1 Signed-off-by: Sasha Levin --- diff --git a/queue-6.1/arp-use-rcu-protection-in-arp_xmit.patch b/queue-6.1/arp-use-rcu-protection-in-arp_xmit.patch new file mode 100644 index 0000000000..ee12570ac7 --- /dev/null +++ b/queue-6.1/arp-use-rcu-protection-in-arp_xmit.patch @@ -0,0 +1,45 @@ +From 21a32096f2f777dae1ef8d481f1001e1b075d79a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 13:58:36 +0000 +Subject: arp: use RCU protection in arp_xmit() + +From: Eric Dumazet + +[ Upstream commit a42b69f692165ec39db42d595f4f65a4c8f42e44 ] + +arp_xmit() can be called without RTNL or RCU protection. + +Use RCU protection to avoid potential UAF. + +Fixes: 29a26a568038 ("netfilter: Pass struct net into the netfilter hooks") +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250207135841.1948589-5-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/arp.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c +index ccff96820a703..8f9b5568f1dc1 100644 +--- a/net/ipv4/arp.c ++++ b/net/ipv4/arp.c +@@ -658,10 +658,12 @@ static int arp_xmit_finish(struct net *net, struct sock *sk, struct sk_buff *skb + */ + void arp_xmit(struct sk_buff *skb) + { ++ rcu_read_lock(); + /* Send it off, maybe filter it using firewalling first. */ + NF_HOOK(NFPROTO_ARP, NF_ARP_OUT, +- dev_net(skb->dev), NULL, skb, NULL, skb->dev, ++ dev_net_rcu(skb->dev), NULL, skb, NULL, skb->dev, + arp_xmit_finish); ++ rcu_read_unlock(); + } + EXPORT_SYMBOL(arp_xmit); + +-- +2.39.5 + diff --git a/queue-6.1/clocksource-use-migrate_disable-to-avoid-calling-get.patch b/queue-6.1/clocksource-use-migrate_disable-to-avoid-calling-get.patch new file mode 100644 index 0000000000..2e82522b33 --- /dev/null +++ b/queue-6.1/clocksource-use-migrate_disable-to-avoid-calling-get.patch @@ -0,0 +1,82 @@ +From 5dea4d0602318540833fabeda2a7b71fbf9a4b36 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 31 Jan 2025 12:33:23 -0500 +Subject: clocksource: Use migrate_disable() to avoid calling get_random_u32() + in atomic context + +From: Waiman Long + +[ Upstream commit 6bb05a33337b2c842373857b63de5c9bf1ae2a09 ] + +The following bug report happened with a PREEMPT_RT kernel: + + BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48 + in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 2012, name: kwatchdog + preempt_count: 1, expected: 0 + RCU nest depth: 0, expected: 0 + get_random_u32+0x4f/0x110 + clocksource_verify_choose_cpus+0xab/0x1a0 + clocksource_verify_percpu.part.0+0x6b/0x330 + clocksource_watchdog_kthread+0x193/0x1a0 + +It is due to the fact that clocksource_verify_choose_cpus() is invoked with +preemption disabled. This function invokes get_random_u32() to obtain +random numbers for choosing CPUs. The batched_entropy_32 local lock and/or +the base_crng.lock spinlock in driver/char/random.c will be acquired during +the call. In PREEMPT_RT kernel, they are both sleeping locks and so cannot +be acquired in atomic context. + +Fix this problem by using migrate_disable() to allow smp_processor_id() to +be reliably used without introducing atomic context. preempt_disable() is +then called after clocksource_verify_choose_cpus() but before the +clocksource measurement is being run to avoid introducing unexpected +latency. + +Fixes: 7560c02bdffb ("clocksource: Check per-CPU clock synchronization when marked unstable") +Suggested-by: Sebastian Andrzej Siewior +Signed-off-by: Waiman Long +Signed-off-by: Thomas Gleixner +Reviewed-by: Paul E. McKenney +Reviewed-by: Sebastian Andrzej Siewior +Link: https://lore.kernel.org/all/20250131173323.891943-2-longman@redhat.com +Signed-off-by: Sasha Levin +--- + kernel/time/clocksource.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c +index 51afd4cc2d004..9e221a97d2274 100644 +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -348,10 +348,10 @@ void clocksource_verify_percpu(struct clocksource *cs) + cpumask_clear(&cpus_ahead); + cpumask_clear(&cpus_behind); + cpus_read_lock(); +- preempt_disable(); ++ migrate_disable(); + clocksource_verify_choose_cpus(); + if (cpumask_empty(&cpus_chosen)) { +- preempt_enable(); ++ migrate_enable(); + cpus_read_unlock(); + pr_warn("Not enough CPUs to check clocksource '%s'.\n", cs->name); + return; +@@ -359,6 +359,7 @@ void clocksource_verify_percpu(struct clocksource *cs) + testcpu = smp_processor_id(); + pr_info("Checking clocksource %s synchronization from CPU %d to CPUs %*pbl.\n", + cs->name, testcpu, cpumask_pr_args(&cpus_chosen)); ++ preempt_disable(); + for_each_cpu(cpu, &cpus_chosen) { + if (cpu == testcpu) + continue; +@@ -378,6 +379,7 @@ void clocksource_verify_percpu(struct clocksource *cs) + cs_nsec_min = cs_nsec; + } + preempt_enable(); ++ migrate_enable(); + cpus_read_unlock(); + if (!cpumask_empty(&cpus_ahead)) + pr_warn(" CPUs %*pbl ahead of CPU %d for clocksource %s.\n", +-- +2.39.5 + diff --git a/queue-6.1/clocksource-use-pr_info-for-checking-clocksource-syn.patch b/queue-6.1/clocksource-use-pr_info-for-checking-clocksource-syn.patch new file mode 100644 index 0000000000..892c41a1dc --- /dev/null +++ b/queue-6.1/clocksource-use-pr_info-for-checking-clocksource-syn.patch @@ -0,0 +1,45 @@ +From bea3e1e5ed72db1aa7a98a7a2b58de68bec7a8f7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Jan 2025 20:54:41 -0500 +Subject: clocksource: Use pr_info() for "Checking clocksource synchronization" + message + +From: Waiman Long + +[ Upstream commit 1f566840a82982141f94086061927a90e79440e5 ] + +The "Checking clocksource synchronization" message is normally printed +when clocksource_verify_percpu() is called for a given clocksource if +both the CLOCK_SOURCE_UNSTABLE and CLOCK_SOURCE_VERIFY_PERCPU flags +are set. + +It is an informational message and so pr_info() is the correct choice. + +Signed-off-by: Waiman Long +Signed-off-by: Thomas Gleixner +Reviewed-by: Paul E. McKenney +Acked-by: John Stultz +Link: https://lore.kernel.org/all/20250125015442.3740588-1-longman@redhat.com +Stable-dep-of: 6bb05a33337b ("clocksource: Use migrate_disable() to avoid calling get_random_u32() in atomic context") +Signed-off-by: Sasha Levin +--- + kernel/time/clocksource.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c +index a3650699463bb..51afd4cc2d004 100644 +--- a/kernel/time/clocksource.c ++++ b/kernel/time/clocksource.c +@@ -357,7 +357,8 @@ void clocksource_verify_percpu(struct clocksource *cs) + return; + } + testcpu = smp_processor_id(); +- pr_warn("Checking clocksource %s synchronization from CPU %d to CPUs %*pbl.\n", cs->name, testcpu, cpumask_pr_args(&cpus_chosen)); ++ pr_info("Checking clocksource %s synchronization from CPU %d to CPUs %*pbl.\n", ++ cs->name, testcpu, cpumask_pr_args(&cpus_chosen)); + for_each_cpu(cpu, &cpus_chosen) { + if (cpu == testcpu) + continue; +-- +2.39.5 + diff --git a/queue-6.1/flow_dissector-use-rcu-protection-to-fetch-dev_net.patch b/queue-6.1/flow_dissector-use-rcu-protection-to-fetch-dev_net.patch new file mode 100644 index 0000000000..1416572ab2 --- /dev/null +++ b/queue-6.1/flow_dissector-use-rcu-protection-to-fetch-dev_net.patch @@ -0,0 +1,81 @@ +From 08212d273809959b3134d720ae57ed4e84fcb66d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 15:51:17 +0000 +Subject: flow_dissector: use RCU protection to fetch dev_net() + +From: Eric Dumazet + +[ Upstream commit afec62cd0a4191cde6dd3a75382be4d51a38ce9b ] + +__skb_flow_dissect() can be called from arbitrary contexts. + +It must extend its RCU protection section to include +the call to dev_net(), which can become dev_net_rcu(). + +This makes sure the net structure can not disappear under us. + +Fixes: 9b52e3f267a6 ("flow_dissector: handle no-skb use case") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250205155120.1676781-10-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/flow_dissector.c | 21 +++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c +index fba8eb1bb2815..de17f13232381 100644 +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -1004,10 +1004,12 @@ bool __skb_flow_dissect(const struct net *net, + FLOW_DISSECTOR_KEY_BASIC, + target_container); + ++ rcu_read_lock(); ++ + if (skb) { + if (!net) { + if (skb->dev) +- net = dev_net(skb->dev); ++ net = dev_net_rcu(skb->dev); + else if (skb->sk) + net = sock_net(skb->sk); + } +@@ -1018,7 +1020,6 @@ bool __skb_flow_dissect(const struct net *net, + enum netns_bpf_attach_type type = NETNS_BPF_FLOW_DISSECTOR; + struct bpf_prog_array *run_array; + +- rcu_read_lock(); + run_array = rcu_dereference(init_net.bpf.run_array[type]); + if (!run_array) + run_array = rcu_dereference(net->bpf.run_array[type]); +@@ -1046,17 +1047,17 @@ bool __skb_flow_dissect(const struct net *net, + prog = READ_ONCE(run_array->items[0].prog); + result = bpf_flow_dissect(prog, &ctx, n_proto, nhoff, + hlen, flags); +- if (result == BPF_FLOW_DISSECTOR_CONTINUE) +- goto dissect_continue; +- __skb_flow_bpf_to_target(&flow_keys, flow_dissector, +- target_container); +- rcu_read_unlock(); +- return result == BPF_OK; ++ if (result != BPF_FLOW_DISSECTOR_CONTINUE) { ++ __skb_flow_bpf_to_target(&flow_keys, flow_dissector, ++ target_container); ++ rcu_read_unlock(); ++ return result == BPF_OK; ++ } + } +-dissect_continue: +- rcu_read_unlock(); + } + ++ rcu_read_unlock(); ++ + if (dissector_uses_key(flow_dissector, + FLOW_DISSECTOR_KEY_ETH_ADDRS)) { + struct ethhdr *eth = eth_hdr(skb); +-- +2.39.5 + diff --git a/queue-6.1/ipv4-add-rcu-protection-to-ip4_dst_hoplimit.patch b/queue-6.1/ipv4-add-rcu-protection-to-ip4_dst_hoplimit.patch new file mode 100644 index 0000000000..09048728d5 --- /dev/null +++ b/queue-6.1/ipv4-add-rcu-protection-to-ip4_dst_hoplimit.patch @@ -0,0 +1,47 @@ +From efab47b045842984df0fa4f1febb36ae1715a8d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 15:51:10 +0000 +Subject: ipv4: add RCU protection to ip4_dst_hoplimit() + +From: Eric Dumazet + +[ Upstream commit 469308552ca4560176cfc100e7ca84add1bebd7c ] + +ip4_dst_hoplimit() must use RCU protection to make +sure the net structure it reads does not disappear. + +Fixes: fa50d974d104 ("ipv4: Namespaceify ip_default_ttl sysctl knob") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250205155120.1676781-3-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + include/net/route.h | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/include/net/route.h b/include/net/route.h +index af8431b25f800..f396176022377 100644 +--- a/include/net/route.h ++++ b/include/net/route.h +@@ -362,10 +362,15 @@ static inline int inet_iif(const struct sk_buff *skb) + static inline int ip4_dst_hoplimit(const struct dst_entry *dst) + { + int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT); +- struct net *net = dev_net(dst->dev); + +- if (hoplimit == 0) ++ if (hoplimit == 0) { ++ const struct net *net; ++ ++ rcu_read_lock(); ++ net = dev_net_rcu(dst->dev); + hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl); ++ rcu_read_unlock(); ++ } + return hoplimit; + } + +-- +2.39.5 + diff --git a/queue-6.1/ipv4-icmp-convert-to-dev_net_rcu.patch b/queue-6.1/ipv4-icmp-convert-to-dev_net_rcu.patch new file mode 100644 index 0000000000..65ce5cfd45 --- /dev/null +++ b/queue-6.1/ipv4-icmp-convert-to-dev_net_rcu.patch @@ -0,0 +1,150 @@ +From 1467da24a9cfa031f950f499423d5d5520515d76 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 15:51:16 +0000 +Subject: ipv4: icmp: convert to dev_net_rcu() + +From: Eric Dumazet + +[ Upstream commit 4b8474a0951e605d2a27a2c483da4eb4b8c63760 ] + +__icmp_send() must ensure rcu_read_lock() is held, as spotted +by Jakub. + +Other ICMP uses of dev_net() seem safe, change them to dev_net_rcu() +to get LOCKDEP support. + +Fixes: dde1bc0e6f86 ("[NETNS]: Add namespace for ICMP replying code.") +Closes: https://lore.kernel.org/netdev/20250203153633.46ce0337@kernel.org/ +Reported-by: Jakub Kicinski +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20250205155120.1676781-9-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/icmp.c | 31 +++++++++++++++++-------------- + 1 file changed, 17 insertions(+), 14 deletions(-) + +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +index a6adf6a2ec4b5..a21d32b3ae6c3 100644 +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -403,10 +403,10 @@ static void icmp_push_reply(struct sock *sk, + + static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) + { +- struct ipcm_cookie ipc; + struct rtable *rt = skb_rtable(skb); +- struct net *net = dev_net(rt->dst.dev); ++ struct net *net = dev_net_rcu(rt->dst.dev); + bool apply_ratelimit = false; ++ struct ipcm_cookie ipc; + struct flowi4 fl4; + struct sock *sk; + struct inet_sock *inet; +@@ -609,12 +609,14 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, + struct sock *sk; + + if (!rt) +- goto out; ++ return; ++ ++ rcu_read_lock(); + + if (rt->dst.dev) +- net = dev_net(rt->dst.dev); ++ net = dev_net_rcu(rt->dst.dev); + else if (skb_in->dev) +- net = dev_net(skb_in->dev); ++ net = dev_net_rcu(skb_in->dev); + else + goto out; + +@@ -783,7 +785,8 @@ void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, + icmp_xmit_unlock(sk); + out_bh_enable: + local_bh_enable(); +-out:; ++out: ++ rcu_read_unlock(); + } + EXPORT_SYMBOL(__icmp_send); + +@@ -832,7 +835,7 @@ static void icmp_socket_deliver(struct sk_buff *skb, u32 info) + * avoid additional coding at protocol handlers. + */ + if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) { +- __ICMP_INC_STATS(dev_net(skb->dev), ICMP_MIB_INERRORS); ++ __ICMP_INC_STATS(dev_net_rcu(skb->dev), ICMP_MIB_INERRORS); + return; + } + +@@ -866,7 +869,7 @@ static enum skb_drop_reason icmp_unreach(struct sk_buff *skb) + struct net *net; + u32 info = 0; + +- net = dev_net(skb_dst(skb)->dev); ++ net = dev_net_rcu(skb_dst(skb)->dev); + + /* + * Incomplete header ? +@@ -977,7 +980,7 @@ static enum skb_drop_reason icmp_unreach(struct sk_buff *skb) + static enum skb_drop_reason icmp_redirect(struct sk_buff *skb) + { + if (skb->len < sizeof(struct iphdr)) { +- __ICMP_INC_STATS(dev_net(skb->dev), ICMP_MIB_INERRORS); ++ __ICMP_INC_STATS(dev_net_rcu(skb->dev), ICMP_MIB_INERRORS); + return SKB_DROP_REASON_PKT_TOO_SMALL; + } + +@@ -1009,7 +1012,7 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb) + struct icmp_bxm icmp_param; + struct net *net; + +- net = dev_net(skb_dst(skb)->dev); ++ net = dev_net_rcu(skb_dst(skb)->dev); + /* should there be an ICMP stat for ignored echos? */ + if (READ_ONCE(net->ipv4.sysctl_icmp_echo_ignore_all)) + return SKB_NOT_DROPPED_YET; +@@ -1038,9 +1041,9 @@ static enum skb_drop_reason icmp_echo(struct sk_buff *skb) + + bool icmp_build_probe(struct sk_buff *skb, struct icmphdr *icmphdr) + { ++ struct net *net = dev_net_rcu(skb->dev); + struct icmp_ext_hdr *ext_hdr, _ext_hdr; + struct icmp_ext_echo_iio *iio, _iio; +- struct net *net = dev_net(skb->dev); + struct inet6_dev *in6_dev; + struct in_device *in_dev; + struct net_device *dev; +@@ -1179,7 +1182,7 @@ static enum skb_drop_reason icmp_timestamp(struct sk_buff *skb) + return SKB_NOT_DROPPED_YET; + + out_err: +- __ICMP_INC_STATS(dev_net(skb_dst(skb)->dev), ICMP_MIB_INERRORS); ++ __ICMP_INC_STATS(dev_net_rcu(skb_dst(skb)->dev), ICMP_MIB_INERRORS); + return SKB_DROP_REASON_PKT_TOO_SMALL; + } + +@@ -1196,7 +1199,7 @@ int icmp_rcv(struct sk_buff *skb) + { + enum skb_drop_reason reason = SKB_DROP_REASON_NOT_SPECIFIED; + struct rtable *rt = skb_rtable(skb); +- struct net *net = dev_net(rt->dst.dev); ++ struct net *net = dev_net_rcu(rt->dst.dev); + struct icmphdr *icmph; + + if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) { +@@ -1369,9 +1372,9 @@ int icmp_err(struct sk_buff *skb, u32 info) + struct iphdr *iph = (struct iphdr *)skb->data; + int offset = iph->ihl<<2; + struct icmphdr *icmph = (struct icmphdr *)(skb->data + offset); ++ struct net *net = dev_net_rcu(skb->dev); + int type = icmp_hdr(skb)->type; + int code = icmp_hdr(skb)->code; +- struct net *net = dev_net(skb->dev); + + /* + * Use ping_err to handle all icmp errors except those +-- +2.39.5 + diff --git a/queue-6.1/ipv4-use-rcu-protection-in-__ip_rt_update_pmtu.patch b/queue-6.1/ipv4-use-rcu-protection-in-__ip_rt_update_pmtu.patch new file mode 100644 index 0000000000..8d64ef4a1a --- /dev/null +++ b/queue-6.1/ipv4-use-rcu-protection-in-__ip_rt_update_pmtu.patch @@ -0,0 +1,77 @@ +From bda9cb4b28b0d1089385ff4113674307ca7b21df Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 15:51:15 +0000 +Subject: ipv4: use RCU protection in __ip_rt_update_pmtu() + +From: Eric Dumazet + +[ Upstream commit 139512191bd06f1b496117c76372b2ce372c9a41 ] + +__ip_rt_update_pmtu() must use RCU protection to make +sure the net structure it reads does not disappear. + +Fixes: 2fbc6e89b2f1 ("ipv4: Update exception handling for multipath routes via same device") +Fixes: 1de6b15a434c ("Namespaceify min_pmtu sysctl") +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20250205155120.1676781-8-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/route.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 0bda6916ebcfb..4574dcba9f193 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1020,9 +1020,9 @@ out: kfree_skb_reason(skb, reason); + static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) + { + struct dst_entry *dst = &rt->dst; +- struct net *net = dev_net(dst->dev); + struct fib_result res; + bool lock = false; ++ struct net *net; + u32 old_mtu; + + if (ip_mtu_locked(dst)) +@@ -1032,6 +1032,8 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) + if (old_mtu < mtu) + return; + ++ rcu_read_lock(); ++ net = dev_net_rcu(dst->dev); + if (mtu < net->ipv4.ip_rt_min_pmtu) { + lock = true; + mtu = min(old_mtu, net->ipv4.ip_rt_min_pmtu); +@@ -1039,9 +1041,8 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) + + if (rt->rt_pmtu == mtu && !lock && + time_before(jiffies, dst->expires - net->ipv4.ip_rt_mtu_expires / 2)) +- return; ++ goto out; + +- rcu_read_lock(); + if (fib_lookup(net, fl4, &res, 0) == 0) { + struct fib_nh_common *nhc; + +@@ -1055,14 +1056,14 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) + update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock, + jiffies + net->ipv4.ip_rt_mtu_expires); + } +- rcu_read_unlock(); +- return; ++ goto out; + } + #endif /* CONFIG_IP_ROUTE_MULTIPATH */ + nhc = FIB_RES_NHC(res); + update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock, + jiffies + net->ipv4.ip_rt_mtu_expires); + } ++out: + rcu_read_unlock(); + } + +-- +2.39.5 + diff --git a/queue-6.1/ipv4-use-rcu-protection-in-inet_select_addr.patch b/queue-6.1/ipv4-use-rcu-protection-in-inet_select_addr.patch new file mode 100644 index 0000000000..ce0a435cd9 --- /dev/null +++ b/queue-6.1/ipv4-use-rcu-protection-in-inet_select_addr.patch @@ -0,0 +1,41 @@ +From d954885a7286107106974242899115e06889e4ac Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 15:51:14 +0000 +Subject: ipv4: use RCU protection in inet_select_addr() + +From: Eric Dumazet + +[ Upstream commit 719817cd293e4fa389e1f69c396f3f816ed5aa41 ] + +inet_select_addr() must use RCU protection to make +sure the net structure it reads does not disappear. + +Fixes: c4544c724322 ("[NETNS]: Process inet_select_addr inside a namespace.") +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20250205155120.1676781-7-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/devinet.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c +index 430ca93ba939d..1738cc2bfc7f0 100644 +--- a/net/ipv4/devinet.c ++++ b/net/ipv4/devinet.c +@@ -1320,10 +1320,11 @@ __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope) + __be32 addr = 0; + unsigned char localnet_scope = RT_SCOPE_HOST; + struct in_device *in_dev; +- struct net *net = dev_net(dev); ++ struct net *net; + int master_idx; + + rcu_read_lock(); ++ net = dev_net_rcu(dev); + in_dev = __in_dev_get_rcu(dev); + if (!in_dev) + goto no_in_dev; +-- +2.39.5 + diff --git a/queue-6.1/ipv4-use-rcu-protection-in-ipv4_default_advmss.patch b/queue-6.1/ipv4-use-rcu-protection-in-ipv4_default_advmss.patch new file mode 100644 index 0000000000..59c34d26b2 --- /dev/null +++ b/queue-6.1/ipv4-use-rcu-protection-in-ipv4_default_advmss.patch @@ -0,0 +1,48 @@ +From 27d33b9f04ff941a73a8e3dd7f66b649aa041f80 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 15:51:12 +0000 +Subject: ipv4: use RCU protection in ipv4_default_advmss() + +From: Eric Dumazet + +[ Upstream commit 71b8471c93fa0bcab911fcb65da1eb6c4f5f735f ] + +ipv4_default_advmss() must use RCU protection to make +sure the net structure it reads does not disappear. + +Fixes: 2e9589ff809e ("ipv4: Namespaceify min_adv_mss sysctl knob") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250205155120.1676781-5-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/route.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index f877a96fd1eb5..5f18520d054c0 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1306,10 +1306,15 @@ static void set_class_tag(struct rtable *rt, u32 tag) + + static unsigned int ipv4_default_advmss(const struct dst_entry *dst) + { +- struct net *net = dev_net(dst->dev); + unsigned int header_size = sizeof(struct tcphdr) + sizeof(struct iphdr); +- unsigned int advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size, +- net->ipv4.ip_rt_min_advmss); ++ unsigned int advmss; ++ struct net *net; ++ ++ rcu_read_lock(); ++ net = dev_net_rcu(dst->dev); ++ advmss = max_t(unsigned int, ipv4_mtu(dst) - header_size, ++ net->ipv4.ip_rt_min_advmss); ++ rcu_read_unlock(); + + return min(advmss, IPV4_MAX_PMTU - header_size); + } +-- +2.39.5 + diff --git a/queue-6.1/ipv4-use-rcu-protection-in-rt_is_expired.patch b/queue-6.1/ipv4-use-rcu-protection-in-rt_is_expired.patch new file mode 100644 index 0000000000..c740033b6a --- /dev/null +++ b/queue-6.1/ipv4-use-rcu-protection-in-rt_is_expired.patch @@ -0,0 +1,44 @@ +From b9d91058f8ce83026e8e2a8282890797ad6e2ed6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 15:51:13 +0000 +Subject: ipv4: use RCU protection in rt_is_expired() + +From: Eric Dumazet + +[ Upstream commit dd205fcc33d92d54eee4d7f21bb073af9bd5ce2b ] + +rt_is_expired() must use RCU protection to make +sure the net structure it reads does not disappear. + +Fixes: e84f84f27647 ("netns: place rt_genid into struct net") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250205155120.1676781-6-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/route.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index 5f18520d054c0..ae56d94f68d9f 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -393,7 +393,13 @@ static inline int ip_rt_proc_init(void) + + static inline bool rt_is_expired(const struct rtable *rth) + { +- return rth->rt_genid != rt_genid_ipv4(dev_net(rth->dst.dev)); ++ bool res; ++ ++ rcu_read_lock(); ++ res = rth->rt_genid != rt_genid_ipv4(dev_net_rcu(rth->dst.dev)); ++ rcu_read_unlock(); ++ ++ return res; + } + + void rt_cache_flush(struct net *net) +-- +2.39.5 + diff --git a/queue-6.1/ipv6-mcast-add-rcu-protection-to-mld_newpack.patch b/queue-6.1/ipv6-mcast-add-rcu-protection-to-mld_newpack.patch new file mode 100644 index 0000000000..6306983cb3 --- /dev/null +++ b/queue-6.1/ipv6-mcast-add-rcu-protection-to-mld_newpack.patch @@ -0,0 +1,80 @@ +From d068448361a4775dc0449560d4ebbd7a866a2ffc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 12 Feb 2025 14:10:21 +0000 +Subject: ipv6: mcast: add RCU protection to mld_newpack() + +From: Eric Dumazet + +[ Upstream commit a527750d877fd334de87eef81f1cb5f0f0ca3373 ] + +mld_newpack() can be called without RTNL or RCU being held. + +Note that we no longer can use sock_alloc_send_skb() because +ipv6.igmp_sk uses GFP_KERNEL allocations which can sleep. + +Instead use alloc_skb() and charge the net->ipv6.igmp_sk +socket under RCU protection. + +Fixes: b8ad0cbc58f7 ("[NETNS][IPV6] mcast - handle several network namespace") +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Link: https://patch.msgid.link/20250212141021.1663666-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/mcast.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c +index a777695389403..a1b3f3e7921fa 100644 +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -1731,21 +1731,19 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) + struct net_device *dev = idev->dev; + int hlen = LL_RESERVED_SPACE(dev); + int tlen = dev->needed_tailroom; +- struct net *net = dev_net(dev); + const struct in6_addr *saddr; + struct in6_addr addr_buf; + struct mld2_report *pmr; + struct sk_buff *skb; + unsigned int size; + struct sock *sk; +- int err; ++ struct net *net; + +- sk = net->ipv6.igmp_sk; + /* we assume size > sizeof(ra) here + * Also try to not allocate high-order pages for big MTU + */ + size = min_t(int, mtu, PAGE_SIZE / 2) + hlen + tlen; +- skb = sock_alloc_send_skb(sk, size, 1, &err); ++ skb = alloc_skb(size, GFP_KERNEL); + if (!skb) + return NULL; + +@@ -1753,6 +1751,12 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) + skb_reserve(skb, hlen); + skb_tailroom_reserve(skb, mtu, tlen); + ++ rcu_read_lock(); ++ ++ net = dev_net_rcu(dev); ++ sk = net->ipv6.igmp_sk; ++ skb_set_owner_w(skb, sk); ++ + if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { + /* : + * use unspecified address as the source address +@@ -1764,6 +1768,8 @@ static struct sk_buff *mld_newpack(struct inet6_dev *idev, unsigned int mtu) + + ip6_mc_hdr(sk, skb, dev, saddr, &mld2_all_mcr, NEXTHDR_HOP, 0); + ++ rcu_read_unlock(); ++ + skb_put_data(skb, ra, sizeof(ra)); + + skb_set_transport_header(skb, skb_tail_pointer(skb) - skb->data); +-- +2.39.5 + diff --git a/queue-6.1/ipv6-use-rcu-protection-in-ip6_default_advmss.patch b/queue-6.1/ipv6-use-rcu-protection-in-ip6_default_advmss.patch new file mode 100644 index 0000000000..e16255eed8 --- /dev/null +++ b/queue-6.1/ipv6-use-rcu-protection-in-ip6_default_advmss.patch @@ -0,0 +1,49 @@ +From a2ed0b04691e00b46d8628a8b04f06532a37b0ad Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 15:51:18 +0000 +Subject: ipv6: use RCU protection in ip6_default_advmss() + +From: Eric Dumazet + +[ Upstream commit 3c8ffcd248da34fc41e52a46e51505900115fc2a ] + +ip6_default_advmss() needs rcu protection to make +sure the net structure it reads does not disappear. + +Fixes: 5578689a4e3c ("[NETNS][IPV6] route6 - make route6 per namespace") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250205155120.1676781-11-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/route.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index f3268bac9f198..17918f411386a 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -3190,13 +3190,18 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst) + { + struct net_device *dev = dst->dev; + unsigned int mtu = dst_mtu(dst); +- struct net *net = dev_net(dev); ++ struct net *net; + + mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr); + ++ rcu_read_lock(); ++ ++ net = dev_net_rcu(dev); + if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss) + mtu = net->ipv6.sysctl.ip6_rt_min_advmss; + ++ rcu_read_unlock(); ++ + /* + * Maximal non-jumbo IPv6 payload is IPV6_MAXPLEN and + * corresponding MSS is IPV6_MAXPLEN - tcp_header_size. +-- +2.39.5 + diff --git a/queue-6.1/ndisc-extend-rcu-protection-in-ndisc_send_skb.patch b/queue-6.1/ndisc-extend-rcu-protection-in-ndisc_send_skb.patch new file mode 100644 index 0000000000..9b32f849f1 --- /dev/null +++ b/queue-6.1/ndisc-extend-rcu-protection-in-ndisc_send_skb.patch @@ -0,0 +1,72 @@ +From 514ee4ee7c70390ff7483df13e3b0754621106ed Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 13:58:39 +0000 +Subject: ndisc: extend RCU protection in ndisc_send_skb() + +From: Eric Dumazet + +[ Upstream commit ed6ae1f325d3c43966ec1b62ac1459e2b8e45640 ] + +ndisc_send_skb() can be called without RTNL or RCU held. + +Acquire rcu_read_lock() earlier, so that we can use dev_net_rcu() +and avoid a potential UAF. + +Fixes: 1762f7e88eb3 ("[NETNS][IPV6] ndisc - make socket control per namespace") +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250207135841.1948589-8-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ndisc.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c +index 2e8e0847631e3..1a6408a24d21c 100644 +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -471,16 +471,20 @@ static void ip6_nd_hdr(struct sk_buff *skb, + void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr, + const struct in6_addr *saddr) + { ++ struct icmp6hdr *icmp6h = icmp6_hdr(skb); + struct dst_entry *dst = skb_dst(skb); +- struct net *net = dev_net(skb->dev); +- struct sock *sk = net->ipv6.ndisc_sk; + struct inet6_dev *idev; ++ struct net *net; ++ struct sock *sk; + int err; +- struct icmp6hdr *icmp6h = icmp6_hdr(skb); + u8 type; + + type = icmp6h->icmp6_type; + ++ rcu_read_lock(); ++ ++ net = dev_net_rcu(skb->dev); ++ sk = net->ipv6.ndisc_sk; + if (!dst) { + struct flowi6 fl6; + int oif = skb->dev->ifindex; +@@ -488,6 +492,7 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr, + icmpv6_flow_init(sk, &fl6, type, saddr, daddr, oif); + dst = icmp6_dst_alloc(skb->dev, &fl6); + if (IS_ERR(dst)) { ++ rcu_read_unlock(); + kfree_skb(skb); + return; + } +@@ -502,7 +507,6 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr, + + ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, skb->len); + +- rcu_read_lock(); + idev = __in6_dev_get(dst->dev); + IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); + +-- +2.39.5 + diff --git a/queue-6.1/ndisc-use-rcu-protection-in-ndisc_alloc_skb.patch b/queue-6.1/ndisc-use-rcu-protection-in-ndisc_alloc_skb.patch new file mode 100644 index 0000000000..48a8c99c0c --- /dev/null +++ b/queue-6.1/ndisc-use-rcu-protection-in-ndisc_alloc_skb.patch @@ -0,0 +1,59 @@ +From f794eb073c5d56e643785429fc129c0feebf0392 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 13:58:34 +0000 +Subject: ndisc: use RCU protection in ndisc_alloc_skb() + +From: Eric Dumazet + +[ Upstream commit 628e6d18930bbd21f2d4562228afe27694f66da9 ] + +ndisc_alloc_skb() can be called without RTNL or RCU being held. + +Add RCU protection to avoid possible UAF. + +Fixes: de09334b9326 ("ndisc: Introduce ndisc_alloc_skb() helper.") +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250207135841.1948589-3-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv6/ndisc.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c +index 6df3f4aadf641..2e8e0847631e3 100644 +--- a/net/ipv6/ndisc.c ++++ b/net/ipv6/ndisc.c +@@ -418,15 +418,11 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, + { + int hlen = LL_RESERVED_SPACE(dev); + int tlen = dev->needed_tailroom; +- struct sock *sk = dev_net(dev)->ipv6.ndisc_sk; + struct sk_buff *skb; + + skb = alloc_skb(hlen + sizeof(struct ipv6hdr) + len + tlen, GFP_ATOMIC); +- if (!skb) { +- ND_PRINTK(0, err, "ndisc: %s failed to allocate an skb\n", +- __func__); ++ if (!skb) + return NULL; +- } + + skb->protocol = htons(ETH_P_IPV6); + skb->dev = dev; +@@ -437,7 +433,9 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, + /* Manually assign socket ownership as we avoid calling + * sock_alloc_send_pskb() to bypass wmem buffer limits + */ +- skb_set_owner_w(skb, sk); ++ rcu_read_lock(); ++ skb_set_owner_w(skb, dev_net_rcu(dev)->ipv6.ndisc_sk); ++ rcu_read_unlock(); + + return skb; + } +-- +2.39.5 + diff --git a/queue-6.1/neighbour-delete-redundant-judgment-statements.patch b/queue-6.1/neighbour-delete-redundant-judgment-statements.patch new file mode 100644 index 0000000000..762f846583 --- /dev/null +++ b/queue-6.1/neighbour-delete-redundant-judgment-statements.patch @@ -0,0 +1,40 @@ +From 0b557d70cf51a93d8a2e244a6a9f42fb8326ec46 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 22 Aug 2024 12:32:45 +0800 +Subject: neighbour: delete redundant judgment statements + +From: Li Zetao + +[ Upstream commit c25bdd2ac8cf7da70a226f1a66cdce7af15ff86f ] + +The initial value of err is -ENOBUFS, and err is guaranteed to be +less than 0 before all goto errout. Therefore, on the error path +of errout, there is no need to repeatedly judge that err is less than 0, +and delete redundant judgments to make the code more concise. + +Signed-off-by: Li Zetao +Reviewed-by: Petr Machata +Signed-off-by: David S. Miller +Stable-dep-of: becbd5850c03 ("neighbour: use RCU protection in __neigh_notify()") +Signed-off-by: Sasha Levin +--- + net/core/neighbour.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index dd0965e1afe85..b127533e74f37 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -3516,8 +3516,7 @@ static void __neigh_notify(struct neighbour *n, int type, int flags, + rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); + return; + errout: +- if (err < 0) +- rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); ++ rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); + } + + void neigh_app_ns(struct neighbour *n) +-- +2.39.5 + diff --git a/queue-6.1/neighbour-use-rcu-protection-in-__neigh_notify.patch b/queue-6.1/neighbour-use-rcu-protection-in-__neigh_notify.patch new file mode 100644 index 0000000000..543551e206 --- /dev/null +++ b/queue-6.1/neighbour-use-rcu-protection-in-__neigh_notify.patch @@ -0,0 +1,58 @@ +From 815f5f7b5dd971185fa45b55241fc4b3ee81c80e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 13:58:35 +0000 +Subject: neighbour: use RCU protection in __neigh_notify() + +From: Eric Dumazet + +[ Upstream commit becbd5850c03ed33b232083dd66c6e38c0c0e569 ] + +__neigh_notify() can be called without RTNL or RCU protection. + +Use RCU protection to avoid potential UAF. + +Fixes: 426b5303eb43 ("[NETNS]: Modify the neighbour table code so it handles multiple network namespaces") +Signed-off-by: Eric Dumazet +Reviewed-by: David Ahern +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250207135841.1948589-4-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/core/neighbour.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/net/core/neighbour.c b/net/core/neighbour.c +index b127533e74f37..2e2c009b5a2db 100644 +--- a/net/core/neighbour.c ++++ b/net/core/neighbour.c +@@ -3498,10 +3498,12 @@ static const struct seq_operations neigh_stat_seq_ops = { + static void __neigh_notify(struct neighbour *n, int type, int flags, + u32 pid) + { +- struct net *net = dev_net(n->dev); + struct sk_buff *skb; + int err = -ENOBUFS; ++ struct net *net; + ++ rcu_read_lock(); ++ net = dev_net_rcu(n->dev); + skb = nlmsg_new(neigh_nlmsg_size(), GFP_ATOMIC); + if (skb == NULL) + goto errout; +@@ -3514,9 +3516,11 @@ static void __neigh_notify(struct neighbour *n, int type, int flags, + goto errout; + } + rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC); +- return; ++ goto out; + errout: + rtnl_set_sk_err(net, RTNLGRP_NEIGH, err); ++out: ++ rcu_read_unlock(); + } + + void neigh_app_ns(struct neighbour *n) +-- +2.39.5 + diff --git a/queue-6.1/net-add-dev_net_rcu-helper.patch b/queue-6.1/net-add-dev_net_rcu-helper.patch new file mode 100644 index 0000000000..92d1fc2dca --- /dev/null +++ b/queue-6.1/net-add-dev_net_rcu-helper.patch @@ -0,0 +1,62 @@ +From 5aaa3ca6b033e85fcb52ecd0ba06361666010dca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 5 Feb 2025 15:51:09 +0000 +Subject: net: add dev_net_rcu() helper + +From: Eric Dumazet + +[ Upstream commit 482ad2a4ace2740ca0ff1cbc8f3c7f862f3ab507 ] + +dev->nd_net can change, readers should either +use rcu_read_lock() or RTNL. + +We currently use a generic helper, dev_net() with +no debugging support. We probably have many hidden bugs. + +Add dev_net_rcu() helper for callers using rcu_read_lock() +protection. + +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250205155120.1676781-2-edumazet@google.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 71b8471c93fa ("ipv4: use RCU protection in ipv4_default_advmss()") +Signed-off-by: Sasha Levin +--- + include/linux/netdevice.h | 6 ++++++ + include/net/net_namespace.h | 2 +- + 2 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index c75aed1fff7d1..d0b4920dee730 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -2538,6 +2538,12 @@ struct net *dev_net(const struct net_device *dev) + return read_pnet(&dev->nd_net); + } + ++static inline ++struct net *dev_net_rcu(const struct net_device *dev) ++{ ++ return read_pnet_rcu(&dev->nd_net); ++} ++ + static inline + void dev_net_set(struct net_device *dev, struct net *net) + { +diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h +index 3ffcc1b02a590..ee50d54936629 100644 +--- a/include/net/net_namespace.h ++++ b/include/net/net_namespace.h +@@ -373,7 +373,7 @@ static inline struct net *read_pnet(const possible_net_t *pnet) + #endif + } + +-static inline struct net *read_pnet_rcu(possible_net_t *pnet) ++static inline struct net *read_pnet_rcu(const possible_net_t *pnet) + { + #ifdef CONFIG_NET_NS + return rcu_dereference(pnet->net); +-- +2.39.5 + diff --git a/queue-6.1/net-ipv4-cache-pmtu-for-all-packet-paths-if-multipat.patch b/queue-6.1/net-ipv4-cache-pmtu-for-all-packet-paths-if-multipat.patch new file mode 100644 index 0000000000..0f03f365dd --- /dev/null +++ b/queue-6.1/net-ipv4-cache-pmtu-for-all-packet-paths-if-multipat.patch @@ -0,0 +1,292 @@ +From c8ebdeba76025607ff93da19339557ec43ceda1b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 8 Nov 2024 09:34:24 +0000 +Subject: net: ipv4: Cache pmtu for all packet paths if multipath enabled + +From: Vladimir Vdovin + +[ Upstream commit 7d3f3b4367f315a61fc615e3138f3d320da8c466 ] + +Check number of paths by fib_info_num_path(), +and update_or_create_fnhe() for every path. +Problem is that pmtu is cached only for the oif +that has received icmp message "need to frag", +other oifs will still try to use "default" iface mtu. + +An example topology showing the problem: + + | host1 + +---------+ + | dummy0 | 10.179.20.18/32 mtu9000 + +---------+ + +-----------+----------------+ + +---------+ +---------+ + | ens17f0 | 10.179.2.141/31 | ens17f1 | 10.179.2.13/31 + +---------+ +---------+ + | (all here have mtu 9000) | + +------+ +------+ + | ro1 | 10.179.2.140/31 | ro2 | 10.179.2.12/31 + +------+ +------+ + | | +---------+------------+-------------------+------ + | + +-----+ + | ro3 | 10.10.10.10 mtu1500 + +-----+ + | + ======================================== + some networks + ======================================== + | + +-----+ + | eth0| 10.10.30.30 mtu9000 + +-----+ + | host2 + +host1 have enabled multipath and +sysctl net.ipv4.fib_multipath_hash_policy = 1: + +default proto static src 10.179.20.18 + nexthop via 10.179.2.12 dev ens17f1 weight 1 + nexthop via 10.179.2.140 dev ens17f0 weight 1 + +When host1 tries to do pmtud from 10.179.20.18/32 to host2, +host1 receives at ens17f1 iface an icmp packet from ro3 that ro3 mtu=1500. +And host1 caches it in nexthop exceptions cache. + +Problem is that it is cached only for the iface that has received icmp, +and there is no way that ro3 will send icmp msg to host1 via another path. + +Host1 now have this routes to host2: + +ip r g 10.10.30.30 sport 30000 dport 443 +10.10.30.30 via 10.179.2.12 dev ens17f1 src 10.179.20.18 uid 0 + cache expires 521sec mtu 1500 + +ip r g 10.10.30.30 sport 30033 dport 443 +10.10.30.30 via 10.179.2.140 dev ens17f0 src 10.179.20.18 uid 0 + cache + +So when host1 tries again to reach host2 with mtu>1500, +if packet flow is lucky enough to be hashed with oif=ens17f1 its ok, +if oif=ens17f0 it blackholes and still gets icmp msgs from ro3 to ens17f1, +until lucky day when ro3 will send it through another flow to ens17f0. + +Signed-off-by: Vladimir Vdovin +Reviewed-by: Ido Schimmel +Link: https://patch.msgid.link/20241108093427.317942-1-deliran@verdict.gg +Signed-off-by: Jakub Kicinski +Stable-dep-of: 139512191bd0 ("ipv4: use RCU protection in __ip_rt_update_pmtu()") +Signed-off-by: Sasha Levin +--- + net/ipv4/route.c | 13 ++++ + tools/testing/selftests/net/pmtu.sh | 112 +++++++++++++++++++++++----- + 2 files changed, 108 insertions(+), 17 deletions(-) + +diff --git a/net/ipv4/route.c b/net/ipv4/route.c +index ae56d94f68d9f..0bda6916ebcfb 100644 +--- a/net/ipv4/route.c ++++ b/net/ipv4/route.c +@@ -1046,6 +1046,19 @@ static void __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu) + struct fib_nh_common *nhc; + + fib_select_path(net, &res, fl4, NULL); ++#ifdef CONFIG_IP_ROUTE_MULTIPATH ++ if (fib_info_num_path(res.fi) > 1) { ++ int nhsel; ++ ++ for (nhsel = 0; nhsel < fib_info_num_path(res.fi); nhsel++) { ++ nhc = fib_info_nhc(res.fi, nhsel); ++ update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock, ++ jiffies + net->ipv4.ip_rt_mtu_expires); ++ } ++ rcu_read_unlock(); ++ return; ++ } ++#endif /* CONFIG_IP_ROUTE_MULTIPATH */ + nhc = FIB_RES_NHC(res); + update_or_create_fnhe(nhc, fl4->daddr, 0, mtu, lock, + jiffies + net->ipv4.ip_rt_mtu_expires); +diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh +index dbfa56173d291..33f4fb34ac9b2 100755 +--- a/tools/testing/selftests/net/pmtu.sh ++++ b/tools/testing/selftests/net/pmtu.sh +@@ -197,6 +197,12 @@ + # + # - pmtu_ipv6_route_change + # Same as above but with IPv6 ++# ++# - pmtu_ipv4_mp_exceptions ++# Use the same topology as in pmtu_ipv4, but add routeable addresses ++# on host A and B on lo reachable via both routers. Host A and B ++# addresses have multipath routes to each other, b_r1 mtu = 1500. ++# Check that PMTU exceptions are created for both paths. + + # Kselftest framework requirement - SKIP code is 4. + ksft_skip=4 +@@ -266,7 +272,8 @@ tests=" + list_flush_ipv4_exception ipv4: list and flush cached exceptions 1 + list_flush_ipv6_exception ipv6: list and flush cached exceptions 1 + pmtu_ipv4_route_change ipv4: PMTU exception w/route replace 1 +- pmtu_ipv6_route_change ipv6: PMTU exception w/route replace 1" ++ pmtu_ipv6_route_change ipv6: PMTU exception w/route replace 1 ++ pmtu_ipv4_mp_exceptions ipv4: PMTU multipath nh exceptions 1" + + NS_A="ns-A" + NS_B="ns-B" +@@ -353,6 +360,9 @@ tunnel6_a_addr="fd00:2::a" + tunnel6_b_addr="fd00:2::b" + tunnel6_mask="64" + ++host4_a_addr="192.168.99.99" ++host4_b_addr="192.168.88.88" ++ + dummy6_0_prefix="fc00:1000::" + dummy6_1_prefix="fc00:1001::" + dummy6_mask="64" +@@ -907,6 +917,52 @@ setup_ovs_bridge() { + run_cmd ip route add ${prefix6}:${b_r1}::1 via ${prefix6}:${a_r1}::2 + } + ++setup_multipath_new() { ++ # Set up host A with multipath routes to host B host4_b_addr ++ run_cmd ${ns_a} ip addr add ${host4_a_addr} dev lo ++ run_cmd ${ns_a} ip nexthop add id 401 via ${prefix4}.${a_r1}.2 dev veth_A-R1 ++ run_cmd ${ns_a} ip nexthop add id 402 via ${prefix4}.${a_r2}.2 dev veth_A-R2 ++ run_cmd ${ns_a} ip nexthop add id 403 group 401/402 ++ run_cmd ${ns_a} ip route add ${host4_b_addr} src ${host4_a_addr} nhid 403 ++ ++ # Set up host B with multipath routes to host A host4_a_addr ++ run_cmd ${ns_b} ip addr add ${host4_b_addr} dev lo ++ run_cmd ${ns_b} ip nexthop add id 401 via ${prefix4}.${b_r1}.2 dev veth_B-R1 ++ run_cmd ${ns_b} ip nexthop add id 402 via ${prefix4}.${b_r2}.2 dev veth_B-R2 ++ run_cmd ${ns_b} ip nexthop add id 403 group 401/402 ++ run_cmd ${ns_b} ip route add ${host4_a_addr} src ${host4_b_addr} nhid 403 ++} ++ ++setup_multipath_old() { ++ # Set up host A with multipath routes to host B host4_b_addr ++ run_cmd ${ns_a} ip addr add ${host4_a_addr} dev lo ++ run_cmd ${ns_a} ip route add ${host4_b_addr} \ ++ src ${host4_a_addr} \ ++ nexthop via ${prefix4}.${a_r1}.2 weight 1 \ ++ nexthop via ${prefix4}.${a_r2}.2 weight 1 ++ ++ # Set up host B with multipath routes to host A host4_a_addr ++ run_cmd ${ns_b} ip addr add ${host4_b_addr} dev lo ++ run_cmd ${ns_b} ip route add ${host4_a_addr} \ ++ src ${host4_b_addr} \ ++ nexthop via ${prefix4}.${b_r1}.2 weight 1 \ ++ nexthop via ${prefix4}.${b_r2}.2 weight 1 ++} ++ ++setup_multipath() { ++ if [ "$USE_NH" = "yes" ]; then ++ setup_multipath_new ++ else ++ setup_multipath_old ++ fi ++ ++ # Set up routers with routes to dummies ++ run_cmd ${ns_r1} ip route add ${host4_a_addr} via ${prefix4}.${a_r1}.1 ++ run_cmd ${ns_r2} ip route add ${host4_a_addr} via ${prefix4}.${a_r2}.1 ++ run_cmd ${ns_r1} ip route add ${host4_b_addr} via ${prefix4}.${b_r1}.1 ++ run_cmd ${ns_r2} ip route add ${host4_b_addr} via ${prefix4}.${b_r2}.1 ++} ++ + setup() { + [ "$(id -u)" -ne 0 ] && echo " need to run as root" && return $ksft_skip + +@@ -988,23 +1044,15 @@ link_get_mtu() { + } + + route_get_dst_exception() { +- ns_cmd="${1}" +- dst="${2}" +- dsfield="${3}" ++ ns_cmd="${1}"; shift + +- if [ -z "${dsfield}" ]; then +- dsfield=0 +- fi +- +- ${ns_cmd} ip route get "${dst}" dsfield "${dsfield}" ++ ${ns_cmd} ip route get "$@" + } + + route_get_dst_pmtu_from_exception() { +- ns_cmd="${1}" +- dst="${2}" +- dsfield="${3}" ++ ns_cmd="${1}"; shift + +- mtu_parse "$(route_get_dst_exception "${ns_cmd}" "${dst}" "${dsfield}")" ++ mtu_parse "$(route_get_dst_exception "${ns_cmd}" "$@")" + } + + check_pmtu_value() { +@@ -1147,10 +1195,10 @@ test_pmtu_ipv4_dscp_icmp_exception() { + run_cmd "${ns_a}" ping -q -M want -Q "${dsfield}" -c 1 -w 1 -s "${len}" "${dst2}" + + # Check that exceptions have been created with the correct PMTU +- pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" "${policy_mark}")" ++ pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" dsfield "${policy_mark}")" + check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1 + +- pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" "${policy_mark}")" ++ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" dsfield "${policy_mark}")" + check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1 + } + +@@ -1197,9 +1245,9 @@ test_pmtu_ipv4_dscp_udp_exception() { + UDP:"${dst2}":50000,tos="${dsfield}" + + # Check that exceptions have been created with the correct PMTU +- pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" "${policy_mark}")" ++ pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst1}" dsfield "${policy_mark}")" + check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1 +- pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" "${policy_mark}")" ++ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst2}" dsfield "${policy_mark}")" + check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1 + } + +@@ -2205,6 +2253,36 @@ test_pmtu_ipv6_route_change() { + test_pmtu_ipvX_route_change 6 + } + ++test_pmtu_ipv4_mp_exceptions() { ++ setup namespaces routing multipath || return $ksft_skip ++ ++ trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ ++ "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \ ++ "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \ ++ "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2 ++ ++ # Set up initial MTU values ++ mtu "${ns_a}" veth_A-R1 2000 ++ mtu "${ns_r1}" veth_R1-A 2000 ++ mtu "${ns_r1}" veth_R1-B 1500 ++ mtu "${ns_b}" veth_B-R1 1500 ++ ++ mtu "${ns_a}" veth_A-R2 2000 ++ mtu "${ns_r2}" veth_R2-A 2000 ++ mtu "${ns_r2}" veth_R2-B 1500 ++ mtu "${ns_b}" veth_B-R2 1500 ++ ++ # Ping and expect two nexthop exceptions for two routes ++ run_cmd ${ns_a} ping -q -M want -i 0.1 -c 1 -s 1800 "${host4_b_addr}" ++ ++ # Check that exceptions have been created with the correct PMTU ++ pmtu_a_R1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${host4_b_addr}" oif veth_A-R1)" ++ pmtu_a_R2="$(route_get_dst_pmtu_from_exception "${ns_a}" "${host4_b_addr}" oif veth_A-R2)" ++ ++ check_pmtu_value "1500" "${pmtu_a_R1}" "exceeding MTU (veth_A-R1)" || return 1 ++ check_pmtu_value "1500" "${pmtu_a_R2}" "exceeding MTU (veth_A-R2)" || return 1 ++} ++ + usage() { + echo + echo "$0 [OPTIONS] [TEST]..." +-- +2.39.5 + diff --git a/queue-6.1/net-treat-possible_net_t-net-pointer-as-an-rcu-one-a.patch b/queue-6.1/net-treat-possible_net_t-net-pointer-as-an-rcu-one-a.patch new file mode 100644 index 0000000000..9ab3093e19 --- /dev/null +++ b/queue-6.1/net-treat-possible_net_t-net-pointer-as-an-rcu-one-a.patch @@ -0,0 +1,65 @@ +From 5dc92a140423879ea9100f85bf77ff6cb46c2d2a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 13 Oct 2023 14:10:23 +0200 +Subject: net: treat possible_net_t net pointer as an RCU one and add + read_pnet_rcu() + +From: Jiri Pirko + +[ Upstream commit 2034d90ae41ae93e30d492ebcf1f06f97a9cfba6 ] + +Make the net pointer stored in possible_net_t structure annotated as +an RCU pointer. Change the access helpers to treat it as such. +Introduce read_pnet_rcu() helper to allow caller to dereference +the net pointer under RCU read lock. + +Signed-off-by: Jiri Pirko +Reviewed-by: Simon Horman +Signed-off-by: David S. Miller +Stable-dep-of: 71b8471c93fa ("ipv4: use RCU protection in ipv4_default_advmss()") +Signed-off-by: Sasha Levin +--- + include/net/net_namespace.h | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h +index 17c7a88418345..3ffcc1b02a590 100644 +--- a/include/net/net_namespace.h ++++ b/include/net/net_namespace.h +@@ -353,21 +353,30 @@ static inline void put_net_track(struct net *net, netns_tracker *tracker) + + typedef struct { + #ifdef CONFIG_NET_NS +- struct net *net; ++ struct net __rcu *net; + #endif + } possible_net_t; + + static inline void write_pnet(possible_net_t *pnet, struct net *net) + { + #ifdef CONFIG_NET_NS +- pnet->net = net; ++ rcu_assign_pointer(pnet->net, net); + #endif + } + + static inline struct net *read_pnet(const possible_net_t *pnet) + { + #ifdef CONFIG_NET_NS +- return pnet->net; ++ return rcu_dereference_protected(pnet->net, true); ++#else ++ return &init_net; ++#endif ++} ++ ++static inline struct net *read_pnet_rcu(possible_net_t *pnet) ++{ ++#ifdef CONFIG_NET_NS ++ return rcu_dereference(pnet->net); + #else + return &init_net; + #endif +-- +2.39.5 + diff --git a/queue-6.1/openvswitch-use-rcu-protection-in-ovs_vport_cmd_fill.patch b/queue-6.1/openvswitch-use-rcu-protection-in-ovs_vport_cmd_fill.patch new file mode 100644 index 0000000000..526812fce9 --- /dev/null +++ b/queue-6.1/openvswitch-use-rcu-protection-in-ovs_vport_cmd_fill.patch @@ -0,0 +1,66 @@ +From f3a38f8d1c0bd6073720690cc074f712fb304f73 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 7 Feb 2025 13:58:37 +0000 +Subject: openvswitch: use RCU protection in ovs_vport_cmd_fill_info() + +From: Eric Dumazet + +[ Upstream commit 90b2f49a502fa71090d9f4fe29a2f51fe5dff76d ] + +ovs_vport_cmd_fill_info() can be called without RTNL or RCU. + +Use RCU protection and dev_net_rcu() to avoid potential UAF. + +Fixes: 9354d4520342 ("openvswitch: reliable interface indentification in port dumps") +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250207135841.1948589-6-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/openvswitch/datapath.c | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c +index 3c7b245354096..a2d8b1b4c83e5 100644 +--- a/net/openvswitch/datapath.c ++++ b/net/openvswitch/datapath.c +@@ -2076,6 +2076,7 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, + { + struct ovs_header *ovs_header; + struct ovs_vport_stats vport_stats; ++ struct net *net_vport; + int err; + + ovs_header = genlmsg_put(skb, portid, seq, &dp_vport_genl_family, +@@ -2092,12 +2093,15 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, + nla_put_u32(skb, OVS_VPORT_ATTR_IFINDEX, vport->dev->ifindex)) + goto nla_put_failure; + +- if (!net_eq(net, dev_net(vport->dev))) { +- int id = peernet2id_alloc(net, dev_net(vport->dev), gfp); ++ rcu_read_lock(); ++ net_vport = dev_net_rcu(vport->dev); ++ if (!net_eq(net, net_vport)) { ++ int id = peernet2id_alloc(net, net_vport, GFP_ATOMIC); + + if (nla_put_s32(skb, OVS_VPORT_ATTR_NETNSID, id)) +- goto nla_put_failure; ++ goto nla_put_failure_unlock; + } ++ rcu_read_unlock(); + + ovs_vport_get_stats(vport, &vport_stats); + if (nla_put_64bit(skb, OVS_VPORT_ATTR_STATS, +@@ -2115,6 +2119,8 @@ static int ovs_vport_cmd_fill_info(struct vport *vport, struct sk_buff *skb, + genlmsg_end(skb, ovs_header); + return 0; + ++nla_put_failure_unlock: ++ rcu_read_unlock(); + nla_put_failure: + err = -EMSGSIZE; + error: +-- +2.39.5 + diff --git a/queue-6.1/series b/queue-6.1/series index 0c9d78878a..525a2b19d6 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -528,3 +528,23 @@ alpha-align-stack-for-page-fault-and-user-unaligned-trap-handlers.patch gpiolib-acpi-add-a-quirk-for-acer-nitro-anv14.patch gpio-stmpe-check-return-value-of-stmpe_reg_read-in-stmpe_gpio_irq_sync_unlock.patch partitions-mac-fix-handling-of-bogus-partition-table.patch +clocksource-use-pr_info-for-checking-clocksource-syn.patch +clocksource-use-migrate_disable-to-avoid-calling-get.patch +ipv4-add-rcu-protection-to-ip4_dst_hoplimit.patch +net-treat-possible_net_t-net-pointer-as-an-rcu-one-a.patch +net-add-dev_net_rcu-helper.patch +ipv4-use-rcu-protection-in-ipv4_default_advmss.patch +ipv4-use-rcu-protection-in-rt_is_expired.patch +ipv4-use-rcu-protection-in-inet_select_addr.patch +net-ipv4-cache-pmtu-for-all-packet-paths-if-multipat.patch +ipv4-use-rcu-protection-in-__ip_rt_update_pmtu.patch +ipv4-icmp-convert-to-dev_net_rcu.patch +flow_dissector-use-rcu-protection-to-fetch-dev_net.patch +ipv6-use-rcu-protection-in-ip6_default_advmss.patch +ndisc-use-rcu-protection-in-ndisc_alloc_skb.patch +neighbour-delete-redundant-judgment-statements.patch +neighbour-use-rcu-protection-in-__neigh_notify.patch +arp-use-rcu-protection-in-arp_xmit.patch +openvswitch-use-rcu-protection-in-ovs_vport_cmd_fill.patch +ndisc-extend-rcu-protection-in-ndisc_send_skb.patch +ipv6-mcast-add-rcu-protection-to-mld_newpack.patch