aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2014-05-23 11:09:42 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2014-06-02 10:54:28 +0200
commita1cee076f4d4774504c62e0f1846a11a6fcb6be3 (patch)
treec2f9d23040c1898b98e5aea2aa93207c2f56fe19 /net/netfilter
parentnetfilter: nf_tables: fix wrong transaction ordering in set elements (diff)
downloadlinux-dev-a1cee076f4d4774504c62e0f1846a11a6fcb6be3.tar.xz
linux-dev-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/netfilter')
-rw-r--r--net/netfilter/nf_tables_api.c3
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);