Blame SOURCES/CVE-2023-32233-full2.patch

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