diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-05-23 11:09:42 +0200 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-06-02 10:54:28 +0200 |
commit | a1cee076f4d4774504c62e0f1846a11a6fcb6be3 (patch) | |
tree | c2f9d23040c1898b98e5aea2aa93207c2f56fe19 /net | |
parent | 46bbafceb201df635b7c0a9d7a0e526cb2f8cb75 (diff) | |
download | linux-a1cee076f4d4774504c62e0f1846a11a6fcb6be3.tar.gz linux-a1cee076f4d4774504c62e0f1846a11a6fcb6be3.tar.bz2 linux-a1cee076f4d4774504c62e0f1846a11a6fcb6be3.zip |
netfilter: nf_tables: release objects in reverse order in the abort path
The patch c7c32e7 ("netfilter: nf_tables: defer all object release via
rcu") indicates that we always release deleted objects in the reverse
order, but that is only needed in the abort path. These are the two
possible scenarios when releasing objects:
1) Deletion scenario in the commit path: no need to release objects in
the reverse order since userspace already ensures that dependencies are
fulfilled), ie. userspace tells us to delete rule -> ... -> rule ->
chain -> table. In this case, we have to release the objects in the
*same order* as userspace provided.
2) Deletion scenario in the abort path: we have to iterate in the reverse
order to undo what it cannot be added, ie. userspace sent us a batch
that includes: table -> chain -> rule -> ... -> rule, and that needs to
be partially undone. In this case, we have to release objects in the
reverse order to ensure that the set and chain objects point to valid
rule and table objects.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/nf_tables_api.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 9365531ee911..4fffa3680d42 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c @@ -3527,7 +3527,8 @@ static int nf_tables_abort(struct sk_buff *skb) } } - list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { + list_for_each_entry_safe_reverse(trans, next, + &net->nft.commit_list, list) { list_del(&trans->list); trans->ctx.nla = NULL; call_rcu(&trans->rcu_head, nf_tables_abort_release_rcu); |