|
|
dd9019 |
From 0a078bf71d41c66168b4740bee12d8f1a7d94f80 Mon Sep 17 00:00:00 2001
|
|
|
dd9019 |
From: Joe Lawrence <joe.lawrence@redhat.com>
|
|
|
dd9019 |
Date: Thu, 10 Aug 2023 15:09:04 -0400
|
|
|
dd9019 |
Subject: [KPATCH 7.9] kpatch fixes for CVE-2023-32233
|
|
|
dd9019 |
Content-type: text/plain
|
|
|
dd9019 |
|
|
|
dd9019 |
Kernels:
|
|
|
dd9019 |
3.10.0-1160.95.1.el7
|
|
|
dd9019 |
|
|
|
dd9019 |
|
|
|
dd9019 |
Changes since last build:
|
|
|
dd9019 |
[x86_64]:
|
|
|
dd9019 |
cls_u32.o: changed function: u32_set_parms.isra.21
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_delsetelem
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_newsetelem
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_set_lookup
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_set_lookup_byid
|
|
|
dd9019 |
nf_tables_api.o: changed function: nft_validate_register_store
|
|
|
dd9019 |
nft_byteorder.o: changed function: nft_byteorder_eval
|
|
|
dd9019 |
nft_dynset.o: changed function: nft_dynset_init
|
|
|
dd9019 |
nft_lookup.o: changed function: nft_lookup_init
|
|
|
dd9019 |
|
|
|
dd9019 |
[ppc64le]:
|
|
|
dd9019 |
cls_u32.o: changed function: u32_set_parms.isra.21
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_bind_check_setelem
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_delset
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_delsetelem
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_dump_set
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_getset
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_getsetelem
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_newset
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_newsetelem
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_set_lookup
|
|
|
dd9019 |
nf_tables_api.o: changed function: nf_tables_set_lookup_byid
|
|
|
dd9019 |
nf_tables_api.o: changed function: nft_add_set_elem
|
|
|
dd9019 |
nf_tables_api.o: changed function: nft_validate_register_store
|
|
|
dd9019 |
nft_byteorder.o: changed function: nft_byteorder_eval
|
|
|
dd9019 |
nft_dynset.o: changed function: nft_dynset_init
|
|
|
dd9019 |
nft_lookup.o: changed function: nft_lookup_init
|
|
|
dd9019 |
|
|
|
dd9019 |
---------------------------
|
|
|
dd9019 |
|
|
|
dd9019 |
Modifications:
|
|
|
dd9019 |
- For ppc64le, add -fno-optimize-sibling-calls attribute for
|
|
|
dd9019 |
nf_tables_api.c :: nf_tables_getsetelem()
|
|
|
dd9019 |
|
|
|
dd9019 |
commit cde71785485c5f12520ed90f93e3e2f78270a7b7
|
|
|
dd9019 |
Author: Florian Westphal <fwestpha@redhat.com>
|
|
|
dd9019 |
Date: Thu Jul 13 16:10:39 2023 +0200
|
|
|
dd9019 |
|
|
|
dd9019 |
netfilter: nf_tables: do not allow SET_ID to refer to another table
|
|
|
dd9019 |
|
|
|
dd9019 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2196159
|
|
|
dd9019 |
Upstream Status: commit 470ee20e069a6
|
|
|
dd9019 |
|
|
|
dd9019 |
Conflicts:
|
|
|
dd9019 |
net/netfilter/nf_tables_api.c
|
|
|
dd9019 |
|
|
|
dd9019 |
We lack commit 6ab3443e9e796 ("netfilter: nf_tables: pass ctx to nf_tables_expr_destroy()"),
|
|
|
dd9019 |
which added the "nft_table" pointer to struct nft_set.
|
|
|
dd9019 |
We can't easily pick this one up becaue it makes the kabi checker trip over
|
|
|
dd9019 |
the nft_set layout change, and RH_KABI_EXTEND can't be used at the structures
|
|
|
dd9019 |
end because nft_set last member is a VLA.
|
|
|
dd9019 |
|
|
|
dd9019 |
Fortunately we can work around it by changing
|
|
|
dd9019 |
"set->table" to "trans->ctx.table", we only need this check in the transaction phase.
|
|
|
dd9019 |
|
|
|
dd9019 |
commit 470ee20e069a6d05ae549f7d0ef2bdbcee6a81b2
|
|
|
dd9019 |
Author: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
|
|
|
dd9019 |
Date: Tue Aug 9 14:01:46 2022 -0300
|
|
|
dd9019 |
|
|
|
dd9019 |
netfilter: nf_tables: do not allow SET_ID to refer to another table
|
|
|
dd9019 |
|
|
|
dd9019 |
When doing lookups for sets on the same batch by using its ID, a set from a
|
|
|
dd9019 |
different table can be used.
|
|
|
dd9019 |
|
|
|
dd9019 |
Then, when the table is removed, a reference to the set may be kept after
|
|
|
dd9019 |
the set is freed, leading to a potential use-after-free.
|
|
|
dd9019 |
|
|
|
dd9019 |
When looking for sets by ID, use the table that was used for the lookup by
|
|
|
dd9019 |
name, and only return sets belonging to that same table.
|
|
|
dd9019 |
|
|
|
dd9019 |
This fixes CVE-2022-2586, also reported as ZDI-CAN-17470.
|
|
|
dd9019 |
|
|
|
dd9019 |
Reported-by: Team Orca of Sea Security (@seasecresponse)
|
|
|
dd9019 |
Fixes: 958bee14d071 ("netfilter: nf_tables: use new transaction infrastructure to handle sets")
|
|
|
dd9019 |
Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
|
|
|
dd9019 |
Cc: <stable@vger.kernel.org>
|
|
|
dd9019 |
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
dd9019 |
|
|
|
dd9019 |
Signed-off-by: Florian Westphal <fwestpha@redhat.com>
|
|
|
dd9019 |
|
|
|
dd9019 |
commit 6a38a385344448ab2f4e68e833fcf9a7e3d62128
|
|
|
dd9019 |
Author: Florian Westphal <fwestpha@redhat.com>
|
|
|
dd9019 |
Date: Thu Jul 13 16:11:38 2023 +0200
|
|
|
dd9019 |
|
|
|
dd9019 |
netfilter: nf_tables: skip deactivated anonymous sets during lookups
|
|
|
dd9019 |
|
|
|
dd9019 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2196159
|
|
|
dd9019 |
Upstream Status: RHEL7 only
|
|
|
dd9019 |
CVE: CVE-2023-32233
|
|
|
dd9019 |
|
|
|
dd9019 |
The fix for the above CVE was incomplete in *RHEL7*.
|
|
|
dd9019 |
its not enough to check if the set is scheduled for removal when
|
|
|
dd9019 |
an element is supposed to be deleted, this check needs to be done
|
|
|
dd9019 |
for all other element operations too, e.g. when an element is
|
|
|
dd9019 |
supposed to be *added* to a set.
|
|
|
dd9019 |
|
|
|
dd9019 |
Move the check to the two functions that do the set lookup.
|
|
|
dd9019 |
sets that are scheduled for removal/pending in the transaction
|
|
|
dd9019 |
are no longer found if they have the "removed" bit set.
|
|
|
dd9019 |
|
|
|
dd9019 |
Fixes: ffb7eb4b21c69 ("netfilter: nf_tables: deactivate anonymous set from preparation phase")
|
|
|
dd9019 |
Reported-by: Phil Sutter <psutter@redhat.com>
|
|
|
dd9019 |
Signed-off-by: Florian Westphal <fwestpha@redhat.com>
|
|
|
dd9019 |
|
|
|
dd9019 |
Signed-off-by: Joe Lawrence <joe.lawrence@redhat.com>
|
|
|
dd9019 |
---
|
|
|
dd9019 |
include/net/netfilter/nf_tables.h | 1 +
|
|
|
dd9019 |
net/netfilter/nf_tables_api.c | 19 ++++++++++++-------
|
|
|
dd9019 |
net/netfilter/nft_dynset.c | 1 +
|
|
|
dd9019 |
net/netfilter/nft_lookup.c | 1 +
|
|
|
dd9019 |
4 files changed, 15 insertions(+), 7 deletions(-)
|
|
|
dd9019 |
|
|
|
dd9019 |
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
|
|
|
dd9019 |
index c0fadaa475e8..f763ef31bee7 100644
|
|
|
dd9019 |
--- a/include/net/netfilter/nf_tables.h
|
|
|
dd9019 |
+++ b/include/net/netfilter/nf_tables.h
|
|
|
dd9019 |
@@ -396,6 +396,7 @@ static inline struct nft_set *nft_set_container_of(const void *priv)
|
|
|
dd9019 |
struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
|
|
|
dd9019 |
const struct nlattr *nla);
|
|
|
dd9019 |
struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
|
|
|
dd9019 |
+ const struct nft_table *table,
|
|
|
dd9019 |
const struct nlattr *nla);
|
|
|
dd9019 |
|
|
|
dd9019 |
static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
|
|
|
dd9019 |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
|
|
|
dd9019 |
index e5c639ae2e76..273130af8386 100644
|
|
|
dd9019 |
--- a/net/netfilter/nf_tables_api.c
|
|
|
dd9019 |
+++ b/net/netfilter/nf_tables_api.c
|
|
|
dd9019 |
@@ -2431,22 +2431,28 @@ struct nft_set *nf_tables_set_lookup(const struct nft_table *table,
|
|
|
dd9019 |
return ERR_PTR(-EINVAL);
|
|
|
dd9019 |
|
|
|
dd9019 |
list_for_each_entry(set, &table->sets, list) {
|
|
|
dd9019 |
- if (!nla_strcmp(nla, set->name))
|
|
|
dd9019 |
+ if (!nla_strcmp(nla, set->name) && !set->removed)
|
|
|
dd9019 |
return set;
|
|
|
dd9019 |
}
|
|
|
dd9019 |
return ERR_PTR(-ENOENT);
|
|
|
dd9019 |
}
|
|
|
dd9019 |
|
|
|
dd9019 |
struct nft_set *nf_tables_set_lookup_byid(const struct net *net,
|
|
|
dd9019 |
+ const struct nft_table *table,
|
|
|
dd9019 |
const struct nlattr *nla)
|
|
|
dd9019 |
{
|
|
|
dd9019 |
struct nft_trans *trans;
|
|
|
dd9019 |
u32 id = ntohl(nla_get_be32(nla));
|
|
|
dd9019 |
|
|
|
dd9019 |
list_for_each_entry(trans, &net->nft.commit_list, list) {
|
|
|
dd9019 |
- if (trans->msg_type == NFT_MSG_NEWSET &&
|
|
|
dd9019 |
- id == nft_trans_set_id(trans))
|
|
|
dd9019 |
- return nft_trans_set(trans);
|
|
|
dd9019 |
+ if (trans->msg_type == NFT_MSG_NEWSET) {
|
|
|
dd9019 |
+ struct nft_set *set = nft_trans_set(trans);
|
|
|
dd9019 |
+
|
|
|
dd9019 |
+ if (id == nft_trans_set_id(trans) &&
|
|
|
dd9019 |
+ trans->ctx.table == table &&
|
|
|
dd9019 |
+ !set->removed)
|
|
|
dd9019 |
+ return set;
|
|
|
dd9019 |
+ }
|
|
|
dd9019 |
}
|
|
|
dd9019 |
return ERR_PTR(-ENOENT);
|
|
|
dd9019 |
}
|
|
|
dd9019 |
@@ -3295,6 +3301,7 @@ nla_put_failure:
|
|
|
dd9019 |
return -ENOSPC;
|
|
|
dd9019 |
}
|
|
|
dd9019 |
|
|
|
dd9019 |
+__attribute__((optimize("-fno-optimize-sibling-calls")))
|
|
|
dd9019 |
static int nf_tables_getsetelem(struct sock *nlsk, struct sk_buff *skb,
|
|
|
dd9019 |
const struct nlmsghdr *nlh,
|
|
|
dd9019 |
const struct nlattr * const nla[])
|
|
|
dd9019 |
@@ -3640,6 +3647,7 @@ static int nf_tables_newsetelem(struct net *net, struct sock *nlsk,
|
|
|
dd9019 |
if (IS_ERR(set)) {
|
|
|
dd9019 |
if (nla[NFTA_SET_ELEM_LIST_SET_ID]) {
|
|
|
dd9019 |
set = nf_tables_set_lookup_byid(net,
|
|
|
dd9019 |
+ ctx.table,
|
|
|
dd9019 |
nla[NFTA_SET_ELEM_LIST_SET_ID]);
|
|
|
dd9019 |
}
|
|
|
dd9019 |
if (IS_ERR(set))
|
|
|
dd9019 |
@@ -3762,9 +3770,6 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
|
|
|
dd9019 |
if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
|
|
|
dd9019 |
return -EBUSY;
|
|
|
dd9019 |
|
|
|
dd9019 |
- if (set->removed)
|
|
|
dd9019 |
- return -ENOENT;
|
|
|
dd9019 |
-
|
|
|
dd9019 |
if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) {
|
|
|
dd9019 |
struct nft_set_dump_args args = {
|
|
|
dd9019 |
.iter = {
|
|
|
dd9019 |
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
|
|
|
dd9019 |
index 9c11a024d96d..c50dd3221fa5 100644
|
|
|
dd9019 |
--- a/net/netfilter/nft_dynset.c
|
|
|
dd9019 |
+++ b/net/netfilter/nft_dynset.c
|
|
|
dd9019 |
@@ -119,6 +119,7 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
|
|
|
dd9019 |
if (IS_ERR(set)) {
|
|
|
dd9019 |
if (tb[NFTA_DYNSET_SET_ID])
|
|
|
dd9019 |
set = nf_tables_set_lookup_byid(ctx->net,
|
|
|
dd9019 |
+ ctx->table,
|
|
|
dd9019 |
tb[NFTA_DYNSET_SET_ID]);
|
|
|
dd9019 |
if (IS_ERR(set))
|
|
|
dd9019 |
return PTR_ERR(set);
|
|
|
dd9019 |
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
|
|
|
dd9019 |
index f57f7b8f2400..7a3c09fd50ef 100644
|
|
|
dd9019 |
--- a/net/netfilter/nft_lookup.c
|
|
|
dd9019 |
+++ b/net/netfilter/nft_lookup.c
|
|
|
dd9019 |
@@ -74,6 +74,7 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
|
|
|
dd9019 |
if (IS_ERR(set)) {
|
|
|
dd9019 |
if (tb[NFTA_LOOKUP_SET_ID]) {
|
|
|
dd9019 |
set = nf_tables_set_lookup_byid(ctx->net,
|
|
|
dd9019 |
+ ctx->table,
|
|
|
dd9019 |
tb[NFTA_LOOKUP_SET_ID]);
|
|
|
dd9019 |
}
|
|
|
dd9019 |
if (IS_ERR(set))
|
|
|
dd9019 |
--
|
|
|
dd9019 |
2.41.0
|
|
|
dd9019 |
|