]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.1
authorSasha Levin <sashal@kernel.org>
Tue, 18 Feb 2025 12:30:05 +0000 (07:30 -0500)
committerSasha Levin <sashal@kernel.org>
Tue, 18 Feb 2025 12:31:06 +0000 (07:31 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
21 files changed:
queue-6.1/arp-use-rcu-protection-in-arp_xmit.patch [new file with mode: 0644]
queue-6.1/clocksource-use-migrate_disable-to-avoid-calling-get.patch [new file with mode: 0644]
queue-6.1/clocksource-use-pr_info-for-checking-clocksource-syn.patch [new file with mode: 0644]
queue-6.1/flow_dissector-use-rcu-protection-to-fetch-dev_net.patch [new file with mode: 0644]
queue-6.1/ipv4-add-rcu-protection-to-ip4_dst_hoplimit.patch [new file with mode: 0644]
queue-6.1/ipv4-icmp-convert-to-dev_net_rcu.patch [new file with mode: 0644]
queue-6.1/ipv4-use-rcu-protection-in-__ip_rt_update_pmtu.patch [new file with mode: 0644]
queue-6.1/ipv4-use-rcu-protection-in-inet_select_addr.patch [new file with mode: 0644]
queue-6.1/ipv4-use-rcu-protection-in-ipv4_default_advmss.patch [new file with mode: 0644]
queue-6.1/ipv4-use-rcu-protection-in-rt_is_expired.patch [new file with mode: 0644]
queue-6.1/ipv6-mcast-add-rcu-protection-to-mld_newpack.patch [new file with mode: 0644]
queue-6.1/ipv6-use-rcu-protection-in-ip6_default_advmss.patch [new file with mode: 0644]
queue-6.1/ndisc-extend-rcu-protection-in-ndisc_send_skb.patch [new file with mode: 0644]
queue-6.1/ndisc-use-rcu-protection-in-ndisc_alloc_skb.patch [new file with mode: 0644]
queue-6.1/neighbour-delete-redundant-judgment-statements.patch [new file with mode: 0644]
queue-6.1/neighbour-use-rcu-protection-in-__neigh_notify.patch [new file with mode: 0644]
queue-6.1/net-add-dev_net_rcu-helper.patch [new file with mode: 0644]
queue-6.1/net-ipv4-cache-pmtu-for-all-packet-paths-if-multipat.patch [new file with mode: 0644]
queue-6.1/net-treat-possible_net_t-net-pointer-as-an-rcu-one-a.patch [new file with mode: 0644]
queue-6.1/openvswitch-use-rcu-protection-in-ovs_vport_cmd_fill.patch [new file with mode: 0644]
queue-6.1/series

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 (file)
index 0000000..ee12570
--- /dev/null
@@ -0,0 +1,45 @@
+From 21a32096f2f777dae1ef8d481f1001e1b075d79a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Feb 2025 13:58:36 +0000
+Subject: arp: use RCU protection in arp_xmit()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250207135841.1948589-5-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..2e82522
--- /dev/null
@@ -0,0 +1,82 @@
+From 5dea4d0602318540833fabeda2a7b71fbf9a4b36 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <longman@redhat.com>
+
+[ 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 <bigeasy@linutronix.de>
+Signed-off-by: Waiman Long <longman@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
+Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
+Link: https://lore.kernel.org/all/20250131173323.891943-2-longman@redhat.com
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..892c41a
--- /dev/null
@@ -0,0 +1,45 @@
+From bea3e1e5ed72db1aa7a98a7a2b58de68bec7a8f7 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 24 Jan 2025 20:54:41 -0500
+Subject: clocksource: Use pr_info() for "Checking clocksource synchronization"
+ message
+
+From: Waiman Long <longman@redhat.com>
+
+[ 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 <longman@redhat.com>
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Reviewed-by: Paul E. McKenney <paulmck@kernel.org>
+Acked-by: John Stultz <jstultz@google.com>
+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 <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..1416572
--- /dev/null
@@ -0,0 +1,81 @@
+From 08212d273809959b3134d720ae57ed4e84fcb66d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 15:51:17 +0000
+Subject: flow_dissector: use RCU protection to fetch dev_net()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250205155120.1676781-10-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..0904872
--- /dev/null
@@ -0,0 +1,47 @@
+From efab47b045842984df0fa4f1febb36ae1715a8d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 15:51:10 +0000
+Subject: ipv4: add RCU protection to ip4_dst_hoplimit()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250205155120.1676781-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..65ce5cf
--- /dev/null
@@ -0,0 +1,150 @@
+From 1467da24a9cfa031f950f499423d5d5520515d76 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 15:51:16 +0000
+Subject: ipv4: icmp: convert to dev_net_rcu()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <kuba@kernel.org>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Link: https://patch.msgid.link/20250205155120.1676781-9-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..8d64ef4
--- /dev/null
@@ -0,0 +1,77 @@
+From bda9cb4b28b0d1089385ff4113674307ca7b21df Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 15:51:15 +0000
+Subject: ipv4: use RCU protection in __ip_rt_update_pmtu()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Link: https://patch.msgid.link/20250205155120.1676781-8-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..ce0a435
--- /dev/null
@@ -0,0 +1,41 @@
+From d954885a7286107106974242899115e06889e4ac Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 15:51:14 +0000
+Subject: ipv4: use RCU protection in inet_select_addr()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Link: https://patch.msgid.link/20250205155120.1676781-7-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..59c34d2
--- /dev/null
@@ -0,0 +1,48 @@
+From 27d33b9f04ff941a73a8e3dd7f66b649aa041f80 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 15:51:12 +0000
+Subject: ipv4: use RCU protection in ipv4_default_advmss()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250205155120.1676781-5-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..c740033
--- /dev/null
@@ -0,0 +1,44 @@
+From b9d91058f8ce83026e8e2a8282890797ad6e2ed6 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 15:51:13 +0000
+Subject: ipv4: use RCU protection in rt_is_expired()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250205155120.1676781-6-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..6306983
--- /dev/null
@@ -0,0 +1,80 @@
+From d068448361a4775dc0449560d4ebbd7a866a2ffc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 12 Feb 2025 14:10:21 +0000
+Subject: ipv6: mcast: add RCU protection to mld_newpack()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Link: https://patch.msgid.link/20250212141021.1663666-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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)) {
+               /* <draft-ietf-magma-mld-source-05.txt>:
+                * 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 (file)
index 0000000..e16255e
--- /dev/null
@@ -0,0 +1,49 @@
+From a2ed0b04691e00b46d8628a8b04f06532a37b0ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 15:51:18 +0000
+Subject: ipv6: use RCU protection in ip6_default_advmss()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250205155120.1676781-11-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..9b32f84
--- /dev/null
@@ -0,0 +1,72 @@
+From 514ee4ee7c70390ff7483df13e3b0754621106ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Feb 2025 13:58:39 +0000
+Subject: ndisc: extend RCU protection in ndisc_send_skb()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250207135841.1948589-8-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..48a8c99
--- /dev/null
@@ -0,0 +1,59 @@
+From f794eb073c5d56e643785429fc129c0feebf0392 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Feb 2025 13:58:34 +0000
+Subject: ndisc: use RCU protection in ndisc_alloc_skb()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250207135841.1948589-3-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..762f846
--- /dev/null
@@ -0,0 +1,40 @@
+From 0b557d70cf51a93d8a2e244a6a9f42fb8326ec46 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 22 Aug 2024 12:32:45 +0800
+Subject: neighbour: delete redundant judgment statements
+
+From: Li Zetao <lizetao1@huawei.com>
+
+[ 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 <lizetao1@huawei.com>
+Reviewed-by: Petr Machata <petrm@nvidia.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: becbd5850c03 ("neighbour: use RCU protection in __neigh_notify()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..543551e
--- /dev/null
@@ -0,0 +1,58 @@
+From 815f5f7b5dd971185fa45b55241fc4b3ee81c80e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Feb 2025 13:58:35 +0000
+Subject: neighbour: use RCU protection in __neigh_notify()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reviewed-by: David Ahern <dsahern@kernel.org>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250207135841.1948589-4-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..92d1fc2
--- /dev/null
@@ -0,0 +1,62 @@
+From 5aaa3ca6b033e85fcb52ecd0ba06361666010dca Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 5 Feb 2025 15:51:09 +0000
+Subject: net: add dev_net_rcu() helper
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250205155120.1676781-2-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 71b8471c93fa ("ipv4: use RCU protection in ipv4_default_advmss()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..0f03f36
--- /dev/null
@@ -0,0 +1,292 @@
+From c8ebdeba76025607ff93da19339557ec43ceda1b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 8 Nov 2024 09:34:24 +0000
+Subject: net: ipv4: Cache pmtu for all packet paths if multipath enabled
+
+From: Vladimir Vdovin <deliran@verdict.gg>
+
+[ 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 <deliran@verdict.gg>
+Reviewed-by: Ido Schimmel <idosch@nvidia.com>
+Link: https://patch.msgid.link/20241108093427.317942-1-deliran@verdict.gg
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Stable-dep-of: 139512191bd0 ("ipv4: use RCU protection in __ip_rt_update_pmtu()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..9ab3093
--- /dev/null
@@ -0,0 +1,65 @@
+From 5dc92a140423879ea9100f85bf77ff6cb46c2d2a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <jiri@nvidia.com>
+
+[ 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 <jiri@nvidia.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 71b8471c93fa ("ipv4: use RCU protection in ipv4_default_advmss()")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..526812f
--- /dev/null
@@ -0,0 +1,66 @@
+From f3a38f8d1c0bd6073720690cc074f712fb304f73 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 7 Feb 2025 13:58:37 +0000
+Subject: openvswitch: use RCU protection in ovs_vport_cmd_fill_info()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Reviewed-by: Kuniyuki Iwashima <kuniyu@amazon.com>
+Link: https://patch.msgid.link/20250207135841.1948589-6-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+
index 0c9d78878ad1ab62e79f44d5de0a28bd4fce1b70..525a2b19d693389dae6bdbe4e18dd82e21d2222f 100644 (file)
@@ -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