mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 00:40:51 +07:00
netfilter: nftables: clone set element expression template
commit 4d8f9065830e526c83199186c5f56a6514f457d2 upstream.
memcpy() breaks when using connlimit in set elements. Use
nft_expr_clone() to initialize the connlimit expression list, otherwise
connlimit garbage collector crashes when walking on the list head copy.
[ 493.064656] Workqueue: events_power_efficient nft_rhash_gc [nf_tables]
[ 493.064685] RIP: 0010:find_or_evict+0x5a/0x90 [nf_conncount]
[ 493.064694] Code: 2b 43 40 83 f8 01 77 0d 48 c7 c0 f5 ff ff ff 44 39 63 3c 75 df 83 6d 18 01 48 8b 43 08 48 89 de 48 8b 13 48 8b 3d ee 2f 00 00 <48> 89 42 08 48 89 10 48 b8 00 01 00 00 00 00 ad de 48 89 03 48 83
[ 493.064699] RSP: 0018:ffffc90000417dc0 EFLAGS: 00010297
[ 493.064704] RAX: 0000000000000000 RBX: ffff888134f38410 RCX: 0000000000000000
[ 493.064708] RDX: 0000000000000000 RSI: ffff888134f38410 RDI: ffff888100060cc0
[ 493.064711] RBP: ffff88812ce594a8 R08: ffff888134f38438 R09: 00000000ebb9025c
[ 493.064714] R10: ffffffff8219f838 R11: 0000000000000017 R12: 0000000000000001
[ 493.064718] R13: ffffffff82146740 R14: ffff888134f38410 R15: 0000000000000000
[ 493.064721] FS: 0000000000000000(0000) GS:ffff88840e440000(0000) knlGS:0000000000000000
[ 493.064725] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 493.064729] CR2: 0000000000000008 CR3: 00000001330aa002 CR4: 00000000001706e0
[ 493.064733] Call Trace:
[ 493.064737] nf_conncount_gc_list+0x8f/0x150 [nf_conncount]
[ 493.064746] nft_rhash_gc+0x106/0x390 [nf_tables]
Reported-by: Laura Garcia Liebana <nevola@gmail.com>
Fixes: 4094445229
("netfilter: nf_tables: add elements with stateful expressions")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
9cbca6f62c
commit
03ee02e1db
@ -5160,6 +5160,24 @@ static void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
|
|||||||
kfree(elem);
|
kfree(elem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nft_set_elem_expr_setup(struct nft_ctx *ctx,
|
||||||
|
const struct nft_set_ext *ext,
|
||||||
|
struct nft_expr *expr)
|
||||||
|
{
|
||||||
|
struct nft_expr *elem_expr = nft_set_ext_expr(ext);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (expr == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
err = nft_expr_clone(elem_expr, expr);
|
||||||
|
if (err < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
nft_expr_destroy(ctx, expr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
||||||
const struct nlattr *attr, u32 nlmsg_flags)
|
const struct nlattr *attr, u32 nlmsg_flags)
|
||||||
{
|
{
|
||||||
@ -5362,15 +5380,17 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
|||||||
*nft_set_ext_obj(ext) = obj;
|
*nft_set_ext_obj(ext) = obj;
|
||||||
obj->use++;
|
obj->use++;
|
||||||
}
|
}
|
||||||
if (expr) {
|
|
||||||
memcpy(nft_set_ext_expr(ext), expr, expr->ops->size);
|
err = nft_set_elem_expr_setup(ctx, ext, expr);
|
||||||
kfree(expr);
|
if (err < 0)
|
||||||
expr = NULL;
|
goto err_elem_expr;
|
||||||
}
|
expr = NULL;
|
||||||
|
|
||||||
trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
|
trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set);
|
||||||
if (trans == NULL)
|
if (trans == NULL) {
|
||||||
goto err_trans;
|
err = -ENOMEM;
|
||||||
|
goto err_elem_expr;
|
||||||
|
}
|
||||||
|
|
||||||
ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
|
ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
|
||||||
err = set->ops->insert(ctx->net, set, &elem, &ext2);
|
err = set->ops->insert(ctx->net, set, &elem, &ext2);
|
||||||
@ -5414,7 +5434,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
|
|||||||
set->ops->remove(ctx->net, set, &elem);
|
set->ops->remove(ctx->net, set, &elem);
|
||||||
err_element_clash:
|
err_element_clash:
|
||||||
kfree(trans);
|
kfree(trans);
|
||||||
err_trans:
|
err_elem_expr:
|
||||||
if (obj)
|
if (obj)
|
||||||
obj->use--;
|
obj->use--;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user