netfilter: nf_tables: Audit log rule reset
authorPhil Sutter <phil@nwl.cc>
Tue, 29 Aug 2023 17:51:58 +0000 (19:51 +0200)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 30 Aug 2023 23:29:28 +0000 (01:29 +0200)
Resetting rules' stateful data happens outside of the transaction logic,
so 'get' and 'dump' handlers have to emit audit log entries themselves.

Fixes: 8daa8fde3fc3f ("netfilter: nf_tables: Introduce NFT_MSG_GETRULE_RESET")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Richard Guy Briggs <rgb@redhat.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/linux/audit.h
kernel/auditsc.c
net/netfilter/nf_tables_api.c

index 192bf03..51b1b70 100644 (file)
@@ -118,6 +118,7 @@ enum audit_nfcfgop {
        AUDIT_NFT_OP_FLOWTABLE_REGISTER,
        AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,
        AUDIT_NFT_OP_SETELEM_RESET,
+       AUDIT_NFT_OP_RULE_RESET,
        AUDIT_NFT_OP_INVALID,
 };
 
index 38481e3..fc0c7c0 100644 (file)
@@ -144,6 +144,7 @@ static const struct audit_nfcfgop_tab audit_nfcfgs[] = {
        { AUDIT_NFT_OP_FLOWTABLE_REGISTER,      "nft_register_flowtable"   },
        { AUDIT_NFT_OP_FLOWTABLE_UNREGISTER,    "nft_unregister_flowtable" },
        { AUDIT_NFT_OP_SETELEM_RESET,           "nft_reset_setelem"        },
+       { AUDIT_NFT_OP_RULE_RESET,              "nft_reset_rule"           },
        { AUDIT_NFT_OP_INVALID,                 "nft_invalid"              },
 };
 
index 361e98e..2c81cee 100644 (file)
@@ -3422,6 +3422,18 @@ err:
        nfnetlink_set_err(ctx->net, ctx->portid, NFNLGRP_NFTABLES, -ENOBUFS);
 }
 
+static void audit_log_rule_reset(const struct nft_table *table,
+                                unsigned int base_seq,
+                                unsigned int nentries)
+{
+       char *buf = kasprintf(GFP_ATOMIC, "%s:%u",
+                             table->name, base_seq);
+
+       audit_log_nfcfg(buf, table->family, nentries,
+                       AUDIT_NFT_OP_RULE_RESET, GFP_ATOMIC);
+       kfree(buf);
+}
+
 struct nft_rule_dump_ctx {
        char *table;
        char *chain;
@@ -3528,6 +3540,9 @@ static int nf_tables_dump_rules(struct sk_buff *skb,
 done:
        rcu_read_unlock();
 
+       if (reset && idx > cb->args[0])
+               audit_log_rule_reset(table, cb->seq, idx - cb->args[0]);
+
        cb->args[0] = idx;
        return skb->len;
 }
@@ -3635,6 +3650,9 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info,
        if (err < 0)
                goto err_fill_rule_info;
 
+       if (reset)
+               audit_log_rule_reset(table, nft_pernet(net)->base_seq, 1);
+
        return nfnetlink_unicast(skb2, net, NETLINK_CB(skb).portid);
 
 err_fill_rule_info: