提交 200dcf98 编写于 作者: P Pablo Neira Ayuso 提交者: Zheng Zengkai

netfilter: nf_tables: initialize set before expression setup

stable inclusion
from stable-5.10.64
commit 36983fc2f87ea3b74a33bf460c9ee7329735b7b5
bugzilla: 182256 https://gitee.com/openeuler/kernel/issues/I4EG0U

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

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

commit ad9f151e upstream.

nft_set_elem_expr_alloc() needs an initialized set if expression sets on
the NFT_EXPR_GC flag. Move set fields initialization before expression
setup.

[4512935.019450] ==================================================================
[4512935.019456] BUG: KASAN: null-ptr-deref in nft_set_elem_expr_alloc+0x84/0xd0 [nf_tables]
[4512935.019487] Read of size 8 at addr 0000000000000070 by task nft/23532
[4512935.019494] CPU: 1 PID: 23532 Comm: nft Not tainted 5.12.0-rc4+ #48
[...]
[4512935.019502] Call Trace:
[4512935.019505]  dump_stack+0x89/0xb4
[4512935.019512]  ? nft_set_elem_expr_alloc+0x84/0xd0 [nf_tables]
[4512935.019536]  ? nft_set_elem_expr_alloc+0x84/0xd0 [nf_tables]
[4512935.019560]  kasan_report.cold.12+0x5f/0xd8
[4512935.019566]  ? nft_set_elem_expr_alloc+0x84/0xd0 [nf_tables]
[4512935.019590]  nft_set_elem_expr_alloc+0x84/0xd0 [nf_tables]
[4512935.019615]  nf_tables_newset+0xc7f/0x1460 [nf_tables]

Reported-by: syzbot+ce96ca2b1d0b37c6422d@syzkaller.appspotmail.com
Fixes: 65038428 ("netfilter: nf_tables: allow to specify stateful expression in set definition")
Signed-off-by: NPablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: NFlorian Westphal <fw@strlen.de>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Acked-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NChen Jun <chenjun102@huawei.com>
Signed-off-by: NZheng Zengkai <zhengzengkai@huawei.com>
上级 b58e8178
...@@ -4280,15 +4280,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, ...@@ -4280,15 +4280,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
err = nf_tables_set_alloc_name(&ctx, set, name); err = nf_tables_set_alloc_name(&ctx, set, name);
kfree(name); kfree(name);
if (err < 0) if (err < 0)
goto err_set_alloc_name; goto err_set_name;
if (nla[NFTA_SET_EXPR]) {
expr = nft_set_elem_expr_alloc(&ctx, set, nla[NFTA_SET_EXPR]);
if (IS_ERR(expr)) {
err = PTR_ERR(expr);
goto err_set_alloc_name;
}
}
udata = NULL; udata = NULL;
if (udlen) { if (udlen) {
...@@ -4299,21 +4291,19 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, ...@@ -4299,21 +4291,19 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
INIT_LIST_HEAD(&set->bindings); INIT_LIST_HEAD(&set->bindings);
set->table = table; set->table = table;
write_pnet(&set->net, net); write_pnet(&set->net, net);
set->ops = ops; set->ops = ops;
set->ktype = ktype; set->ktype = ktype;
set->klen = desc.klen; set->klen = desc.klen;
set->dtype = dtype; set->dtype = dtype;
set->objtype = objtype; set->objtype = objtype;
set->dlen = desc.dlen; set->dlen = desc.dlen;
set->expr = expr;
set->flags = flags; set->flags = flags;
set->size = desc.size; set->size = desc.size;
set->policy = policy; set->policy = policy;
set->udlen = udlen; set->udlen = udlen;
set->udata = udata; set->udata = udata;
set->timeout = timeout; set->timeout = timeout;
set->gc_int = gc_int; set->gc_int = gc_int;
set->handle = nf_tables_alloc_handle(table);
set->field_count = desc.field_count; set->field_count = desc.field_count;
for (i = 0; i < desc.field_count; i++) for (i = 0; i < desc.field_count; i++)
...@@ -4323,20 +4313,32 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk, ...@@ -4323,20 +4313,32 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
if (err < 0) if (err < 0)
goto err_set_init; goto err_set_init;
if (nla[NFTA_SET_EXPR]) {
expr = nft_set_elem_expr_alloc(&ctx, set, nla[NFTA_SET_EXPR]);
if (IS_ERR(expr)) {
err = PTR_ERR(expr);
goto err_set_expr_alloc;
}
set->expr = expr;
}
set->handle = nf_tables_alloc_handle(table);
err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set); err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
if (err < 0) if (err < 0)
goto err_set_trans; goto err_set_expr_alloc;
list_add_tail_rcu(&set->list, &table->sets); list_add_tail_rcu(&set->list, &table->sets);
table->use++; table->use++;
return 0; return 0;
err_set_trans: err_set_expr_alloc:
if (set->expr)
nft_expr_destroy(&ctx, set->expr);
ops->destroy(set); ops->destroy(set);
err_set_init: err_set_init:
if (expr)
nft_expr_destroy(&ctx, expr);
err_set_alloc_name:
kfree(set->name); kfree(set->name);
err_set_name: err_set_name:
kvfree(set); kvfree(set);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册