kernel: patch CVE-2023-32233

Message ID 20230510122324.3303-1-arne_f@ipfire.org
State Accepted
Commit cb73ca19a6152689e130502a6d28fec5145ef288
Headers
Series kernel: patch CVE-2023-32233 |

Commit Message

Arne Fitzenreiter May 10, 2023, 12:23 p.m. UTC
  Signed-off-by: Arne Fitzenreiter <arne_f@ipfire.org>
---
 lfs/linux                                     |   3 +
 ...ter_nftables_deactivate_anonymus_set.patch | 121 ++++++++++++++++++
 2 files changed, 124 insertions(+)
 create mode 100644 src/patches/linux/linux-6.3-netfilter_nftables_deactivate_anonymus_set.patch
  

Comments

Michael Tremer May 10, 2023, 3:25 p.m. UTC | #1
Reviewed-by: Michael Tremer <michael.tremer@ipfire.org>

For some reason, nf_tables is a module on aarch64 and it is not being loaded. At least I would like to have this aligned to the other architectures. I do believe that we might have a chance to disable this entirely as we are not using it.

-Michael

> On 10 May 2023, at 13:23, Arne Fitzenreiter <arne_f@ipfire.org> wrote:
> 
> Signed-off-by: Arne Fitzenreiter <arne_f@ipfire.org>
> ---
> lfs/linux                                     |   3 +
> ...ter_nftables_deactivate_anonymus_set.patch | 121 ++++++++++++++++++
> 2 files changed, 124 insertions(+)
> create mode 100644 src/patches/linux/linux-6.3-netfilter_nftables_deactivate_anonymus_set.patch
> 
> diff --git a/lfs/linux b/lfs/linux
> index 489715424..a95c6aea4 100644
> --- a/lfs/linux
> +++ b/lfs/linux
> @@ -147,6 +147,9 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
> # Fix pmc compile dependency errors
> cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux/linux-6.0.7-platform-x86-amd-Fix-pmc-compile-dependency-errors.patch
> 
> + # Patch netfilter CVE-2023-32233
> + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux/linux-6.3-netfilter_nftables_deactivate_anonymus_set.patch
> +
> ifeq "$(BUILD_ARCH)" "aarch64"
> # Apply Arm-multiarch kernel patches.
> cd $(DIR_APP) && xzcat $(DIR_DL)/arm-multi-patches-$(ARM_PATCHES).patch.xz | patch -Np1
> diff --git a/src/patches/linux/linux-6.3-netfilter_nftables_deactivate_anonymus_set.patch b/src/patches/linux/linux-6.3-netfilter_nftables_deactivate_anonymus_set.patch
> new file mode 100644
> index 000000000..cd75de5c2
> --- /dev/null
> +++ b/src/patches/linux/linux-6.3-netfilter_nftables_deactivate_anonymus_set.patch
> @@ -0,0 +1,121 @@
> +From c1592a89942e9678f7d9c8030efa777c0d57edab Mon Sep 17 00:00:00 2001
> +From: Pablo Neira Ayuso <pablo@netfilter.org>
> +Date: Tue, 2 May 2023 10:25:24 +0200
> +Subject: 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>
> +---
> + include/net/netfilter/nf_tables.h |  1 +
> + net/netfilter/nf_tables_api.c     | 12 ++++++++++++
> + net/netfilter/nft_dynset.c        |  2 +-
> + net/netfilter/nft_lookup.c        |  2 +-
> + net/netfilter/nft_objref.c        |  2 +-
> + 5 files changed, 16 insertions(+), 3 deletions(-)
> +
> +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
> +index 3ed21d2d56590..2e24ea1d744c2 100644
> +--- a/include/net/netfilter/nf_tables.h
> ++++ b/include/net/netfilter/nf_tables.h
> +@@ -619,6 +619,7 @@ struct nft_set_binding {
> + };
> + 
> + enum nft_trans_phase;
> ++void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set);
> + void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
> +      struct nft_set_binding *binding,
> +      enum nft_trans_phase phase);
> +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
> +index 8b6c61a2196cb..59fb8320ab4d7 100644
> +--- a/net/netfilter/nf_tables_api.c
> ++++ b/net/netfilter/nf_tables_api.c
> +@@ -5127,12 +5127,24 @@ static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *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++;
> ++}
> ++EXPORT_SYMBOL_GPL(nf_tables_activate_set);
> ++
> + 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 274579b1696e0..bd19c7aec92ee 100644
> +--- a/net/netfilter/nft_dynset.c
> ++++ b/net/netfilter/nft_dynset.c
> +@@ -342,7 +342,7 @@ static void nft_dynset_activate(const struct nft_ctx *ctx,
> + {
> + 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 cecf8ab90e58f..03ef4fdaa460b 100644
> +--- a/net/netfilter/nft_lookup.c
> ++++ b/net/netfilter/nft_lookup.c
> +@@ -167,7 +167,7 @@ static void nft_lookup_activate(const struct nft_ctx *ctx,
> + {
> + 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 cb37169608bab..a48dd5b5d45b1 100644
> +--- a/net/netfilter/nft_objref.c
> ++++ b/net/netfilter/nft_objref.c
> +@@ -185,7 +185,7 @@ static void nft_objref_map_activate(const struct nft_ctx *ctx,
> + {
> + 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,
> +-- 
> +cgit 
> +
> -- 
> 2.38.1
>
  

Patch

diff --git a/lfs/linux b/lfs/linux
index 489715424..a95c6aea4 100644
--- a/lfs/linux
+++ b/lfs/linux
@@ -147,6 +147,9 @@  $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
 	# Fix pmc compile dependency errors
 	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux/linux-6.0.7-platform-x86-amd-Fix-pmc-compile-dependency-errors.patch
 
+	# Patch netfilter CVE-2023-32233
+	cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/linux/linux-6.3-netfilter_nftables_deactivate_anonymus_set.patch
+
 ifeq "$(BUILD_ARCH)" "aarch64"
 	# Apply Arm-multiarch kernel patches.
 	cd $(DIR_APP) && xzcat $(DIR_DL)/arm-multi-patches-$(ARM_PATCHES).patch.xz | patch -Np1
diff --git a/src/patches/linux/linux-6.3-netfilter_nftables_deactivate_anonymus_set.patch b/src/patches/linux/linux-6.3-netfilter_nftables_deactivate_anonymus_set.patch
new file mode 100644
index 000000000..cd75de5c2
--- /dev/null
+++ b/src/patches/linux/linux-6.3-netfilter_nftables_deactivate_anonymus_set.patch
@@ -0,0 +1,121 @@ 
+From c1592a89942e9678f7d9c8030efa777c0d57edab Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Tue, 2 May 2023 10:25:24 +0200
+Subject: 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>
+---
+ include/net/netfilter/nf_tables.h |  1 +
+ net/netfilter/nf_tables_api.c     | 12 ++++++++++++
+ net/netfilter/nft_dynset.c        |  2 +-
+ net/netfilter/nft_lookup.c        |  2 +-
+ net/netfilter/nft_objref.c        |  2 +-
+ 5 files changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
+index 3ed21d2d56590..2e24ea1d744c2 100644
+--- a/include/net/netfilter/nf_tables.h
++++ b/include/net/netfilter/nf_tables.h
+@@ -619,6 +619,7 @@ struct nft_set_binding {
+ };
+ 
+ enum nft_trans_phase;
++void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set);
+ void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
+ 			      struct nft_set_binding *binding,
+ 			      enum nft_trans_phase phase);
+diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
+index 8b6c61a2196cb..59fb8320ab4d7 100644
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -5127,12 +5127,24 @@ static void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *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++;
++}
++EXPORT_SYMBOL_GPL(nf_tables_activate_set);
++
+ 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 274579b1696e0..bd19c7aec92ee 100644
+--- a/net/netfilter/nft_dynset.c
++++ b/net/netfilter/nft_dynset.c
+@@ -342,7 +342,7 @@ static void nft_dynset_activate(const struct nft_ctx *ctx,
+ {
+ 	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 cecf8ab90e58f..03ef4fdaa460b 100644
+--- a/net/netfilter/nft_lookup.c
++++ b/net/netfilter/nft_lookup.c
+@@ -167,7 +167,7 @@ static void nft_lookup_activate(const struct nft_ctx *ctx,
+ {
+ 	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 cb37169608bab..a48dd5b5d45b1 100644
+--- a/net/netfilter/nft_objref.c
++++ b/net/netfilter/nft_objref.c
+@@ -185,7 +185,7 @@ static void nft_objref_map_activate(const struct nft_ctx *ctx,
+ {
+ 	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,
+-- 
+cgit 
+