diff options
author | Sasha Levin <sashal@kernel.org> | 2024-04-19 07:43:51 -0400 |
---|---|---|
committer | Sasha Levin <sashal@kernel.org> | 2024-04-19 07:43:51 -0400 |
commit | b6adb0780786dee6a1466dcca94c22b2c0b0f2d9 (patch) | |
tree | 3d10643377d014d74ddf4b6c2b9c12ba635ac204 | |
parent | bc31263b2ebeaace32b5941c3cedc82d46815689 (diff) | |
download | stable-queue-b6adb0780786dee6a1466dcca94c22b2c0b0f2d9.tar.gz |
Fixes for 5.10
Signed-off-by: Sasha Levin <sashal@kernel.org>
4 files changed, 257 insertions, 0 deletions
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 index 0000000000..a6f20171d5 --- /dev/null +++ b/queue-5.10/netfilter-nf_tables-fix-potential-data-race-in-__nft.patch @@ -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 index 0000000000..0a36340165 --- /dev/null +++ b/queue-5.10/netfilter-nft_set_pipapo-do-not-free-live-element.patch @@ -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 + diff --git a/queue-5.10/series b/queue-5.10/series index 83637f15b5..2f8ef693c7 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -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 index 0000000000..62965127d4 --- /dev/null +++ b/queue-5.10/tun-limit-printing-rate-when-illegal-packet-received.patch @@ -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 + |