mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-12-28 16:56:26 +00:00
b04df3da1b
nf_tables_chain_destroy can sleep, it can't be used from call_rcu
callbacks.
Moreover, nf_tables_rule_release() is only safe for error unwinding,
while transaction mutex is held and the to-be-desroyed rule was not
exposed to either dataplane or dumps, as it deactives+frees without
the required synchronize_rcu() in-between.
nft_rule_expr_deactivate() callbacks will change ->use counters
of other chains/sets, see e.g. nft_lookup .deactivate callback, these
must be serialized via transaction mutex.
Also add a few lockdep asserts to make this more explicit.
Calling synchronize_rcu() isn't ideal, but fixing this without is hard
and way more intrusive. As-is, we can get:
WARNING: .. net/netfilter/nf_tables_api.c:5515 nft_set_destroy+0x..
Workqueue: events nf_tables_trans_destroy_work
RIP: 0010:nft_set_destroy+0x3fe/0x5c0
Call Trace:
<TASK>
nf_tables_trans_destroy_work+0x6b7/0xad0
process_one_work+0x64a/0xce0
worker_thread+0x613/0x10d0
In case the synchronize_rcu becomes an issue, we can explore alternatives.
One way would be to allocate nft_trans_rule objects + one nft_trans_chain
object, deactivate the rules + the chain and then defer the freeing to the
nft destroy workqueue. We'd still need to keep the synchronize_rcu path as
a fallback to handle -ENOMEM corner cases though.
Reported-by: syzbot+b26935466701e56cfdc2@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/67478d92.050a0220.253251.0062.GAE@google.com/T/
Fixes:
|
||
---|---|---|
.. | ||
ipv4 | ||
ipv6 | ||
br_netfilter.h | ||
nf_bpf_link.h | ||
nf_conntrack_acct.h | ||
nf_conntrack_act_ct.h | ||
nf_conntrack_bpf.h | ||
nf_conntrack_bridge.h | ||
nf_conntrack_core.h | ||
nf_conntrack_count.h | ||
nf_conntrack_ecache.h | ||
nf_conntrack_expect.h | ||
nf_conntrack_extend.h | ||
nf_conntrack_helper.h | ||
nf_conntrack_l4proto.h | ||
nf_conntrack_labels.h | ||
nf_conntrack_seqadj.h | ||
nf_conntrack_synproxy.h | ||
nf_conntrack_timeout.h | ||
nf_conntrack_timestamp.h | ||
nf_conntrack_tuple.h | ||
nf_conntrack_zones.h | ||
nf_conntrack.h | ||
nf_dup_netdev.h | ||
nf_flow_table.h | ||
nf_hooks_lwtunnel.h | ||
nf_log.h | ||
nf_nat_helper.h | ||
nf_nat_masquerade.h | ||
nf_nat_redirect.h | ||
nf_nat.h | ||
nf_queue.h | ||
nf_reject.h | ||
nf_socket.h | ||
nf_synproxy.h | ||
nf_tables_core.h | ||
nf_tables_ipv4.h | ||
nf_tables_ipv6.h | ||
nf_tables_offload.h | ||
nf_tables.h | ||
nf_tproxy.h | ||
nft_fib.h | ||
nft_meta.h | ||
nft_reject.h | ||
xt_rateest.h |