netfilter: nf_tables: Fix entries val in rule reset audit log

The value in idx and the number of rules handled in that particular
__nf_tables_dump_rules() call is not identical. The former is a cursor
to pick up from if multiple netlink messages are needed, so its value is
ever increasing. Fixing this is not just a matter of subtracting s_idx
from it, though: When resetting rules in multiple chains,
__nf_tables_dump_rules() is called for each and cb->args[0] is not
adjusted in between. Introduce a dedicated counter to record the number
of rules reset in this call in a less confusing way.

While being at it, prevent the direct return upon buffer exhaustion: Any
rules previously dumped into that skb would evade audit logging
otherwise.

Fixes: 9b5ba5c9c5 ("netfilter: nf_tables: Unbreak audit log reset")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Phil Sutter 2023-09-13 15:51:36 +02:00 committed by Pablo Neira Ayuso
parent 4908d5af16
commit 7fb818f248
1 changed files with 10 additions and 6 deletions

View File

@ -3451,6 +3451,8 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
struct net *net = sock_net(skb->sk);
const struct nft_rule *rule, *prule;
unsigned int s_idx = cb->args[0];
unsigned int entries = 0;
int ret = 0;
u64 handle;
prule = NULL;
@ -3473,9 +3475,11 @@ static int __nf_tables_dump_rules(struct sk_buff *skb,
NFT_MSG_NEWRULE,
NLM_F_MULTI | NLM_F_APPEND,
table->family,
table, chain, rule, handle, reset) < 0)
return 1;
table, chain, rule, handle, reset) < 0) {
ret = 1;
break;
}
entries++;
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
cont:
prule = rule;
@ -3483,10 +3487,10 @@ cont_skip:
(*idx)++;
}
if (reset && *idx)
audit_log_rule_reset(table, cb->seq, *idx);
if (reset && entries)
audit_log_rule_reset(table, cb->seq, entries);
return 0;
return ret;
}
static int nf_tables_dump_rules(struct sk_buff *skb,