]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.4-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Sep 2021 08:43:04 +0000 (10:43 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 13 Sep 2021 08:43:04 +0000 (10:43 +0200)
added patches:
netns-protect-netns-id-lookups-with-rcu.patch

queue-5.4/netns-protect-netns-id-lookups-with-rcu.patch [new file with mode: 0644]
queue-5.4/series

diff --git a/queue-5.4/netns-protect-netns-id-lookups-with-rcu.patch b/queue-5.4/netns-protect-netns-id-lookups-with-rcu.patch
new file mode 100644 (file)
index 0000000..ba36b0d
--- /dev/null
@@ -0,0 +1,94 @@
+From 2dce224f469f060b9998a5a869151ef83c08ce77 Mon Sep 17 00:00:00 2001
+From: Guillaume Nault <gnault@redhat.com>
+Date: Mon, 13 Jan 2020 22:39:22 +0100
+Subject: netns: protect netns ID lookups with RCU
+
+From: Guillaume Nault <gnault@redhat.com>
+
+commit 2dce224f469f060b9998a5a869151ef83c08ce77 upstream.
+
+__peernet2id() can be protected by RCU as it only calls idr_for_each(),
+which is RCU-safe, and never modifies the nsid table.
+
+rtnl_net_dumpid() can also do lockless lookups. It does two nested
+idr_for_each() calls on nsid tables (one direct call and one indirect
+call because of rtnl_net_dumpid_one() calling __peernet2id()). The
+netnsid tables are never updated. Therefore it is safe to not take the
+nsid_lock and run within an RCU-critical section instead.
+
+Signed-off-by: Guillaume Nault <gnault@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: HÃ¥kon Bugge <haakon.bugge@oracle.com>
+
+---
+ net/core/net_namespace.c |   28 ++++++++++------------------
+ 1 file changed, 10 insertions(+), 18 deletions(-)
+
+--- a/net/core/net_namespace.c
++++ b/net/core/net_namespace.c
+@@ -211,9 +211,9 @@ static int net_eq_idr(int id, void *net,
+       return 0;
+ }
+-/* Should be called with nsid_lock held. If a new id is assigned, the bool alloc
+- * is set to true, thus the caller knows that the new id must be notified via
+- * rtnl.
++/* Must be called from RCU-critical section or with nsid_lock held. If
++ * a new id is assigned, the bool alloc is set to true, thus the
++ * caller knows that the new id must be notified via rtnl.
+  */
+ static int __peernet2id_alloc(struct net *net, struct net *peer, bool *alloc)
+ {
+@@ -237,7 +237,7 @@ static int __peernet2id_alloc(struct net
+       return NETNSA_NSID_NOT_ASSIGNED;
+ }
+-/* should be called with nsid_lock held */
++/* Must be called from RCU-critical section or with nsid_lock held */
+ static int __peernet2id(struct net *net, struct net *peer)
+ {
+       bool no = false;
+@@ -281,9 +281,10 @@ int peernet2id(struct net *net, struct n
+ {
+       int id;
+-      spin_lock_bh(&net->nsid_lock);
++      rcu_read_lock();
+       id = __peernet2id(net, peer);
+-      spin_unlock_bh(&net->nsid_lock);
++      rcu_read_unlock();
++
+       return id;
+ }
+ EXPORT_SYMBOL(peernet2id);
+@@ -962,6 +963,7 @@ struct rtnl_net_dump_cb {
+       int s_idx;
+ };
++/* Runs in RCU-critical section. */
+ static int rtnl_net_dumpid_one(int id, void *peer, void *data)
+ {
+       struct rtnl_net_dump_cb *net_cb = (struct rtnl_net_dump_cb *)data;
+@@ -1046,19 +1048,9 @@ static int rtnl_net_dumpid(struct sk_buf
+                       goto end;
+       }
+-      spin_lock_bh(&net_cb.tgt_net->nsid_lock);
+-      if (net_cb.fillargs.add_ref &&
+-          !net_eq(net_cb.ref_net, net_cb.tgt_net) &&
+-          !spin_trylock_bh(&net_cb.ref_net->nsid_lock)) {
+-              spin_unlock_bh(&net_cb.tgt_net->nsid_lock);
+-              err = -EAGAIN;
+-              goto end;
+-      }
++      rcu_read_lock();
+       idr_for_each(&net_cb.tgt_net->netns_ids, rtnl_net_dumpid_one, &net_cb);
+-      if (net_cb.fillargs.add_ref &&
+-          !net_eq(net_cb.ref_net, net_cb.tgt_net))
+-              spin_unlock_bh(&net_cb.ref_net->nsid_lock);
+-      spin_unlock_bh(&net_cb.tgt_net->nsid_lock);
++      rcu_read_unlock();
+       cb->args[0] = net_cb.idx;
+ end:
index a8ca7a6ba280ef2029a58c693fff0ae4d1c9850f..21f681fa20cba58971c50ac50783cb31d94d761f 100644 (file)
@@ -59,6 +59,7 @@ media-go7007-remove-redundant-initialization.patch
 media-coda-fix-frame_mem_ctrl-for-yuv420-and-yvu420-.patch
 bluetooth-sco-prevent-information-leak-in-sco_conn_d.patch
 6lowpan-iphc-fix-an-off-by-one-check-of-array-index.patch
+netns-protect-netns-id-lookups-with-rcu.patch
 drm-amdgpu-acp-make-pm-domain-really-work.patch
 tcp-seq_file-avoid-skipping-sk-during-tcp_seek_last_.patch
 arm-dts-meson8-use-a-higher-default-gpu-clock-freque.patch