netfilter: nf_tables: fix transaction race condition
authorPatrick McHardy <kaber@trash.net>
Tue, 3 Mar 2015 20:04:18 +0000 (20:04 +0000)
committerPablo Neira Ayuso <pablo@netfilter.org>
Wed, 4 Mar 2015 17:46:04 +0000 (18:46 +0100)
commit8670c3a55e91cb27a4b4d4d4c4fa35b0149e1abf
treec62f3d5d48a68d59264eb3e158237f33c92760db
parent8f711a601d6a2f61bb0ca173911bedc5069d3b9a
netfilter: nf_tables: fix transaction race condition

A race condition exists in the rule transaction code for rules that
get added and removed within the same transaction.

The new rule starts out as inactive in the current and active in the
next generation and is inserted into the ruleset. When it is deleted,
it is additionally set to inactive in the next generation as well.

On commit the next generation is begun, then the actions are finalized.
For the new rule this would mean clearing out the inactive bit for
the previously current, now next generation.

However nft_rule_clear() clears out the bits for *both* generations,
activating the rule in the current generation, where it should be
deactivated due to being deleted. The rule will thus be active until
the deletion is finalized, removing the rule from the ruleset.

Similarly, when aborting a transaction for the same case, the undo
of insertion will remove it from the RCU protected rule list, the
deletion will clear out all bits. However until the next RCU
synchronization after all operations have been undone, the rule is
active on CPUs which can still see the rule on the list.

Generally, there may never be any modifications of the current
generations' inactive bit since this defeats the entire purpose of
atomicity. Change nft_rule_clear() to only touch the next generations
bit to fix this.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_tables_api.c