netfilter: nfnetlink_queue: un-break NF_REPEAT

Only override userspace verdict if the ct hook returns something
other than ACCEPT.

Else, this replaces NF_REPEAT (run all hooks again) with NF_ACCEPT
(move to next hook).

Fixes: 6291b3a67a ("netfilter: conntrack: convert nf_conntrack_update to netfilter verdicts")
Reported-by: l.6diay@passmail.com
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Florian Westphal 2024-02-06 17:54:18 +01:00 committed by Pablo Neira Ayuso
parent 7395dfacff
commit f82777e8ce

View File

@ -232,18 +232,25 @@ static void nfqnl_reinject(struct nf_queue_entry *entry, unsigned int verdict)
if (verdict == NF_ACCEPT ||
verdict == NF_REPEAT ||
verdict == NF_STOP) {
unsigned int ct_verdict = verdict;
rcu_read_lock();
ct_hook = rcu_dereference(nf_ct_hook);
if (ct_hook)
verdict = ct_hook->update(entry->state.net, entry->skb);
ct_verdict = ct_hook->update(entry->state.net, entry->skb);
rcu_read_unlock();
switch (verdict & NF_VERDICT_MASK) {
switch (ct_verdict & NF_VERDICT_MASK) {
case NF_ACCEPT:
/* follow userspace verdict, could be REPEAT */
break;
case NF_STOLEN:
nf_queue_entry_free(entry);
return;
default:
verdict = ct_verdict & NF_VERDICT_MASK;
break;
}
}
nf_reinject(entry, verdict);
}