]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/linux/linux-6.3-netfilter_nftables_deactivate_anonymus_set.patch
checkrootfiles: fix checks on hosts with newer grep
[people/pmueller/ipfire-2.x.git] / src / patches / linux / linux-6.3-netfilter_nftables_deactivate_anonymus_set.patch
1 From c1592a89942e9678f7d9c8030efa777c0d57edab Mon Sep 17 00:00:00 2001
2 From: Pablo Neira Ayuso <pablo@netfilter.org>
3 Date: Tue, 2 May 2023 10:25:24 +0200
4 Subject: netfilter: nf_tables: deactivate anonymous set from preparation phase
5
6 Toggle deleted anonymous sets as inactive in the next generation, so
7 users cannot perform any update on it. Clear the generation bitmask
8 in case the transaction is aborted.
9
10 The following KASAN splat shows a set element deletion for a bound
11 anonymous set that has been already removed in the same transaction.
12
13 [ 64.921510] ==================================================================
14 [ 64.923123] BUG: KASAN: wild-memory-access in nf_tables_commit+0xa24/0x1490 [nf_tables]
15 [ 64.924745] Write of size 8 at addr dead000000000122 by task test/890
16 [ 64.927903] CPU: 3 PID: 890 Comm: test Not tainted 6.3.0+ #253
17 [ 64.931120] Call Trace:
18 [ 64.932699] <TASK>
19 [ 64.934292] dump_stack_lvl+0x33/0x50
20 [ 64.935908] ? nf_tables_commit+0xa24/0x1490 [nf_tables]
21 [ 64.937551] kasan_report+0xda/0x120
22 [ 64.939186] ? nf_tables_commit+0xa24/0x1490 [nf_tables]
23 [ 64.940814] nf_tables_commit+0xa24/0x1490 [nf_tables]
24 [ 64.942452] ? __kasan_slab_alloc+0x2d/0x60
25 [ 64.944070] ? nf_tables_setelem_notify+0x190/0x190 [nf_tables]
26 [ 64.945710] ? kasan_set_track+0x21/0x30
27 [ 64.947323] nfnetlink_rcv_batch+0x709/0xd90 [nfnetlink]
28 [ 64.948898] ? nfnetlink_rcv_msg+0x480/0x480 [nfnetlink]
29
30 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
31 ---
32 include/net/netfilter/nf_tables.h | 1 +
33 net/netfilter/nf_tables_api.c | 12 ++++++++++++
34 net/netfilter/nft_dynset.c | 2 +-
35 net/netfilter/nft_lookup.c | 2 +-
36 net/netfilter/nft_objref.c | 2 +-
37 5 files changed, 16 insertions(+), 3 deletions(-)
38
39 diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
40 index 3ed21d2d56590..2e24ea1d744c2 100644
41 --- a/include/net/netfilter/nf_tables.h
42 +++ b/include/net/netfilter/nf_tables.h
43 @@ -619,6 +619,7 @@ struct nft_set_binding {
44 };
45
46 enum nft_trans_phase;
47 +void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set);
48 void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
49 struct nft_set_binding *binding,
50 enum nft_trans_phase phase);
51 diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
52 index 8b6c61a2196cb..59fb8320ab4d7 100644
53 --- a/net/netfilter/nf_tables_api.c
54 +++ b/net/netfilter/nf_tables_api.c
55 @@ -5127,12 +5127,24 @@ static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
56 }
57 }
58
59 +void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set)
60 +{
61 + if (nft_set_is_anonymous(set))
62 + nft_clear(ctx->net, set);
63 +
64 + set->use++;
65 +}
66 +EXPORT_SYMBOL_GPL(nf_tables_activate_set);
67 +
68 void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
69 struct nft_set_binding *binding,
70 enum nft_trans_phase phase)
71 {
72 switch (phase) {
73 case NFT_TRANS_PREPARE:
74 + if (nft_set_is_anonymous(set))
75 + nft_deactivate_next(ctx->net, set);
76 +
77 set->use--;
78 return;
79 case NFT_TRANS_ABORT:
80 diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
81 index 274579b1696e0..bd19c7aec92ee 100644
82 --- a/net/netfilter/nft_dynset.c
83 +++ b/net/netfilter/nft_dynset.c
84 @@ -342,7 +342,7 @@ static void nft_dynset_activate(const struct nft_ctx *ctx,
85 {
86 struct nft_dynset *priv = nft_expr_priv(expr);
87
88 - priv->set->use++;
89 + nf_tables_activate_set(ctx, priv->set);
90 }
91
92 static void nft_dynset_destroy(const struct nft_ctx *ctx,
93 diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
94 index cecf8ab90e58f..03ef4fdaa460b 100644
95 --- a/net/netfilter/nft_lookup.c
96 +++ b/net/netfilter/nft_lookup.c
97 @@ -167,7 +167,7 @@ static void nft_lookup_activate(const struct nft_ctx *ctx,
98 {
99 struct nft_lookup *priv = nft_expr_priv(expr);
100
101 - priv->set->use++;
102 + nf_tables_activate_set(ctx, priv->set);
103 }
104
105 static void nft_lookup_destroy(const struct nft_ctx *ctx,
106 diff --git a/net/netfilter/nft_objref.c b/net/netfilter/nft_objref.c
107 index cb37169608bab..a48dd5b5d45b1 100644
108 --- a/net/netfilter/nft_objref.c
109 +++ b/net/netfilter/nft_objref.c
110 @@ -185,7 +185,7 @@ static void nft_objref_map_activate(const struct nft_ctx *ctx,
111 {
112 struct nft_objref_map *priv = nft_expr_priv(expr);
113
114 - priv->set->use++;
115 + nf_tables_activate_set(ctx, priv->set);
116 }
117
118 static void nft_objref_map_destroy(const struct nft_ctx *ctx,
119 --
120 cgit
121