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