|
|
c5c6e7 |
From 7972a497548bcdfc7f3b6f24a1fd5e4b0e008fff Mon Sep 17 00:00:00 2001
|
|
|
c5c6e7 |
From: Ryan Sullivan <rysulliv@redhat.com>
|
|
|
c5c6e7 |
Date: Thu, 15 Jun 2023 10:43:28 -0400
|
|
|
c5c6e7 |
Subject: [KPATCH CVE-2023-32233] kpatch fixes for CVE-2023-32233
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
Kernels:
|
|
|
c5c6e7 |
3.10.0-1160.81.1.el7
|
|
|
c5c6e7 |
3.10.0-1160.83.1.el7
|
|
|
c5c6e7 |
3.10.0-1160.88.1.el7
|
|
|
c5c6e7 |
3.10.0-1160.90.1.el7
|
|
|
c5c6e7 |
3.10.0-1160.92.1.el7
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
Kpatch-MR: https://gitlab.com/redhat/prdsc/rhel/src/kpatch/rhel-7/-/merge_requests/54
|
|
|
c5c6e7 |
Approved-by: Yannick Cote (@ycote1)
|
|
|
c5c6e7 |
Approved-by: Joe Lawrence (@joe.lawrence)
|
|
|
c5c6e7 |
Changes since last build:
|
|
|
c5c6e7 |
[x86_64]:
|
|
|
c5c6e7 |
l2cap_core.o: changed function: l2cap_data_channel
|
|
|
c5c6e7 |
l2cap_core.o: changed function: l2cap_rx_state_recv
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: __nf_tables_abort
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nf_tables_delsetelem
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nf_tables_newset
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nft_delrule
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nft_set_destroy
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nft_validate_register_store
|
|
|
c5c6e7 |
nf_tables_api.o: new function: nf_tables_activate_set
|
|
|
c5c6e7 |
nf_tables_api.o: new function: nf_tables_deactivate_set
|
|
|
c5c6e7 |
nf_tables_api.o: new function: nft_rule_expr_deactivate
|
|
|
c5c6e7 |
nft_dynset.o: new function: klp_is_nft_dynset
|
|
|
c5c6e7 |
nft_dynset.o: new function: nft_dynset_activate
|
|
|
c5c6e7 |
nft_dynset.o: new function: nft_dynset_deactivate
|
|
|
c5c6e7 |
nft_lookup.o: new function: klp_is_nft_lookup
|
|
|
c5c6e7 |
nft_lookup.o: new function: nft_lookup_activate
|
|
|
c5c6e7 |
nft_lookup.o: new function: nft_lookup_deactivate
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
[ppc64le]:
|
|
|
c5c6e7 |
l2cap_core.o: changed function: l2cap_data_channel
|
|
|
c5c6e7 |
l2cap_core.o: changed function: l2cap_rx_state_recv
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: __nf_tables_abort
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nf_tables_bind_check_setelem
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nf_tables_bind_set
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nf_tables_commit
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nf_tables_delrule
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nf_tables_delsetelem
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nf_tables_newset
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nf_tables_unbind_set
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nft_add_set_elem
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nft_delrule_by_chain
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nft_unregister_afinfo
|
|
|
c5c6e7 |
nf_tables_api.o: changed function: nft_validate_register_store
|
|
|
c5c6e7 |
nf_tables_api.o: new function: nf_tables_activate_set
|
|
|
c5c6e7 |
nf_tables_api.o: new function: nf_tables_deactivate_set
|
|
|
c5c6e7 |
nft_dynset.o: new function: klp_is_nft_dynset
|
|
|
c5c6e7 |
nft_dynset.o: new function: nft_dynset_activate
|
|
|
c5c6e7 |
nft_dynset.o: new function: nft_dynset_deactivate
|
|
|
c5c6e7 |
nft_lookup.o: new function: klp_is_nft_lookup
|
|
|
c5c6e7 |
nft_lookup.o: new function: nft_lookup_activate
|
|
|
c5c6e7 |
nft_lookup.o: new function: nft_lookup_deactivate
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
---------------------------
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
Modifications:
|
|
|
c5c6e7 |
- Removes prototype definitions of nf_tables_activate_set() and
|
|
|
c5c6e7 |
nf_tables_deactivate_set() from nf_tables.h and moves them into the
|
|
|
c5c6e7 |
affected files above when they are called
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
- Adds optimization attribute "-fno-optimize-sibling-calls" to the
|
|
|
c5c6e7 |
nf_tables_deactivate_set()
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
- Removes definitions/edits of the policy and removed fields from the
|
|
|
c5c6e7 |
nft_set struct instead using a shadow variable
|
|
|
c5c6e7 |
(ID = KLP_CVE_2023_32233), created in nf_tables_newset() and
|
|
|
c5c6e7 |
destroyed in nft_set_destroy()
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
- Removes .activate and .deactivate from nft_(dynset/lookup)_ops and
|
|
|
c5c6e7 |
instead changes nft_rule_expr_(activate/deactivate) to directly call
|
|
|
c5c6e7 |
activate and deactivate functions from within them
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
commit ffb7eb4b21c69f2b5e084c85b37eb033544e3fc9
|
|
|
c5c6e7 |
Author: Florian Westphal <fwestpha@redhat.com>
|
|
|
c5c6e7 |
Date: Tue May 16 13:34:35 2023 +0200
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
netfilter: nf_tables: deactivate anonymous set from preparation phase
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2196159
|
|
|
c5c6e7 |
Upstream Status: commit c1592a89942e9
|
|
|
c5c6e7 |
CVE: CVE-2023-32233
|
|
|
c5c6e7 |
Conflicts: everywhere
|
|
|
c5c6e7 |
Tested: nftables v0.8 shell/py tests
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
A rule like
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
ip saddr { 1.2.3.4, 5.6.7.8 } accept
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
consists of multiple expressions and a set (the part in { }).
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
This set only has a auto-assigned name "__set%d" hidden from
|
|
|
c5c6e7 |
userspace view, but its still internally referenceable this way.
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
Such "anonymous" sets are owned by the rule that use it.
|
|
|
c5c6e7 |
Rule deletion auto-removes the set as well.
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
Unfortunately userspace can craft a transaction that first
|
|
|
c5c6e7 |
deletes the rule and then attempts an operation on the anon
|
|
|
c5c6e7 |
set, such as deleting it or deleting an element from the set.
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
Upstream patch uses existing delete/activate callbacks to disable
|
|
|
c5c6e7 |
the set in the new generation (the "preview" of the future ruleset).
|
|
|
c5c6e7 |
This makes such attempt at (re)using the set fail because the set
|
|
|
c5c6e7 |
won't be visible anymore.
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
In RHEL7 we cannot mark the set as inactive in next generation
|
|
|
c5c6e7 |
because neither sets nor set elements have such a generation bit mask.
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
This backport adds minimal bits from
|
|
|
c5c6e7 |
408070d6ee3490 "netfilter: nf_tables: add nft_set_is_anonymous() helper"
|
|
|
c5c6e7 |
bb7b40aecbf778 "netfilter: nf_tables: bogus EBUSY in chain deletions"
|
|
|
c5c6e7 |
cd5125d8f51882 "netfilter: nf_tables: split set destruction in deactivate and destroy phase"
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
for the necessary infrastructure to mark anon sets as
|
|
|
c5c6e7 |
"to be removed" from transaction preparation phase.
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
Introduce an explicit "removed" bit flag that is set once the nft_lookup
|
|
|
c5c6e7 |
or dynset expression referencing an anonymous set gets scheduled for
|
|
|
c5c6e7 |
removal in the transaction phase.
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
This can then be detected in a subsequent DELSETEM attempt and
|
|
|
c5c6e7 |
an error can be returned.
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
commit c1592a89942e9678f7d9c8030efa777c0d57edab
|
|
|
c5c6e7 |
Author: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
c5c6e7 |
Date: Tue May 2 10:25:24 2023 +0200
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
netfilter: nf_tables: deactivate anonymous set from preparation phase
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
Toggle deleted anonymous sets as inactive in the next generation, so
|
|
|
c5c6e7 |
users cannot perform any update on it. Clear the generation bitmask
|
|
|
c5c6e7 |
in case the transaction is aborted.
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
The following KASAN splat shows a set element deletion for a bound
|
|
|
c5c6e7 |
anonymous set that has been already removed in the same transaction.
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
[ 64.921510] ==================================================================
|
|
|
c5c6e7 |
[ 64.923123] BUG: KASAN: wild-memory-access in nf_tables_commit+0xa24/0x1490 [nf_tables]
|
|
|
c5c6e7 |
[ 64.924745] Write of size 8 at addr dead000000000122 by task test/890
|
|
|
c5c6e7 |
[ 64.927903] CPU: 3 PID: 890 Comm: test Not tainted 6.3.0+ #253
|
|
|
c5c6e7 |
[ 64.931120] Call Trace:
|
|
|
c5c6e7 |
[ 64.932699] <TASK>
|
|
|
c5c6e7 |
[ 64.934292] dump_stack_lvl+0x33/0x50
|
|
|
c5c6e7 |
[ 64.935908] ? nf_tables_commit+0xa24/0x1490 [nf_tables]
|
|
|
c5c6e7 |
[ 64.937551] kasan_report+0xda/0x120
|
|
|
c5c6e7 |
[ 64.939186] ? nf_tables_commit+0xa24/0x1490 [nf_tables]
|
|
|
c5c6e7 |
[ 64.940814] nf_tables_commit+0xa24/0x1490 [nf_tables]
|
|
|
c5c6e7 |
[ 64.942452] ? __kasan_slab_alloc+0x2d/0x60
|
|
|
c5c6e7 |
[ 64.944070] ? nf_tables_setelem_notify+0x190/0x190 [nf_tables]
|
|
|
c5c6e7 |
[ 64.945710] ? kasan_set_track+0x21/0x30
|
|
|
c5c6e7 |
[ 64.947323] nfnetlink_rcv_batch+0x709/0xd90 [nfnetlink]
|
|
|
c5c6e7 |
[ 64.948898] ? nfnetlink_rcv_msg+0x480/0x480 [nfnetlink]
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
Signed-off-by: Florian Westphal <fwestpha@redhat.com>
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
Signed-off-by: Ryan Sullivan <rysulliv@redhat.com>
|
|
|
c5c6e7 |
---
|
|
|
c5c6e7 |
net/netfilter/nf_tables_api.c | 97 ++++++++++++++++++++++++++++++++++-
|
|
|
c5c6e7 |
net/netfilter/nft_dynset.c | 26 ++++++++++
|
|
|
c5c6e7 |
net/netfilter/nft_lookup.c | 26 ++++++++++
|
|
|
c5c6e7 |
3 files changed, 147 insertions(+), 2 deletions(-)
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
|
|
|
c5c6e7 |
index 44738b987690..feff3b92a617 100644
|
|
|
c5c6e7 |
--- a/net/netfilter/nf_tables_api.c
|
|
|
c5c6e7 |
+++ b/net/netfilter/nf_tables_api.c
|
|
|
c5c6e7 |
@@ -20,6 +20,9 @@
|
|
|
c5c6e7 |
#include <net/netfilter/nf_tables.h>
|
|
|
c5c6e7 |
#include <net/net_namespace.h>
|
|
|
c5c6e7 |
#include <net/sock.h>
|
|
|
c5c6e7 |
+#include <linux/livepatch.h>
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+#define KLP_CVE_2023_32233 0x2022101200000111
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
static LIST_HEAD(nf_tables_expressions);
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
@@ -260,6 +263,50 @@ static inline void nft_rule_clear(struct net *net, struct nft_rule *rule)
|
|
|
c5c6e7 |
rule->genmask &= ~nft_genmask_next(net);
|
|
|
c5c6e7 |
}
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
+extern void nft_dynset_deactivate(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
+ const struct nft_expr *expr);
|
|
|
c5c6e7 |
+extern void nft_dynset_activate(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
+ const struct nft_expr *expr);
|
|
|
c5c6e7 |
+extern int klp_is_nft_dynset(const struct nft_expr *expr);
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+extern void nft_lookup_deactivate(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
+ const struct nft_expr *expr);
|
|
|
c5c6e7 |
+extern void nft_lookup_activate(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
+ const struct nft_expr *expr);
|
|
|
c5c6e7 |
+extern int klp_is_nft_lookup(const struct nft_expr *expr);
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+static void nft_rule_expr_activate(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
+ struct nft_rule *rule)
|
|
|
c5c6e7 |
+{
|
|
|
c5c6e7 |
+ struct nft_expr *expr;
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+ expr = nft_expr_first(rule);
|
|
|
c5c6e7 |
+ while (expr != nft_expr_last(rule) && expr->ops) {
|
|
|
c5c6e7 |
+ if (klp_is_nft_dynset(expr))
|
|
|
c5c6e7 |
+ nft_dynset_activate(ctx, expr);
|
|
|
c5c6e7 |
+ else if (klp_is_nft_lookup(expr))
|
|
|
c5c6e7 |
+ nft_lookup_activate(ctx, expr);
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+ expr = nft_expr_next(expr);
|
|
|
c5c6e7 |
+ }
|
|
|
c5c6e7 |
+}
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+static void nft_rule_expr_deactivate(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
+ struct nft_rule *rule)
|
|
|
c5c6e7 |
+{
|
|
|
c5c6e7 |
+ struct nft_expr *expr;
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+ expr = nft_expr_first(rule);
|
|
|
c5c6e7 |
+ while (expr != nft_expr_last(rule) && expr->ops) {
|
|
|
c5c6e7 |
+ if (klp_is_nft_dynset(expr))
|
|
|
c5c6e7 |
+ nft_dynset_deactivate(ctx, expr);
|
|
|
c5c6e7 |
+ else if (klp_is_nft_lookup(expr))
|
|
|
c5c6e7 |
+ nft_lookup_deactivate(ctx, expr);
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+ expr = nft_expr_next(expr);
|
|
|
c5c6e7 |
+ }
|
|
|
c5c6e7 |
+}
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
static int
|
|
|
c5c6e7 |
nf_tables_delrule_deactivate(struct nft_ctx *ctx, struct nft_rule *rule)
|
|
|
c5c6e7 |
{
|
|
|
c5c6e7 |
@@ -301,6 +348,7 @@ static int nft_delrule(struct nft_ctx *ctx, struct nft_rule *rule)
|
|
|
c5c6e7 |
nft_trans_destroy(trans);
|
|
|
c5c6e7 |
return err;
|
|
|
c5c6e7 |
}
|
|
|
c5c6e7 |
+ nft_rule_expr_deactivate(ctx, rule);
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
return 0;
|
|
|
c5c6e7 |
}
|
|
|
c5c6e7 |
@@ -2736,6 +2784,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
|
|
c5c6e7 |
unsigned char *udata;
|
|
|
c5c6e7 |
u16 udlen;
|
|
|
c5c6e7 |
int err;
|
|
|
c5c6e7 |
+ u16 *klp_removed;
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
if (nla[NFTA_SET_TABLE] == NULL ||
|
|
|
c5c6e7 |
nla[NFTA_SET_NAME] == NULL ||
|
|
|
c5c6e7 |
@@ -2861,10 +2910,16 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
|
|
c5c6e7 |
if (set == NULL)
|
|
|
c5c6e7 |
goto err1;
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
+ klp_removed = klp_shadow_alloc(set, KLP_CVE_2023_32233,
|
|
|
c5c6e7 |
+ sizeof(*klp_removed), GFP_KERNEL,
|
|
|
c5c6e7 |
+ NULL, NULL);
|
|
|
c5c6e7 |
+ if(!klp_removed)
|
|
|
c5c6e7 |
+ goto err2;
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
nla_strlcpy(name, nla[NFTA_SET_NAME], sizeof(set->name));
|
|
|
c5c6e7 |
err = nf_tables_set_alloc_name(&ctx, set, name);
|
|
|
c5c6e7 |
if (err < 0)
|
|
|
c5c6e7 |
- goto err2;
|
|
|
c5c6e7 |
+ goto klp_err;
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
udata = NULL;
|
|
|
c5c6e7 |
if (udlen) {
|
|
|
c5c6e7 |
@@ -2889,7 +2944,7 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
err = ops->init(set, &desc, nla);
|
|
|
c5c6e7 |
if (err < 0)
|
|
|
c5c6e7 |
- goto err2;
|
|
|
c5c6e7 |
+ goto klp_err;
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
err = nft_trans_set_add(&ctx, NFT_MSG_NEWSET, set);
|
|
|
c5c6e7 |
if (err < 0)
|
|
|
c5c6e7 |
@@ -2901,6 +2956,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
err3:
|
|
|
c5c6e7 |
ops->destroy(set);
|
|
|
c5c6e7 |
+klp_err:
|
|
|
c5c6e7 |
+ klp_shadow_free(set, KLP_CVE_2023_32233, NULL);
|
|
|
c5c6e7 |
err2:
|
|
|
c5c6e7 |
kfree(set);
|
|
|
c5c6e7 |
err1:
|
|
|
c5c6e7 |
@@ -2910,6 +2967,7 @@ err1:
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
static void nft_set_destroy(struct nft_set *set)
|
|
|
c5c6e7 |
{
|
|
|
c5c6e7 |
+ klp_shadow_free(set, KLP_CVE_2023_32233, NULL);
|
|
|
c5c6e7 |
set->ops->destroy(set);
|
|
|
c5c6e7 |
module_put(set->ops->owner);
|
|
|
c5c6e7 |
kfree(set);
|
|
|
c5c6e7 |
@@ -3013,6 +3071,34 @@ void nf_tables_unbind_set(const struct nft_ctx *ctx, struct nft_set *set,
|
|
|
c5c6e7 |
nf_tables_set_destroy(ctx, set);
|
|
|
c5c6e7 |
}
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
+static inline bool nft_set_is_anonymous(const struct nft_set *set)
|
|
|
c5c6e7 |
+{
|
|
|
c5c6e7 |
+ return set->flags & NFT_SET_ANONYMOUS;
|
|
|
c5c6e7 |
+}
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set)
|
|
|
c5c6e7 |
+{
|
|
|
c5c6e7 |
+ u16 *klp_removed;
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+ if (nft_set_is_anonymous(set)) {
|
|
|
c5c6e7 |
+ klp_removed = klp_shadow_get(set, KLP_CVE_2023_32233);
|
|
|
c5c6e7 |
+ if(klp_removed)
|
|
|
c5c6e7 |
+ *klp_removed = 0;
|
|
|
c5c6e7 |
+ }
|
|
|
c5c6e7 |
+}
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+__attribute__((optimize("-fno-optimize-sibling-calls")))
|
|
|
c5c6e7 |
+void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
|
|
|
c5c6e7 |
+ struct nft_set_binding *binding)
|
|
|
c5c6e7 |
+{
|
|
|
c5c6e7 |
+ u16 *klp_removed;
|
|
|
c5c6e7 |
+ klp_removed = klp_shadow_get(set, KLP_CVE_2023_32233);
|
|
|
c5c6e7 |
+ if (nft_set_is_anonymous(set)) {
|
|
|
c5c6e7 |
+ if(klp_removed)
|
|
|
c5c6e7 |
+ *klp_removed = 1;
|
|
|
c5c6e7 |
+ }
|
|
|
c5c6e7 |
+}
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
const struct nft_set_ext_type nft_set_ext_types[] = {
|
|
|
c5c6e7 |
[NFT_SET_EXT_KEY] = {
|
|
|
c5c6e7 |
.align = __alignof__(u32),
|
|
|
c5c6e7 |
@@ -3705,6 +3791,7 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
|
|
|
c5c6e7 |
struct nft_set *set;
|
|
|
c5c6e7 |
struct nft_ctx ctx;
|
|
|
c5c6e7 |
int rem, err = 0;
|
|
|
c5c6e7 |
+ u16 *klp_removed;
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
err = nft_ctx_init_from_elemattr(&ctx, net, skb, nlh, nla);
|
|
|
c5c6e7 |
if (err < 0)
|
|
|
c5c6e7 |
@@ -3716,6 +3803,10 @@ static int nf_tables_delsetelem(struct net *net, struct sock *nlsk,
|
|
|
c5c6e7 |
if (!list_empty(&set->bindings) && set->flags & NFT_SET_CONSTANT)
|
|
|
c5c6e7 |
return -EBUSY;
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
+ klp_removed = klp_shadow_get(set, KLP_CVE_2023_32233);
|
|
|
c5c6e7 |
+ if (klp_removed && *klp_removed)
|
|
|
c5c6e7 |
+ return -ENOENT;
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
if (nla[NFTA_SET_ELEM_LIST_ELEMENTS] == NULL) {
|
|
|
c5c6e7 |
struct nft_set_dump_args args = {
|
|
|
c5c6e7 |
.iter = {
|
|
|
c5c6e7 |
@@ -4152,11 +4243,13 @@ static int __nf_tables_abort(struct net *net)
|
|
|
c5c6e7 |
break;
|
|
|
c5c6e7 |
case NFT_MSG_NEWRULE:
|
|
|
c5c6e7 |
trans->ctx.chain->use--;
|
|
|
c5c6e7 |
+ nft_rule_expr_deactivate(&trans->ctx, nft_trans_rule(trans));
|
|
|
c5c6e7 |
list_del_rcu(&nft_trans_rule(trans)->list);
|
|
|
c5c6e7 |
break;
|
|
|
c5c6e7 |
case NFT_MSG_DELRULE:
|
|
|
c5c6e7 |
trans->ctx.chain->use++;
|
|
|
c5c6e7 |
nft_rule_clear(trans->ctx.net, nft_trans_rule(trans));
|
|
|
c5c6e7 |
+ nft_rule_expr_activate(&trans->ctx, nft_trans_rule(trans));
|
|
|
c5c6e7 |
nft_trans_destroy(trans);
|
|
|
c5c6e7 |
break;
|
|
|
c5c6e7 |
case NFT_MSG_NEWSET:
|
|
|
c5c6e7 |
diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
|
|
|
c5c6e7 |
index 0cf187230050..4d6d3af26a5b 100644
|
|
|
c5c6e7 |
--- a/net/netfilter/nft_dynset.c
|
|
|
c5c6e7 |
+++ b/net/netfilter/nft_dynset.c
|
|
|
c5c6e7 |
@@ -204,6 +204,32 @@ err1:
|
|
|
c5c6e7 |
return err;
|
|
|
c5c6e7 |
}
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
+void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
|
|
|
c5c6e7 |
+ struct nft_set_binding *binding);
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+void nft_dynset_deactivate(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
+ const struct nft_expr *expr)
|
|
|
c5c6e7 |
+{
|
|
|
c5c6e7 |
+ struct nft_dynset *priv = nft_expr_priv(expr);
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+ nf_tables_deactivate_set(ctx, priv->set, &priv->binding);
|
|
|
c5c6e7 |
+}
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set);
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+void nft_dynset_activate(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
+ const struct nft_expr *expr)
|
|
|
c5c6e7 |
+{
|
|
|
c5c6e7 |
+ struct nft_dynset *priv = nft_expr_priv(expr);
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+ nf_tables_activate_set(ctx, priv->set);
|
|
|
c5c6e7 |
+}
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+int klp_is_nft_dynset(const struct nft_expr *expr)
|
|
|
c5c6e7 |
+{
|
|
|
c5c6e7 |
+ return expr->ops->type == &nft_dynset_type;
|
|
|
c5c6e7 |
+}
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
static void nft_dynset_destroy(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
const struct nft_expr *expr)
|
|
|
c5c6e7 |
{
|
|
|
c5c6e7 |
diff --git a/net/netfilter/nft_lookup.c b/net/netfilter/nft_lookup.c
|
|
|
c5c6e7 |
index c9ce7d60cd73..ab98a5cb7128 100644
|
|
|
c5c6e7 |
--- a/net/netfilter/nft_lookup.c
|
|
|
c5c6e7 |
+++ b/net/netfilter/nft_lookup.c
|
|
|
c5c6e7 |
@@ -125,6 +125,32 @@ static int nft_lookup_init(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
return 0;
|
|
|
c5c6e7 |
}
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
+void nf_tables_deactivate_set(const struct nft_ctx *ctx, struct nft_set *set,
|
|
|
c5c6e7 |
+ struct nft_set_binding *binding);
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+void nft_lookup_deactivate(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
+ const struct nft_expr *expr)
|
|
|
c5c6e7 |
+{
|
|
|
c5c6e7 |
+ struct nft_lookup *priv = nft_expr_priv(expr);
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+ nf_tables_deactivate_set(ctx, priv->set, &priv->binding);
|
|
|
c5c6e7 |
+}
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+void nf_tables_activate_set(const struct nft_ctx *ctx, struct nft_set *set);
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+void nft_lookup_activate(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
+ const struct nft_expr *expr)
|
|
|
c5c6e7 |
+{
|
|
|
c5c6e7 |
+ struct nft_lookup *priv = nft_expr_priv(expr);
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+ nf_tables_activate_set(ctx, priv->set);
|
|
|
c5c6e7 |
+}
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
+int klp_is_nft_lookup(const struct nft_expr *expr)
|
|
|
c5c6e7 |
+{
|
|
|
c5c6e7 |
+ return expr->ops->type == &nft_lookup_type;
|
|
|
c5c6e7 |
+}
|
|
|
c5c6e7 |
+
|
|
|
c5c6e7 |
static void nft_lookup_destroy(const struct nft_ctx *ctx,
|
|
|
c5c6e7 |
const struct nft_expr *expr)
|
|
|
c5c6e7 |
{
|
|
|
c5c6e7 |
--
|
|
|
c5c6e7 |
2.40.1
|
|
|
c5c6e7 |
|
|
|
c5c6e7 |
|