]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
netfilter: nf_tables: Deduplicate nft_register_obj audit logs
authorPhil Sutter <phil@nwl.cc>
Sat, 23 Sep 2023 01:53:50 +0000 (03:53 +0200)
committerFlorian Westphal <fw@strlen.de>
Wed, 4 Oct 2023 13:57:06 +0000 (15:57 +0200)
When adding/updating an object, the transaction handler emits suitable
audit log entries already, the one in nft_obj_notify() is redundant. To
fix that (and retain the audit logging from objects' 'update' callback),
Introduce an "audit log free" variant for internal use.

Fixes: c520292f29b8 ("audit: log nftables configuration change events once per table")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Richard Guy Briggs <rgb@redhat.com>
Acked-by: Paul Moore <paul@paul-moore.com> (Audit)
Signed-off-by: Florian Westphal <fw@strlen.de>
net/netfilter/nf_tables_api.c
tools/testing/selftests/netfilter/nft_audit.sh

index 4356189360fb88d695b25070264783520aeef6b1..a72b6aeefb1b5de353a89876ccc2635aa60515dd 100644 (file)
@@ -7871,24 +7871,14 @@ static int nf_tables_delobj(struct sk_buff *skb, const struct nfnl_info *info,
        return nft_delobj(&ctx, obj);
 }
 
-void nft_obj_notify(struct net *net, const struct nft_table *table,
-                   struct nft_object *obj, u32 portid, u32 seq, int event,
-                   u16 flags, int family, int report, gfp_t gfp)
+static void
+__nft_obj_notify(struct net *net, const struct nft_table *table,
+                struct nft_object *obj, u32 portid, u32 seq, int event,
+                u16 flags, int family, int report, gfp_t gfp)
 {
        struct nftables_pernet *nft_net = nft_pernet(net);
        struct sk_buff *skb;
        int err;
-       char *buf = kasprintf(gfp, "%s:%u",
-                             table->name, nft_net->base_seq);
-
-       audit_log_nfcfg(buf,
-                       family,
-                       obj->handle,
-                       event == NFT_MSG_NEWOBJ ?
-                                AUDIT_NFT_OP_OBJ_REGISTER :
-                                AUDIT_NFT_OP_OBJ_UNREGISTER,
-                       gfp);
-       kfree(buf);
 
        if (!report &&
            !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES))
@@ -7911,13 +7901,35 @@ void nft_obj_notify(struct net *net, const struct nft_table *table,
 err:
        nfnetlink_set_err(net, portid, NFNLGRP_NFTABLES, -ENOBUFS);
 }
+
+void nft_obj_notify(struct net *net, const struct nft_table *table,
+                   struct nft_object *obj, u32 portid, u32 seq, int event,
+                   u16 flags, int family, int report, gfp_t gfp)
+{
+       struct nftables_pernet *nft_net = nft_pernet(net);
+       char *buf = kasprintf(gfp, "%s:%u",
+                             table->name, nft_net->base_seq);
+
+       audit_log_nfcfg(buf,
+                       family,
+                       obj->handle,
+                       event == NFT_MSG_NEWOBJ ?
+                                AUDIT_NFT_OP_OBJ_REGISTER :
+                                AUDIT_NFT_OP_OBJ_UNREGISTER,
+                       gfp);
+       kfree(buf);
+
+       __nft_obj_notify(net, table, obj, portid, seq, event,
+                        flags, family, report, gfp);
+}
 EXPORT_SYMBOL_GPL(nft_obj_notify);
 
 static void nf_tables_obj_notify(const struct nft_ctx *ctx,
                                 struct nft_object *obj, int event)
 {
-       nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event,
-                      ctx->flags, ctx->family, ctx->report, GFP_KERNEL);
+       __nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid,
+                        ctx->seq, event, ctx->flags, ctx->family,
+                        ctx->report, GFP_KERNEL);
 }
 
 /*
index 0b3255e7b353819fb5268059b040ae8528d347db..bb34329e02a7f99b0b60bef66f9f1a2441b04c16 100755 (executable)
@@ -85,6 +85,26 @@ do_test "nft add set t1 s2 $setblock; add set t1 s3 { $settype; }" \
 do_test "nft add element t1 s3 $setelem" \
 "table=t1 family=2 entries=3 op=nft_register_setelem"
 
+# adding counters
+
+do_test 'nft add counter t1 c1' \
+'table=t1 family=2 entries=1 op=nft_register_obj'
+
+do_test 'nft add counter t2 c1; add counter t2 c2' \
+'table=t2 family=2 entries=2 op=nft_register_obj'
+
+# adding/updating quotas
+
+do_test 'nft add quota t1 q1 { 10 bytes }' \
+'table=t1 family=2 entries=1 op=nft_register_obj'
+
+do_test 'nft add quota t2 q1 { 10 bytes }; add quota t2 q2 { 10 bytes }' \
+'table=t2 family=2 entries=2 op=nft_register_obj'
+
+# changing the quota value triggers obj update path
+do_test 'nft add quota t1 q1 { 20 bytes }' \
+'table=t1 family=2 entries=1 op=nft_register_obj'
+
 # resetting rules
 
 do_test 'nft reset rules t1 c2' \