]> git.baikalelectronics.ru Git - kernel.git/commit
netfilter: conntrack: fix rmmod double-free race
authorFlorian Westphal <fw@strlen.de>
Tue, 14 Feb 2023 16:23:59 +0000 (17:23 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 11 Mar 2023 12:55:24 +0000 (13:55 +0100)
commite422fe3568a9f1093c8ea7e68c1b20603e4c5bd2
tree063dafb46f9f01b1f8f7469c690ca670b61f5bd6
parentc2753b96b03f588dbe3e2b93f14a58f152adfe73
netfilter: conntrack: fix rmmod double-free race

[ Upstream commit 457134d07b40fc841963a70b5f827bb47b601d50 ]

nf_conntrack_hash_check_insert() callers free the ct entry directly, via
nf_conntrack_free.

This isn't safe anymore because
nf_conntrack_hash_check_insert() might place the entry into the conntrack
table and then delteted the entry again because it found that a conntrack
extension has been removed at the same time.

In this case, the just-added entry is removed again and an error is
returned to the caller.

Problem is that another cpu might have picked up this entry and
incremented its reference count.

This results in a use-after-free/double-free, once by the other cpu and
once by the caller of nf_conntrack_hash_check_insert().

Fix this by making nf_conntrack_hash_check_insert() not fail anymore
after the insertion, just like before the 'Fixes' commit.

This is safe because a racing nf_ct_iterate() has to wait for us
to release the conntrack hash spinlocks.

While at it, make the function return -EAGAIN in the rmmod (genid
changed) case, this makes nfnetlink replay the command (suggested
by Pablo Neira).

Fixes: aa5754ba13ea ("netfilter: extensions: introduce extension genid count")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
net/netfilter/nf_conntrack_bpf.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_conntrack_netlink.c