]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.10
authorSasha Levin <sashal@kernel.org>
Fri, 19 Apr 2024 11:43:51 +0000 (07:43 -0400)
committerSasha Levin <sashal@kernel.org>
Fri, 19 Apr 2024 11:43:51 +0000 (07:43 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.10/netfilter-nf_tables-fix-potential-data-race-in-__nft.patch [new file with mode: 0644]
queue-5.10/netfilter-nft_set_pipapo-do-not-free-live-element.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/tun-limit-printing-rate-when-illegal-packet-received.patch [new file with mode: 0644]

diff --git a/queue-5.10/netfilter-nf_tables-fix-potential-data-race-in-__nft.patch b/queue-5.10/netfilter-nf_tables-fix-potential-data-race-in-__nft.patch
new file mode 100644 (file)
index 0000000..a6f2017
--- /dev/null
@@ -0,0 +1,58 @@
+From 5539f57d3b44ffcbe7cb459f7477e2b5595b911a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 7 Apr 2024 14:56:04 +0800
+Subject: netfilter: nf_tables: Fix potential data-race in
+ __nft_expr_type_get()
+
+From: Ziyang Xuan <william.xuanziyang@huawei.com>
+
+[ Upstream commit f969eb84ce482331a991079ab7a5c4dc3b7f89bf ]
+
+nft_unregister_expr() can concurrent with __nft_expr_type_get(),
+and there is not any protection when iterate over nf_tables_expressions
+list in __nft_expr_type_get(). Therefore, there is potential data-race
+of nf_tables_expressions list entry.
+
+Use list_for_each_entry_rcu() to iterate over nf_tables_expressions
+list in __nft_expr_type_get(), and use rcu_read_lock() in the caller
+nft_expr_type_get() to protect the entire type query process.
+
+Fixes: ef1f7df9170d ("netfilter: nf_tables: expression ops overloading")
+Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_tables_api.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index ab7f7e45b9846..858d09b54eaa4 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -2739,7 +2739,7 @@ static const struct nft_expr_type *__nft_expr_type_get(u8 family,
+ {
+       const struct nft_expr_type *type, *candidate = NULL;
+-      list_for_each_entry(type, &nf_tables_expressions, list) {
++      list_for_each_entry_rcu(type, &nf_tables_expressions, list) {
+               if (!nla_strcmp(nla, type->name)) {
+                       if (!type->family && !candidate)
+                               candidate = type;
+@@ -2771,9 +2771,13 @@ static const struct nft_expr_type *nft_expr_type_get(struct net *net,
+       if (nla == NULL)
+               return ERR_PTR(-EINVAL);
++      rcu_read_lock();
+       type = __nft_expr_type_get(family, nla);
+-      if (type != NULL && try_module_get(type->owner))
++      if (type != NULL && try_module_get(type->owner)) {
++              rcu_read_unlock();
+               return type;
++      }
++      rcu_read_unlock();
+       lockdep_nfnl_nft_mutex_not_held();
+ #ifdef CONFIG_MODULES
+-- 
+2.43.0
+
diff --git a/queue-5.10/netfilter-nft_set_pipapo-do-not-free-live-element.patch b/queue-5.10/netfilter-nft_set_pipapo-do-not-free-live-element.patch
new file mode 100644 (file)
index 0000000..0a36340
--- /dev/null
@@ -0,0 +1,105 @@
+From d649978c56b7710a3d638a30c56baf3dde33ffeb Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 10 Apr 2024 21:05:13 +0200
+Subject: netfilter: nft_set_pipapo: do not free live element
+
+From: Florian Westphal <fw@strlen.de>
+
+[ Upstream commit 3cfc9ec039af60dbd8965ae085b2c2ccdcfbe1cc ]
+
+Pablo reports a crash with large batches of elements with a
+back-to-back add/remove pattern.  Quoting Pablo:
+
+  add_elem("00000000") timeout 100 ms
+  ...
+  add_elem("0000000X") timeout 100 ms
+  del_elem("0000000X") <---------------- delete one that was just added
+  ...
+  add_elem("00005000") timeout 100 ms
+
+  1) nft_pipapo_remove() removes element 0000000X
+  Then, KASAN shows a splat.
+
+Looking at the remove function there is a chance that we will drop a
+rule that maps to a non-deactivated element.
+
+Removal happens in two steps, first we do a lookup for key k and return the
+to-be-removed element and mark it as inactive in the next generation.
+Then, in a second step, the element gets removed from the set/map.
+
+The _remove function does not work correctly if we have more than one
+element that share the same key.
+
+This can happen if we insert an element into a set when the set already
+holds an element with same key, but the element mapping to the existing
+key has timed out or is not active in the next generation.
+
+In such case its possible that removal will unmap the wrong element.
+If this happens, we will leak the non-deactivated element, it becomes
+unreachable.
+
+The element that got deactivated (and will be freed later) will
+remain reachable in the set data structure, this can result in
+a crash when such an element is retrieved during lookup (stale
+pointer).
+
+Add a check that the fully matching key does in fact map to the element
+that we have marked as inactive in the deactivation step.
+If not, we need to continue searching.
+
+Add a bug/warn trap at the end of the function as well, the remove
+function must not ever be called with an invisible/unreachable/non-existent
+element.
+
+v2: avoid uneeded temporary variable (Stefano)
+
+Fixes: 3c4287f62044 ("nf_tables: Add set type for arbitrary concatenation of ranges")
+Reported-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nft_set_pipapo.c | 14 +++++++++-----
+ 1 file changed, 9 insertions(+), 5 deletions(-)
+
+diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c
+index b9682e085fcef..5a8521abd8f5c 100644
+--- a/net/netfilter/nft_set_pipapo.c
++++ b/net/netfilter/nft_set_pipapo.c
+@@ -1980,6 +1980,8 @@ static void nft_pipapo_remove(const struct net *net, const struct nft_set *set,
+               rules_fx = rules_f0;
+               nft_pipapo_for_each_field(f, i, m) {
++                      bool last = i == m->field_count - 1;
++
+                       if (!pipapo_match_field(f, start, rules_fx,
+                                               match_start, match_end))
+                               break;
+@@ -1992,16 +1994,18 @@ static void nft_pipapo_remove(const struct net *net, const struct nft_set *set,
+                       match_start += NFT_PIPAPO_GROUPS_PADDED_SIZE(f);
+                       match_end += NFT_PIPAPO_GROUPS_PADDED_SIZE(f);
+-              }
+-              if (i == m->field_count) {
+-                      priv->dirty = true;
+-                      pipapo_drop(m, rulemap);
+-                      return;
++                      if (last && f->mt[rulemap[i].to].e == e) {
++                              priv->dirty = true;
++                              pipapo_drop(m, rulemap);
++                              return;
++                      }
+               }
+               first_rule += rules_f0;
+       }
++
++      WARN_ON_ONCE(1); /* elem_priv not found */
+ }
+ /**
+-- 
+2.43.0
+
index 83637f15b59881ea149c416807c6e2cdeb8f88f0..2f8ef693c7d2417bdce2575d6d78ed81d5c01484 100644 (file)
@@ -34,3 +34,6 @@ ring-buffer-only-update-pages_touched-when-a-new-pag.patch
 selftests-ftrace-limit-length-in-subsystem-enable-tests.patch
 kprobes-fix-possible-use-after-free-issue-on-kprobe-registration.patch
 revert-tracing-trigger-fix-to-return-error-if-failed-to-alloc-snapshot.patch
+netfilter-nf_tables-fix-potential-data-race-in-__nft.patch
+netfilter-nft_set_pipapo-do-not-free-live-element.patch
+tun-limit-printing-rate-when-illegal-packet-received.patch
diff --git a/queue-5.10/tun-limit-printing-rate-when-illegal-packet-received.patch b/queue-5.10/tun-limit-printing-rate-when-illegal-packet-received.patch
new file mode 100644 (file)
index 0000000..6296512
--- /dev/null
@@ -0,0 +1,91 @@
+From ee1583f435bc2e49936703d1d16ba06f44a04957 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 14 Apr 2024 22:02:46 -0400
+Subject: tun: limit printing rate when illegal packet received by tun dev
+
+From: Lei Chen <lei.chen@smartx.com>
+
+[ Upstream commit f8bbc07ac535593139c875ffa19af924b1084540 ]
+
+vhost_worker will call tun call backs to receive packets. If too many
+illegal packets arrives, tun_do_read will keep dumping packet contents.
+When console is enabled, it will costs much more cpu time to dump
+packet and soft lockup will be detected.
+
+net_ratelimit mechanism can be used to limit the dumping rate.
+
+PID: 33036    TASK: ffff949da6f20000  CPU: 23   COMMAND: "vhost-32980"
+ #0 [fffffe00003fce50] crash_nmi_callback at ffffffff89249253
+ #1 [fffffe00003fce58] nmi_handle at ffffffff89225fa3
+ #2 [fffffe00003fceb0] default_do_nmi at ffffffff8922642e
+ #3 [fffffe00003fced0] do_nmi at ffffffff8922660d
+ #4 [fffffe00003fcef0] end_repeat_nmi at ffffffff89c01663
+    [exception RIP: io_serial_in+20]
+    RIP: ffffffff89792594  RSP: ffffa655314979e8  RFLAGS: 00000002
+    RAX: ffffffff89792500  RBX: ffffffff8af428a0  RCX: 0000000000000000
+    RDX: 00000000000003fd  RSI: 0000000000000005  RDI: ffffffff8af428a0
+    RBP: 0000000000002710   R8: 0000000000000004   R9: 000000000000000f
+    R10: 0000000000000000  R11: ffffffff8acbf64f  R12: 0000000000000020
+    R13: ffffffff8acbf698  R14: 0000000000000058  R15: 0000000000000000
+    ORIG_RAX: ffffffffffffffff  CS: 0010  SS: 0018
+ #5 [ffffa655314979e8] io_serial_in at ffffffff89792594
+ #6 [ffffa655314979e8] wait_for_xmitr at ffffffff89793470
+ #7 [ffffa65531497a08] serial8250_console_putchar at ffffffff897934f6
+ #8 [ffffa65531497a20] uart_console_write at ffffffff8978b605
+ #9 [ffffa65531497a48] serial8250_console_write at ffffffff89796558
+ #10 [ffffa65531497ac8] console_unlock at ffffffff89316124
+ #11 [ffffa65531497b10] vprintk_emit at ffffffff89317c07
+ #12 [ffffa65531497b68] printk at ffffffff89318306
+ #13 [ffffa65531497bc8] print_hex_dump at ffffffff89650765
+ #14 [ffffa65531497ca8] tun_do_read at ffffffffc0b06c27 [tun]
+ #15 [ffffa65531497d38] tun_recvmsg at ffffffffc0b06e34 [tun]
+ #16 [ffffa65531497d68] handle_rx at ffffffffc0c5d682 [vhost_net]
+ #17 [ffffa65531497ed0] vhost_worker at ffffffffc0c644dc [vhost]
+ #18 [ffffa65531497f10] kthread at ffffffff892d2e72
+ #19 [ffffa65531497f50] ret_from_fork at ffffffff89c0022f
+
+Fixes: ef3db4a59542 ("tun: avoid BUG, dump packet on GSO errors")
+Signed-off-by: Lei Chen <lei.chen@smartx.com>
+Reviewed-by: Willem de Bruijn <willemb@google.com>
+Acked-by: Jason Wang <jasowang@redhat.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Acked-by: Michael S. Tsirkin <mst@redhat.com>
+Link: https://lore.kernel.org/r/20240415020247.2207781-1-lei.chen@smartx.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/tun.c | 18 ++++++++++--------
+ 1 file changed, 10 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index bb0368272a1bb..77e63e7366e78 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -2141,14 +2141,16 @@ static ssize_t tun_put_user(struct tun_struct *tun,
+                                           tun_is_little_endian(tun), true,
+                                           vlan_hlen)) {
+                       struct skb_shared_info *sinfo = skb_shinfo(skb);
+-                      pr_err("unexpected GSO type: "
+-                             "0x%x, gso_size %d, hdr_len %d\n",
+-                             sinfo->gso_type, tun16_to_cpu(tun, gso.gso_size),
+-                             tun16_to_cpu(tun, gso.hdr_len));
+-                      print_hex_dump(KERN_ERR, "tun: ",
+-                                     DUMP_PREFIX_NONE,
+-                                     16, 1, skb->head,
+-                                     min((int)tun16_to_cpu(tun, gso.hdr_len), 64), true);
++
++                      if (net_ratelimit()) {
++                              netdev_err(tun->dev, "unexpected GSO type: 0x%x, gso_size %d, hdr_len %d\n",
++                                         sinfo->gso_type, tun16_to_cpu(tun, gso.gso_size),
++                                         tun16_to_cpu(tun, gso.hdr_len));
++                              print_hex_dump(KERN_ERR, "tun: ",
++                                             DUMP_PREFIX_NONE,
++                                             16, 1, skb->head,
++                                             min((int)tun16_to_cpu(tun, gso.hdr_len), 64), true);
++                      }
+                       WARN_ON_ONCE(1);
+                       return -EINVAL;
+               }
+-- 
+2.43.0
+