]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 9 Sep 2021 14:51:51 +0000 (16:51 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 9 Sep 2021 14:51:51 +0000 (16:51 +0200)
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

queue-5.10/netfilter-nf_tables-initialize-set-before-expression-setup.patch [new file with mode: 0644]
queue-5.10/netfilter-nftables-avoid-potential-overflows-on-32bit-arches.patch [new file with mode: 0644]
queue-5.10/netfilter-nftables-clone-set-element-expression-template.patch [new file with mode: 0644]
queue-5.10/series

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 (file)
index 0000000..7b027d4
--- /dev/null
@@ -0,0 +1,124 @@
+From foo@baz Thu Sep  9 04:51:16 PM CEST 2021
+From: Florian Westphal <fw@strlen.de>
+Date: Thu,  9 Sep 2021 16:03:36 +0200
+Subject: netfilter: nf_tables: initialize set before expression setup
+To: stable@vger.kernel.org
+Cc: <netfilter-devel@vger.kernel.org>, Pablo Neira Ayuso <pablo@netfilter.org>, syzbot+ce96ca2b1d0b37c6422d@syzkaller.appspotmail.com, Florian Westphal <fw@strlen.de>
+Message-ID: <20210909140337.29707-3-fw@strlen.de>
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+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 <pablo@netfilter.org>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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 (file)
index 0000000..00f13fa
--- /dev/null
@@ -0,0 +1,84 @@
+From foo@baz Thu Sep  9 04:51:16 PM CEST 2021
+From: Florian Westphal <fw@strlen.de>
+Date: Thu,  9 Sep 2021 16:03:35 +0200
+Subject: netfilter: nftables: avoid potential overflows on 32bit arches
+To: stable@vger.kernel.org
+Cc: <netfilter-devel@vger.kernel.org>, Eric Dumazet <edumazet@google.com>, Pablo Neira Ayuso <pablo@netfilter.org>, Florian Westphal <fw@strlen.de>
+Message-ID: <20210909140337.29707-2-fw@strlen.de>
+
+From: Eric Dumazet <edumazet@google.com>
+
+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 <edumazet@google.com>
+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>
+---
+ 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 (file)
index 0000000..46d727a
--- /dev/null
@@ -0,0 +1,102 @@
+From foo@baz Thu Sep  9 04:51:16 PM CEST 2021
+From: Florian Westphal <fw@strlen.de>
+Date: Thu,  9 Sep 2021 16:03:37 +0200
+Subject: netfilter: nftables: clone set element expression template
+To: stable@vger.kernel.org
+Cc: <netfilter-devel@vger.kernel.org>, Pablo Neira Ayuso <pablo@netfilter.org>, Laura Garcia Liebana <nevola@gmail.com>, Florian Westphal <fw@strlen.de>
+Message-ID: <20210909140337.29707-4-fw@strlen.de>
+
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+
+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: 409444522976 ("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>
+---
+ 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--;
index 09a48dd7cee78ef03f392117bf726e95db40c2c8..e23a67a50e327fe4162f59dbe799c4459206890b 100644 (file)
@@ -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