Blame SOURCES/CVE-2023-32233.patch

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