From: Greg Kroah-Hartman Date: Thu, 9 Sep 2021 14:51:51 +0000 (+0200) Subject: 5.10-stable patches X-Git-Tag: v5.4.145~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b680743b6b00ce7d62bd986cf99ff1734c350d2b;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: netfilter-nf_tables-initialize-set-before-expression-setup.patch netfilter-nftables-avoid-potential-overflows-on-32bit-arches.patch netfilter-nftables-clone-set-element-expression-template.patch --- diff --git a/queue-5.10/netfilter-nf_tables-initialize-set-before-expression-setup.patch b/queue-5.10/netfilter-nf_tables-initialize-set-before-expression-setup.patch new file mode 100644 index 00000000000..7b027d40867 --- /dev/null +++ b/queue-5.10/netfilter-nf_tables-initialize-set-before-expression-setup.patch @@ -0,0 +1,124 @@ +From foo@baz Thu Sep 9 04:51:16 PM CEST 2021 +From: Florian Westphal +Date: Thu, 9 Sep 2021 16:03:36 +0200 +Subject: netfilter: nf_tables: initialize set before expression setup +To: stable@vger.kernel.org +Cc: , Pablo Neira Ayuso , syzbot+ce96ca2b1d0b37c6422d@syzkaller.appspotmail.com, Florian Westphal +Message-ID: <20210909140337.29707-3-fw@strlen.de> + +From: Pablo Neira Ayuso + +commit ad9f151e560b016b6ad3280b48e42fa11e1a5440 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: 65038428b2c6 ("netfilter: nf_tables: allow to specify stateful expression in set definition") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal +Signed-off-by: Greg Kroah-Hartman +--- + net/netfilter/nf_tables_api.c | 46 +++++++++++++++++++++--------------------- + 1 file changed, 24 insertions(+), 22 deletions(-) + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -4280,15 +4280,7 @@ static int nf_tables_newset(struct net * + err = nf_tables_set_alloc_name(&ctx, set, name); + kfree(name); + if (err < 0) +- goto err_set_alloc_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; +- } +- } ++ goto err_set_name; + + udata = NULL; + if (udlen) { +@@ -4299,21 +4291,19 @@ static int nf_tables_newset(struct net * + INIT_LIST_HEAD(&set->bindings); + set->table = table; + write_pnet(&set->net, net); +- set->ops = ops; ++ set->ops = ops; + set->ktype = ktype; +- set->klen = desc.klen; ++ set->klen = desc.klen; + set->dtype = dtype; + set->objtype = objtype; +- set->dlen = desc.dlen; +- set->expr = expr; ++ set->dlen = desc.dlen; + set->flags = flags; +- set->size = desc.size; ++ set->size = desc.size; + set->policy = policy; +- set->udlen = udlen; +- set->udata = udata; ++ set->udlen = udlen; ++ set->udata = udata; + set->timeout = timeout; + set->gc_int = gc_int; +- set->handle = nf_tables_alloc_handle(table); + + set->field_count = desc.field_count; + for (i = 0; i < desc.field_count; i++) +@@ -4323,20 +4313,32 @@ static int nf_tables_newset(struct net * + if (err < 0) + 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); + if (err < 0) +- goto err_set_trans; ++ goto err_set_expr_alloc; + + list_add_tail_rcu(&set->list, &table->sets); + table->use++; + return 0; + +-err_set_trans: ++err_set_expr_alloc: ++ if (set->expr) ++ nft_expr_destroy(&ctx, set->expr); ++ + ops->destroy(set); + err_set_init: +- if (expr) +- nft_expr_destroy(&ctx, expr); +-err_set_alloc_name: + kfree(set->name); + err_set_name: + kvfree(set); diff --git a/queue-5.10/netfilter-nftables-avoid-potential-overflows-on-32bit-arches.patch b/queue-5.10/netfilter-nftables-avoid-potential-overflows-on-32bit-arches.patch new file mode 100644 index 00000000000..00f13faa919 --- /dev/null +++ b/queue-5.10/netfilter-nftables-avoid-potential-overflows-on-32bit-arches.patch @@ -0,0 +1,84 @@ +From foo@baz Thu Sep 9 04:51:16 PM CEST 2021 +From: Florian Westphal +Date: Thu, 9 Sep 2021 16:03:35 +0200 +Subject: netfilter: nftables: avoid potential overflows on 32bit arches +To: stable@vger.kernel.org +Cc: , Eric Dumazet , Pablo Neira Ayuso , Florian Westphal +Message-ID: <20210909140337.29707-2-fw@strlen.de> + +From: Eric Dumazet + +commit 6c8774a94e6ad26f29ef103c8671f55c255c6201 upstream. + +User space could ask for very large hash tables, we need to make sure +our size computations wont overflow. + +nf_tables_newset() needs to double check the u64 size +will fit into size_t field. + +Fixes: 0ed6389c483d ("netfilter: nf_tables: rename set implementations") +Signed-off-by: Eric Dumazet +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal +Signed-off-by: Greg Kroah-Hartman +--- + net/netfilter/nf_tables_api.c | 7 +++++-- + net/netfilter/nft_set_hash.c | 10 +++++----- + 2 files changed, 10 insertions(+), 7 deletions(-) + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -4115,6 +4115,7 @@ static int nf_tables_newset(struct net * + struct nft_table *table; + struct nft_set *set; + struct nft_ctx ctx; ++ size_t alloc_size; + char *name; + u64 size; + u64 timeout; +@@ -4263,8 +4264,10 @@ static int nf_tables_newset(struct net * + size = 0; + if (ops->privsize != NULL) + size = ops->privsize(nla, &desc); +- +- set = kvzalloc(sizeof(*set) + size + udlen, GFP_KERNEL); ++ alloc_size = sizeof(*set) + size + udlen; ++ if (alloc_size < size) ++ return -ENOMEM; ++ set = kvzalloc(alloc_size, GFP_KERNEL); + if (!set) + return -ENOMEM; + +--- a/net/netfilter/nft_set_hash.c ++++ b/net/netfilter/nft_set_hash.c +@@ -604,7 +604,7 @@ static u64 nft_hash_privsize(const struc + const struct nft_set_desc *desc) + { + return sizeof(struct nft_hash) + +- nft_hash_buckets(desc->size) * sizeof(struct hlist_head); ++ (u64)nft_hash_buckets(desc->size) * sizeof(struct hlist_head); + } + + static int nft_hash_init(const struct nft_set *set, +@@ -644,8 +644,8 @@ static bool nft_hash_estimate(const stru + return false; + + est->size = sizeof(struct nft_hash) + +- nft_hash_buckets(desc->size) * sizeof(struct hlist_head) + +- desc->size * sizeof(struct nft_hash_elem); ++ (u64)nft_hash_buckets(desc->size) * sizeof(struct hlist_head) + ++ (u64)desc->size * sizeof(struct nft_hash_elem); + est->lookup = NFT_SET_CLASS_O_1; + est->space = NFT_SET_CLASS_O_N; + +@@ -662,8 +662,8 @@ static bool nft_hash_fast_estimate(const + return false; + + est->size = sizeof(struct nft_hash) + +- nft_hash_buckets(desc->size) * sizeof(struct hlist_head) + +- desc->size * sizeof(struct nft_hash_elem); ++ (u64)nft_hash_buckets(desc->size) * sizeof(struct hlist_head) + ++ (u64)desc->size * sizeof(struct nft_hash_elem); + est->lookup = NFT_SET_CLASS_O_1; + est->space = NFT_SET_CLASS_O_N; + diff --git a/queue-5.10/netfilter-nftables-clone-set-element-expression-template.patch b/queue-5.10/netfilter-nftables-clone-set-element-expression-template.patch new file mode 100644 index 00000000000..46d727a773c --- /dev/null +++ b/queue-5.10/netfilter-nftables-clone-set-element-expression-template.patch @@ -0,0 +1,102 @@ +From foo@baz Thu Sep 9 04:51:16 PM CEST 2021 +From: Florian Westphal +Date: Thu, 9 Sep 2021 16:03:37 +0200 +Subject: netfilter: nftables: clone set element expression template +To: stable@vger.kernel.org +Cc: , Pablo Neira Ayuso , Laura Garcia Liebana , Florian Westphal +Message-ID: <20210909140337.29707-4-fw@strlen.de> + +From: Pablo Neira Ayuso + +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 +Fixes: 409444522976 ("netfilter: nf_tables: add elements with stateful expressions") +Signed-off-by: Pablo Neira Ayuso +Signed-off-by: Florian Westphal +Signed-off-by: Greg Kroah-Hartman +--- + net/netfilter/nf_tables_api.c | 36 ++++++++++++++++++++++++++++-------- + 1 file changed, 28 insertions(+), 8 deletions(-) + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -5150,6 +5150,24 @@ static void nf_tables_set_elem_destroy(c + 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, + const struct nlattr *attr, u32 nlmsg_flags) + { +@@ -5352,15 +5370,17 @@ static int nft_add_set_elem(struct nft_c + *nft_set_ext_obj(ext) = obj; + obj->use++; + } +- if (expr) { +- memcpy(nft_set_ext_expr(ext), expr, expr->ops->size); +- kfree(expr); +- expr = NULL; +- } ++ ++ err = nft_set_elem_expr_setup(ctx, ext, expr); ++ if (err < 0) ++ goto err_elem_expr; ++ expr = NULL; + + trans = nft_trans_elem_alloc(ctx, NFT_MSG_NEWSETELEM, set); +- if (trans == NULL) +- goto err_trans; ++ if (trans == NULL) { ++ err = -ENOMEM; ++ goto err_elem_expr; ++ } + + ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK; + err = set->ops->insert(ctx->net, set, &elem, &ext2); +@@ -5404,7 +5424,7 @@ err_set_full: + set->ops->remove(ctx->net, set, &elem); + err_element_clash: + kfree(trans); +-err_trans: ++err_elem_expr: + if (obj) + obj->use--; + diff --git a/queue-5.10/series b/queue-5.10/series index 09a48dd7cee..e23a67a50e3 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -10,3 +10,6 @@ revert-r8169-avoid-link-up-interrupt-issue-on-rtl8106e-if-user-enables-aspm.patc x86-events-amd-iommu-fix-invalid-perf-result-due-to-iommu-pmc-power-gating.patch blk-mq-fix-kernel-panic-during-iterating-over-flush-request.patch blk-mq-fix-is_flush_rq.patch +netfilter-nftables-avoid-potential-overflows-on-32bit-arches.patch +netfilter-nf_tables-initialize-set-before-expression-setup.patch +netfilter-nftables-clone-set-element-expression-template.patch