]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/5.10.215/netfilter-nf_tables-fix-potential-data-race-in-__nft_flowtable_type_get.patch
Linux 5.10.215
[thirdparty/kernel/stable-queue.git] / releases / 5.10.215 / netfilter-nf_tables-fix-potential-data-race-in-__nft_flowtable_type_get.patch
1 From 24225011d81b471acc0e1e315b7d9905459a6304 Mon Sep 17 00:00:00 2001
2 From: Ziyang Xuan <william.xuanziyang@huawei.com>
3 Date: Wed, 3 Apr 2024 15:22:04 +0800
4 Subject: netfilter: nf_tables: Fix potential data-race in __nft_flowtable_type_get()
5
6 From: Ziyang Xuan <william.xuanziyang@huawei.com>
7
8 commit 24225011d81b471acc0e1e315b7d9905459a6304 upstream.
9
10 nft_unregister_flowtable_type() within nf_flow_inet_module_exit() can
11 concurrent with __nft_flowtable_type_get() within nf_tables_newflowtable().
12 And thhere is not any protection when iterate over nf_tables_flowtables
13 list in __nft_flowtable_type_get(). Therefore, there is pertential
14 data-race of nf_tables_flowtables list entry.
15
16 Use list_for_each_entry_rcu() to iterate over nf_tables_flowtables list
17 in __nft_flowtable_type_get(), and use rcu_read_lock() in the caller
18 nft_flowtable_type_get() to protect the entire type query process.
19
20 Fixes: 3b49e2e94e6e ("netfilter: nf_tables: add flow table netlink frontend")
21 Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
22 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
23 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 ---
25 net/netfilter/nf_tables_api.c | 9 +++++++--
26 1 file changed, 7 insertions(+), 2 deletions(-)
27
28 --- a/net/netfilter/nf_tables_api.c
29 +++ b/net/netfilter/nf_tables_api.c
30 @@ -6879,11 +6879,12 @@ static int nft_flowtable_parse_hook(cons
31 return err;
32 }
33
34 +/* call under rcu_read_lock */
35 static const struct nf_flowtable_type *__nft_flowtable_type_get(u8 family)
36 {
37 const struct nf_flowtable_type *type;
38
39 - list_for_each_entry(type, &nf_tables_flowtables, list) {
40 + list_for_each_entry_rcu(type, &nf_tables_flowtables, list) {
41 if (family == type->family)
42 return type;
43 }
44 @@ -6895,9 +6896,13 @@ nft_flowtable_type_get(struct net *net,
45 {
46 const struct nf_flowtable_type *type;
47
48 + rcu_read_lock();
49 type = __nft_flowtable_type_get(family);
50 - if (type != NULL && try_module_get(type->owner))
51 + if (type != NULL && try_module_get(type->owner)) {
52 + rcu_read_unlock();
53 return type;
54 + }
55 + rcu_read_unlock();
56
57 lockdep_nfnl_nft_mutex_not_held();
58 #ifdef CONFIG_MODULES