提交 dcb69fcc 编写于 作者: P Pablo Neira Ayuso 提交者: Jialin Zhang

netfilter: nf_tables: deactivate anonymous set from preparation phase

stable inclusion
from stable-v5.10.180
commit e044a24447189419c3a7ccc5fa6da7516036dc55
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I71F49
CVE: CVE-2023-32233

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=e044a24447189419c3a7ccc5fa6da7516036dc55

--------------------------------

commit c1592a89 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: NPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NLu Wei <luwei32@huawei.com>
Reviewed-by: NYue Haibing <yuehaibing@huawei.com>
Reviewed-by: NXiu Jianfeng <xiujianfeng@huawei.com>
Signed-off-by: NJialin Zhang <zhangjialin11@huawei.com>
上级 d38a530e
...@@ -507,6 +507,7 @@ struct nft_set_binding { ...@@ -507,6 +507,7 @@ struct nft_set_binding {
}; };
enum nft_trans_phase; enum nft_trans_phase;
void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set);
void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
struct nft_set_binding *binding, struct nft_set_binding *binding,
enum nft_trans_phase phase); enum nft_trans_phase phase);
......
...@@ -4479,12 +4479,24 @@ static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set, ...@@ -4479,12 +4479,24 @@ static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
} }
} }
void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set)
{
if (nft_set_is_anonymous(set))
nft_clear(ctx->net, set);
set->use++;
}
EXPORT_SYMBOL_GPL(nf_tables_activate_set);
void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set, void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
struct nft_set_binding *binding, struct nft_set_binding *binding,
enum nft_trans_phase phase) enum nft_trans_phase phase)
{ {
switch (phase) { switch (phase) {
case NFT_TRANS_PREPARE: case NFT_TRANS_PREPARE:
if (nft_set_is_anonymous(set))
nft_deactivate_next(ctx->net, set);
set->use--; set->use--;
return; return;
case NFT_TRANS_ABORT: case NFT_TRANS_ABORT:
......
...@@ -233,7 +233,7 @@ static void nft_dynset_activate(const struct nft_ctx *ctx, ...@@ -233,7 +233,7 @@ static void nft_dynset_activate(const struct nft_ctx *ctx,
{ {
struct nft_dynset *priv = nft_expr_priv(expr); struct nft_dynset *priv = nft_expr_priv(expr);
priv->set->use++; nf_tables_activate_set(ctx, priv->set);
} }
static void nft_dynset_destroy(const struct nft_ctx *ctx, static void nft_dynset_destroy(const struct nft_ctx *ctx,
......
...@@ -132,7 +132,7 @@ static void nft_lookup_activate(const struct nft_ctx *ctx, ...@@ -132,7 +132,7 @@ static void nft_lookup_activate(const struct nft_ctx *ctx,
{ {
struct nft_lookup *priv = nft_expr_priv(expr); struct nft_lookup *priv = nft_expr_priv(expr);
priv->set->use++; nf_tables_activate_set(ctx, priv->set);
} }
static void nft_lookup_destroy(const struct nft_ctx *ctx, static void nft_lookup_destroy(const struct nft_ctx *ctx,
......
...@@ -180,7 +180,7 @@ static void nft_objref_map_activate(const struct nft_ctx *ctx, ...@@ -180,7 +180,7 @@ static void nft_objref_map_activate(const struct nft_ctx *ctx,
{ {
struct nft_objref_map *priv = nft_expr_priv(expr); struct nft_objref_map *priv = nft_expr_priv(expr);
priv->set->use++; nf_tables_activate_set(ctx, priv->set);
} }
static void nft_objref_map_destroy(const struct nft_ctx *ctx, static void nft_objref_map_destroy(const struct nft_ctx *ctx,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册