Blob Blame History Raw
From bb66ee8a99f3f35a02bd1af9fa1948a3a0626a73 Mon Sep 17 00:00:00 2001
From: Ryan Sullivan <rysulliv@redhat.com>
Date: Mon, 22 May 2023 11:02:17 -0400
Subject: [KPATCH CVE-2023-32233] kpatch fixes for CVE-2023-32233


Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-8/-/merge_requests/106
Approved-by: Yannick Cote (@ycote1)
Approved-by: Joe Lawrence (@joe.lawrence)
Kernels:
4.18.0-477.10.1.el8_8

Changes since last build:
[x86_64]:
nf_tables_api.o: changed function: nf_tables_deactivate_set
nf_tables_api.o: changed function: nf_tables_fill_chain_info.isra.53
nf_tables_api.o: changed function: nf_tables_newrule
nf_tables_api.o: new function: __list_del_entry
nf_tables_api.o: new function: nf_tables_activate_set
nf_tables_api.o: new function: nla_put_string
nft_dynset.o: changed function: nft_dynset_activate
nft_lookup.o: changed function: nft_lookup_activate
nft_objref.o: changed function: nft_objref_map_activate

[ppc64le]:
nf_tables_api.o: changed function: nf_tables_deactivate_set
nf_tables_api.o: new function: nf_tables_activate_set
nft_dynset.o: changed function: nft_dynset_activate
nft_lookup.o: changed function: nft_lookup_activate
nft_objref.o: changed function: nft_objref_map_activate

---------------------------

Modifications:
Removes prototype definition of nf_tables_activate_set() from
nf_tables.h and moves it into the affected files above when it is
called, also adds the optimization attribute
"-fno-optimize-sibling-calls" to the nf_tables_deactivate_set function

commit 50c9311832bfa1e4f3a3800819d8e292d8bf7266
Author: Florian Westphal <fwestpha@redhat.com>
Date:   Wed May 10 13:20:40 2023 +0200

    netfilter: nf_tables: deactivate anonymous set from preparation phase

    Bugzilla: https://bugzilla.redhat.com/2196147
    CVE: CVE-2023-32233
    Y-Commit: 4238c2276fd879575b7599c349dafe24fbf2602b

    O-Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2196148
    Upstream Status: commit c1592a89942e9
    O-CVE: CVE-2023-32233

    commit c1592a89942e9678f7d9c8030efa777c0d57edab
    Author: Pablo Neira Ayuso <pablo@netfilter.org>
    Date:   Tue May 2 10:25:24 2023 +0200

        netfilter: nf_tables: deactivate anonymous set from preparation phase

        Toggle deleted anonymous sets as inactive in the next generation, so
        users cannot perform any update on it. Clear the generation bitmask
        in case the transaction is aborted.

        The following KASAN splat shows a set element deletion for a bound
        anonymous set that has been already removed in the same transaction.

        [   64.921510] ==================================================================
        [   64.923123] BUG: KASAN: wild-memory-access in nf_tables_commit+0xa24/0x1490 [nf_tables]
        [   64.924745] Write of size 8 at addr dead000000000122 by task test/890
        [   64.927903] CPU: 3 PID: 890 Comm: test Not tainted 6.3.0+ #253
        [   64.931120] Call Trace:
        [   64.932699]  <TASK>
        [   64.934292]  dump_stack_lvl+0x33/0x50
        [   64.935908]  ? nf_tables_commit+0xa24/0x1490 [nf_tables]
        [   64.937551]  kasan_report+0xda/0x120
        [   64.939186]  ? nf_tables_commit+0xa24/0x1490 [nf_tables]
        [   64.940814]  nf_tables_commit+0xa24/0x1490 [nf_tables]
        [   64.942452]  ? __kasan_slab_alloc+0x2d/0x60
        [   64.944070]  ? nf_tables_setelem_notify+0x190/0x190 [nf_tables]
        [   64.945710]  ? kasan_set_track+0x21/0x30
        [   64.947323]  nfnetlink_rcv_batch+0x709/0xd90 [nfnetlink]
        [   64.948898]  ? nfnetlink_rcv_msg+0x480/0x480 [nfnetlink]

        Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

    Signed-off-by: Florian Westphal <fwestpha@redhat.com>
    Signed-off-by: Lucas Zampieri <lzampier@redhat.com>

Signed-off-by: Ryan Sullivan <rysulliv@redhat.com>
---
 net/netfilter/nf_tables_api.c | 12 ++++++++++++
 net/netfilter/nft_dynset.c    |  3 ++-
 net/netfilter/nft_lookup.c    |  3 ++-
 net/netfilter/nft_objref.c    |  3 ++-
 4 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 19044ada1789..80c30400f252 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -4434,12 +4434,24 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
 }
 EXPORT_SYMBOL_GPL(nf_tables_unbind_set);
 
+void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set)
+{
+	if (nft_set_is_anonymous(set))
+		nft_clear(ctx->net, set);
+
+	set->use++;
+}
+
+__attribute__((optimize("-fno-optimize-sibling-calls")))
 void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
 			      struct nft_set_binding *binding,
 			      enum nft_trans_phase phase)
 {
 	switch (phase) {
 	case NFT_TRANS_PREPARE:
+		if (nft_set_is_anonymous(set))
+			nft_deactivate_next(ctx->net, set);
+
 		set->use--;
 		return;
 	case NFT_TRANS_ABORT:
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
index 4eff0955e533..1549aef8449f 100644
--- a/net/netfilter/nft_dynset.c
+++ b/net/netfilter/nft_dynset.c
@@ -335,12 +335,13 @@ static void nft_dynset_deactivate(const struct nft_ctx *ctx,
 	nf_tables_deactivate_set(ctx, priv->set, &priv->binding, phase);
 }
 
+void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set); // CVE-2023-32233
 static void nft_dynset_activate(const struct nft_ctx *ctx,
 				const struct nft_expr *expr)
 {
 	struct nft_dynset *priv = nft_expr_priv(expr);
 
-	priv->set->use++;
+	nf_tables_activate_set(ctx, priv->set);
 }
 
 static void nft_dynset_destroy(const struct nft_ctx *ctx,
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
index a38a1ea9b6b4..5683e92d2eba 100644
--- a/net/netfilter/nft_lookup.c
+++ b/net/netfilter/nft_lookup.c
@@ -130,12 +130,13 @@ static void nft_lookup_deactivate(const struct nft_ctx *ctx,
 	nf_tables_deactivate_set(ctx, priv->set, &priv->binding, phase);
 }
 
+void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set); // CVE-2023-32233
 static void nft_lookup_activate(const struct nft_ctx *ctx,
 				const struct nft_expr *expr)
 {
 	struct nft_lookup *priv = nft_expr_priv(expr);
 
-	priv->set->use++;
+	nf_tables_activate_set(ctx, priv->set);
 }
 
 static void nft_lookup_destroy(const struct nft_ctx *ctx,
diff --git a/net/netfilter/nft_objref.c b/net/netfilter/nft_objref.c
index 8dfa798ea683..698c48b4af5a 100644
--- a/net/netfilter/nft_objref.c
+++ b/net/netfilter/nft_objref.c
@@ -178,12 +178,13 @@ static void nft_objref_map_deactivate(const struct nft_ctx *ctx,
 	nf_tables_deactivate_set(ctx, priv->set, &priv->binding, phase);
 }
 
+void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set); // CVE-2023-32233
 static void nft_objref_map_activate(const struct nft_ctx *ctx,
 				    const struct nft_expr *expr)
 {
 	struct nft_objref_map *priv = nft_expr_priv(expr);
 
-	priv->set->use++;
+	nf_tables_activate_set(ctx, priv->set);
 }
 
 static void nft_objref_map_destroy(const struct nft_ctx *ctx,
-- 
2.39.2