backport netfilter nf_table sanitiation fixes
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
parent
4a8e848f62
commit
ad0a766ee2
@ -0,0 +1,103 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Wed, 25 May 2022 10:36:38 +0200
|
||||
Subject: [PATCH] netfilter: nf_tables: disallow non-stateful expression in
|
||||
sets earlier
|
||||
|
||||
CVE-2022-1966
|
||||
|
||||
Since 3e135cd499bf ("netfilter: nft_dynset: dynamic stateful expression
|
||||
instantiation"), it is possible to attach stateful expressions to set
|
||||
elements.
|
||||
|
||||
cd5125d8f518 ("netfilter: nf_tables: split set destruction in deactivate
|
||||
and destroy phase") introduces conditional destruction on the object to
|
||||
accomodate transaction semantics.
|
||||
|
||||
nft_expr_init() calls expr->ops->init() first, then check for
|
||||
NFT_STATEFUL_EXPR, this stills allows to initialize a non-stateful
|
||||
lookup expressions which points to a set, which might lead to UAF since
|
||||
the set is not properly detached from the set->binding for this case.
|
||||
Anyway, this combination is non-sense from nf_tables perspective.
|
||||
|
||||
This patch fixes this problem by checking for NFT_STATEFUL_EXPR before
|
||||
expr->ops->init() is called.
|
||||
|
||||
The reporter provides a KASAN splat and a poc reproducer (similar to
|
||||
those autogenerated by syzbot to report use-after-free errors). It is
|
||||
unknown to me if they are using syzbot or if they use similar automated
|
||||
tool to locate the bug that they are reporting.
|
||||
|
||||
For the record, this is the KASAN splat.
|
||||
|
||||
[ 85.431824] ==================================================================
|
||||
[ 85.432901] BUG: KASAN: use-after-free in nf_tables_bind_set+0x81b/0xa20
|
||||
[ 85.433825] Write of size 8 at addr ffff8880286f0e98 by task poc/776
|
||||
[ 85.434756]
|
||||
[ 85.434999] CPU: 1 PID: 776 Comm: poc Tainted: G W 5.18.0+ #2
|
||||
[ 85.436023] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014
|
||||
|
||||
Fixes: 0b2d8a7b638b ("netfilter: nf_tables: add helper functions for expression handling")
|
||||
Reported-and-tested-by: Aaron Adams <edg-e@nccgroup.com>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
(cherry picked from commit 520778042ccca019f3ffa136dd0ca565c486cedd net.git)
|
||||
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
|
||||
Acked-by: Andrea Righi <andrea.righi@canonical.com>
|
||||
Acked-by: Stefan Bader <stefan.bader@canonical.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
---
|
||||
net/netfilter/nf_tables_api.c | 19 ++++++++++---------
|
||||
1 file changed, 10 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
|
||||
index 2feb88ffcd81..91865dc2bcbb 100644
|
||||
--- a/net/netfilter/nf_tables_api.c
|
||||
+++ b/net/netfilter/nf_tables_api.c
|
||||
@@ -2778,27 +2778,31 @@ static struct nft_expr *nft_expr_init(const struct nft_ctx *ctx,
|
||||
|
||||
err = nf_tables_expr_parse(ctx, nla, &expr_info);
|
||||
if (err < 0)
|
||||
- goto err1;
|
||||
+ goto err_expr_parse;
|
||||
+
|
||||
+ err = -EOPNOTSUPP;
|
||||
+ if (!(expr_info.ops->type->flags & NFT_EXPR_STATEFUL))
|
||||
+ goto err_expr_stateful;
|
||||
|
||||
err = -ENOMEM;
|
||||
expr = kzalloc(expr_info.ops->size, GFP_KERNEL);
|
||||
if (expr == NULL)
|
||||
- goto err2;
|
||||
+ goto err_expr_stateful;
|
||||
|
||||
err = nf_tables_newexpr(ctx, &expr_info, expr);
|
||||
if (err < 0)
|
||||
- goto err3;
|
||||
+ goto err_expr_new;
|
||||
|
||||
return expr;
|
||||
-err3:
|
||||
+err_expr_new:
|
||||
kfree(expr);
|
||||
-err2:
|
||||
+err_expr_stateful:
|
||||
owner = expr_info.ops->type->owner;
|
||||
if (expr_info.ops->type->release_ops)
|
||||
expr_info.ops->type->release_ops(expr_info.ops);
|
||||
|
||||
module_put(owner);
|
||||
-err1:
|
||||
+err_expr_parse:
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
@@ -5318,9 +5322,6 @@ struct nft_expr *nft_set_elem_expr_alloc(const struct nft_ctx *ctx,
|
||||
return expr;
|
||||
|
||||
err = -EOPNOTSUPP;
|
||||
- if (!(expr->ops->type->flags & NFT_EXPR_STATEFUL))
|
||||
- goto err_set_elem_expr;
|
||||
-
|
||||
if (expr->ops->type->flags & NFT_EXPR_GC) {
|
||||
if (set->flags & NFT_SET_TIMEOUT)
|
||||
goto err_set_elem_expr;
|
@ -0,0 +1,78 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Fri, 27 May 2022 09:56:18 +0200
|
||||
Subject: [PATCH] netfilter: nf_tables: sanitize nft_set_desc_concat_parse()
|
||||
|
||||
BugLink: https://bugs.launchpad.net/bugs/1976363 (netfilter newset OOB write (LP: #1976363))
|
||||
|
||||
Add several sanity checks for nft_set_desc_concat_parse():
|
||||
|
||||
- validate desc->field_count not larger than desc->field_len array.
|
||||
- field length cannot be larger than desc->field_len (ie. U8_MAX)
|
||||
- total length of the concatenation cannot be larger than register array.
|
||||
|
||||
Joint work with Florian Westphal.
|
||||
|
||||
Fixes: f3a2181e16f1 ("netfilter: nf_tables: Support for sets with multiple ranged fields")
|
||||
Reported-by: <zhangziming.zzm@antgroup.com>
|
||||
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
|
||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
(cherry picked from commit fecf31ee395b0295f2d7260aa29946b7605f7c85 net.git)
|
||||
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
|
||||
Acked-by: Andrea Righi <andrea.righi@canonical.com>
|
||||
Acked-by: Stefan Bader <stefan.bader@canonical.com>
|
||||
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
|
||||
---
|
||||
net/netfilter/nf_tables_api.c | 17 +++++++++++++----
|
||||
1 file changed, 13 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
|
||||
index 91865dc2bcbb..ee4edebe6124 100644
|
||||
--- a/net/netfilter/nf_tables_api.c
|
||||
+++ b/net/netfilter/nf_tables_api.c
|
||||
@@ -4151,6 +4151,9 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr,
|
||||
u32 len;
|
||||
int err;
|
||||
|
||||
+ if (desc->field_count >= ARRAY_SIZE(desc->field_len))
|
||||
+ return -E2BIG;
|
||||
+
|
||||
err = nla_parse_nested_deprecated(tb, NFTA_SET_FIELD_MAX, attr,
|
||||
nft_concat_policy, NULL);
|
||||
if (err < 0)
|
||||
@@ -4160,9 +4163,8 @@ static int nft_set_desc_concat_parse(const struct nlattr *attr,
|
||||
return -EINVAL;
|
||||
|
||||
len = ntohl(nla_get_be32(tb[NFTA_SET_FIELD_LEN]));
|
||||
-
|
||||
- if (len * BITS_PER_BYTE / 32 > NFT_REG32_COUNT)
|
||||
- return -E2BIG;
|
||||
+ if (!len || len > U8_MAX)
|
||||
+ return -EINVAL;
|
||||
|
||||
desc->field_len[desc->field_count++] = len;
|
||||
|
||||
@@ -4173,7 +4175,8 @@ static int nft_set_desc_concat(struct nft_set_desc *desc,
|
||||
const struct nlattr *nla)
|
||||
{
|
||||
struct nlattr *attr;
|
||||
- int rem, err;
|
||||
+ u32 num_regs = 0;
|
||||
+ int rem, err, i;
|
||||
|
||||
nla_for_each_nested(attr, nla, rem) {
|
||||
if (nla_type(attr) != NFTA_LIST_ELEM)
|
||||
@@ -4184,6 +4187,12 @@ static int nft_set_desc_concat(struct nft_set_desc *desc,
|
||||
return err;
|
||||
}
|
||||
|
||||
+ for (i = 0; i < desc->field_count; i++)
|
||||
+ num_regs += DIV_ROUND_UP(desc->field_len[i], sizeof(u32));
|
||||
+
|
||||
+ if (num_regs > NFT_REG32_COUNT)
|
||||
+ return -E2BIG;
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user