Skip to content

Commit 1baf015

Browse files
Phil SutterFlorian Westphal
authored andcommitted
netfilter: nf_tables: audit log object reset once per table
When resetting multiple objects at once (via dump request), emit a log message per table (or filled skb) and resurrect the 'entries' parameter to contain the number of objects being logged for. To test the skb exhaustion path, perform some bulk counter and quota adds in the kselftest. Signed-off-by: Phil Sutter <[email protected]> Reviewed-by: Richard Guy Briggs <[email protected]> Acked-by: Paul Moore <[email protected]> (Audit) Signed-off-by: Florian Westphal <[email protected]>
1 parent 2915240 commit 1baf015

File tree

2 files changed

+74
-22
lines changed

2 files changed

+74
-22
lines changed

net/netfilter/nf_tables_api.c

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7607,6 +7607,16 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
76077607
return -1;
76087608
}
76097609

7610+
static void audit_log_obj_reset(const struct nft_table *table,
7611+
unsigned int base_seq, unsigned int nentries)
7612+
{
7613+
char *buf = kasprintf(GFP_ATOMIC, "%s:%u", table->name, base_seq);
7614+
7615+
audit_log_nfcfg(buf, table->family, nentries,
7616+
AUDIT_NFT_OP_OBJ_RESET, GFP_ATOMIC);
7617+
kfree(buf);
7618+
}
7619+
76107620
struct nft_obj_filter {
76117621
char *table;
76127622
u32 type;
@@ -7621,8 +7631,10 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
76217631
struct net *net = sock_net(skb->sk);
76227632
int family = nfmsg->nfgen_family;
76237633
struct nftables_pernet *nft_net;
7634+
unsigned int entries = 0;
76247635
struct nft_object *obj;
76257636
bool reset = false;
7637+
int rc = 0;
76267638

76277639
if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
76287640
reset = true;
@@ -7635,6 +7647,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
76357647
if (family != NFPROTO_UNSPEC && family != table->family)
76367648
continue;
76377649

7650+
entries = 0;
76387651
list_for_each_entry_rcu(obj, &table->objects, list) {
76397652
if (!nft_is_active(net, obj))
76407653
goto cont;
@@ -7650,34 +7663,27 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
76507663
filter->type != NFT_OBJECT_UNSPEC &&
76517664
obj->ops->type->type != filter->type)
76527665
goto cont;
7653-
if (reset) {
7654-
char *buf = kasprintf(GFP_ATOMIC,
7655-
"%s:%u",
7656-
table->name,
7657-
nft_net->base_seq);
7658-
7659-
audit_log_nfcfg(buf,
7660-
family,
7661-
obj->handle,
7662-
AUDIT_NFT_OP_OBJ_RESET,
7663-
GFP_ATOMIC);
7664-
kfree(buf);
7665-
}
76667666

7667-
if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
7668-
cb->nlh->nlmsg_seq,
7669-
NFT_MSG_NEWOBJ,
7670-
NLM_F_MULTI | NLM_F_APPEND,
7671-
table->family, table,
7672-
obj, reset) < 0)
7673-
goto done;
7667+
rc = nf_tables_fill_obj_info(skb, net,
7668+
NETLINK_CB(cb->skb).portid,
7669+
cb->nlh->nlmsg_seq,
7670+
NFT_MSG_NEWOBJ,
7671+
NLM_F_MULTI | NLM_F_APPEND,
7672+
table->family, table,
7673+
obj, reset);
7674+
if (rc < 0)
7675+
break;
76747676

7677+
entries++;
76757678
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
76767679
cont:
76777680
idx++;
76787681
}
7682+
if (reset && entries)
7683+
audit_log_obj_reset(table, nft_net->base_seq, entries);
7684+
if (rc < 0)
7685+
break;
76797686
}
7680-
done:
76817687
rcu_read_unlock();
76827688

76837689
cb->args[0] = idx;
@@ -7782,7 +7788,7 @@ static int nf_tables_getobj(struct sk_buff *skb, const struct nfnl_info *info,
77827788

77837789
audit_log_nfcfg(buf,
77847790
family,
7785-
obj->handle,
7791+
1,
77867792
AUDIT_NFT_OP_OBJ_RESET,
77877793
GFP_ATOMIC);
77887794
kfree(buf);

tools/testing/selftests/netfilter/nft_audit.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,12 @@ do_test 'nft add counter t1 c1' \
9393
do_test 'nft add counter t2 c1; add counter t2 c2' \
9494
'table=t2 family=2 entries=2 op=nft_register_obj'
9595

96+
for ((i = 3; i <= 500; i++)); do
97+
echo "add counter t2 c$i"
98+
done >$rulefile
99+
do_test "nft -f $rulefile" \
100+
'table=t2 family=2 entries=498 op=nft_register_obj'
101+
96102
# adding/updating quotas
97103

98104
do_test 'nft add quota t1 q1 { 10 bytes }' \
@@ -101,6 +107,12 @@ do_test 'nft add quota t1 q1 { 10 bytes }' \
101107
do_test 'nft add quota t2 q1 { 10 bytes }; add quota t2 q2 { 10 bytes }' \
102108
'table=t2 family=2 entries=2 op=nft_register_obj'
103109

110+
for ((i = 3; i <= 500; i++)); do
111+
echo "add quota t2 q$i { 10 bytes }"
112+
done >$rulefile
113+
do_test "nft -f $rulefile" \
114+
'table=t2 family=2 entries=498 op=nft_register_obj'
115+
104116
# changing the quota value triggers obj update path
105117
do_test 'nft add quota t1 q1 { 20 bytes }' \
106118
'table=t1 family=2 entries=1 op=nft_register_obj'
@@ -150,6 +162,40 @@ done
150162
do_test 'nft reset set t1 s' \
151163
'table=t1 family=2 entries=3 op=nft_reset_setelem'
152164

165+
# resetting counters
166+
167+
do_test 'nft reset counter t1 c1' \
168+
'table=t1 family=2 entries=1 op=nft_reset_obj'
169+
170+
do_test 'nft reset counters t1' \
171+
'table=t1 family=2 entries=1 op=nft_reset_obj'
172+
173+
do_test 'nft reset counters t2' \
174+
'table=t2 family=2 entries=342 op=nft_reset_obj
175+
table=t2 family=2 entries=158 op=nft_reset_obj'
176+
177+
do_test 'nft reset counters' \
178+
'table=t1 family=2 entries=1 op=nft_reset_obj
179+
table=t2 family=2 entries=341 op=nft_reset_obj
180+
table=t2 family=2 entries=159 op=nft_reset_obj'
181+
182+
# resetting quotas
183+
184+
do_test 'nft reset quota t1 q1' \
185+
'table=t1 family=2 entries=1 op=nft_reset_obj'
186+
187+
do_test 'nft reset quotas t1' \
188+
'table=t1 family=2 entries=1 op=nft_reset_obj'
189+
190+
do_test 'nft reset quotas t2' \
191+
'table=t2 family=2 entries=315 op=nft_reset_obj
192+
table=t2 family=2 entries=185 op=nft_reset_obj'
193+
194+
do_test 'nft reset quotas' \
195+
'table=t1 family=2 entries=1 op=nft_reset_obj
196+
table=t2 family=2 entries=314 op=nft_reset_obj
197+
table=t2 family=2 entries=186 op=nft_reset_obj'
198+
153199
# deleting rules
154200

155201
readarray -t handles < <(nft -a list chain t1 c1 | \

0 commit comments

Comments
 (0)