Skip to content

Commit 4507918

Browse files
ummakynesgregkh
authored andcommitted
netfilter: nf_tables: deactivate anonymous set from preparation phase
commit c1592a8 upstream. Toggle deleted anonymous sets as inactive in the next generation, so users cannot perform any update on it. Clear the generation bitmask in case the transaction is aborted. The following KASAN splat shows a set element deletion for a bound anonymous set that has been already removed in the same transaction. [ 64.921510] ================================================================== [ 64.923123] BUG: KASAN: wild-memory-access in nf_tables_commit+0xa24/0x1490 [nf_tables] [ 64.924745] Write of size 8 at addr dead000000000122 by task test/890 [ 64.927903] CPU: 3 PID: 890 Comm: test Not tainted 6.3.0+ #253 [ 64.931120] Call Trace: [ 64.932699] <TASK> [ 64.934292] dump_stack_lvl+0x33/0x50 [ 64.935908] ? nf_tables_commit+0xa24/0x1490 [nf_tables] [ 64.937551] kasan_report+0xda/0x120 [ 64.939186] ? nf_tables_commit+0xa24/0x1490 [nf_tables] [ 64.940814] nf_tables_commit+0xa24/0x1490 [nf_tables] [ 64.942452] ? __kasan_slab_alloc+0x2d/0x60 [ 64.944070] ? nf_tables_setelem_notify+0x190/0x190 [nf_tables] [ 64.945710] ? kasan_set_track+0x21/0x30 [ 64.947323] nfnetlink_rcv_batch+0x709/0xd90 [nfnetlink] [ 64.948898] ? nfnetlink_rcv_msg+0x480/0x480 [nfnetlink] Signed-off-by: Pablo Neira Ayuso <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 1887a4f commit 4507918

File tree

5 files changed

+16
-3
lines changed

5 files changed

+16
-3
lines changed

include/net/netfilter/nf_tables.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ struct nft_set_binding {
614614
};
615615

616616
enum nft_trans_phase;
617+
void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set);
617618
void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
618619
struct nft_set_binding *binding,
619620
enum nft_trans_phase phase);

net/netfilter/nf_tables_api.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4936,12 +4936,24 @@ static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
49364936
}
49374937
}
49384938

4939+
void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set)
4940+
{
4941+
if (nft_set_is_anonymous(set))
4942+
nft_clear(ctx->net, set);
4943+
4944+
set->use++;
4945+
}
4946+
EXPORT_SYMBOL_GPL(nf_tables_activate_set);
4947+
49394948
void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
49404949
struct nft_set_binding *binding,
49414950
enum nft_trans_phase phase)
49424951
{
49434952
switch (phase) {
49444953
case NFT_TRANS_PREPARE:
4954+
if (nft_set_is_anonymous(set))
4955+
nft_deactivate_next(ctx->net, set);
4956+
49454957
set->use--;
49464958
return;
49474959
case NFT_TRANS_ABORT:

net/netfilter/nft_dynset.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ static void nft_dynset_activate(const struct nft_ctx *ctx,
342342
{
343343
struct nft_dynset *priv = nft_expr_priv(expr);
344344

345-
priv->set->use++;
345+
nf_tables_activate_set(ctx, priv->set);
346346
}
347347

348348
static void nft_dynset_destroy(const struct nft_ctx *ctx,

net/netfilter/nft_lookup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ static void nft_lookup_activate(const struct nft_ctx *ctx,
167167
{
168168
struct nft_lookup *priv = nft_expr_priv(expr);
169169

170-
priv->set->use++;
170+
nf_tables_activate_set(ctx, priv->set);
171171
}
172172

173173
static void nft_lookup_destroy(const struct nft_ctx *ctx,

net/netfilter/nft_objref.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ static void nft_objref_map_activate(const struct nft_ctx *ctx,
184184
{
185185
struct nft_objref_map *priv = nft_expr_priv(expr);
186186

187-
priv->set->use++;
187+
nf_tables_activate_set(ctx, priv->set);
188188
}
189189

190190
static void nft_objref_map_destroy(const struct nft_ctx *ctx,

0 commit comments

Comments
 (0)