From bb66ee8a99f3f35a02bd1af9fa1948a3a0626a73 Mon Sep 17 00:00:00 2001 From: Ryan Sullivan 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 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 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] [ 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 Signed-off-by: Florian Westphal Signed-off-by: Lucas Zampieri Signed-off-by: Ryan Sullivan --- 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