Commit 436322eeda54e4c8ebb09c7a293dc169afeabb7a

Authored by Pablo Neira Ayuso
Committed by Greg Kroah-Hartman
1 parent 7266a6b028

netfilter: nf_tables: fix flush ruleset chain dependencies

commit a2f18db0c68fec96631c10cad9384c196e9008ac upstream.

Jumping between chains doesn't mix well with flush ruleset. Rules
from a different chain and set elements may still refer to us.

[  353.373791] ------------[ cut here ]------------
[  353.373845] kernel BUG at net/netfilter/nf_tables_api.c:1159!
[  353.373896] invalid opcode: 0000 [#1] SMP
[  353.373942] Modules linked in: intel_powerclamp uas iwldvm iwlwifi
[  353.374017] CPU: 0 PID: 6445 Comm: 31c3.nft Not tainted 3.18.0 #98
[  353.374069] Hardware name: LENOVO 5129CTO/5129CTO, BIOS 6QET47WW (1.17 ) 07/14/2010
[...]
[  353.375018] Call Trace:
[  353.375046]  [<ffffffff81964c31>] ? nf_tables_commit+0x381/0x540
[  353.375101]  [<ffffffff81949118>] nfnetlink_rcv+0x3d8/0x4b0
[  353.375150]  [<ffffffff81943fc5>] netlink_unicast+0x105/0x1a0
[  353.375200]  [<ffffffff8194438e>] netlink_sendmsg+0x32e/0x790
[  353.375253]  [<ffffffff818f398e>] sock_sendmsg+0x8e/0xc0
[  353.375300]  [<ffffffff818f36b9>] ? move_addr_to_kernel.part.20+0x19/0x70
[  353.375357]  [<ffffffff818f44f9>] ? move_addr_to_kernel+0x19/0x30
[  353.375410]  [<ffffffff819016d2>] ? verify_iovec+0x42/0xd0
[  353.375459]  [<ffffffff818f3e10>] ___sys_sendmsg+0x3f0/0x400
[  353.375510]  [<ffffffff810615fa>] ? native_sched_clock+0x2a/0x90
[  353.375563]  [<ffffffff81176697>] ? acct_account_cputime+0x17/0x20
[  353.375616]  [<ffffffff8110dc78>] ? account_user_time+0x88/0xa0
[  353.375667]  [<ffffffff818f4bbd>] __sys_sendmsg+0x3d/0x80
[  353.375719]  [<ffffffff81b184f4>] ? int_check_syscall_exit_work+0x34/0x3d
[  353.375776]  [<ffffffff818f4c0d>] SyS_sendmsg+0xd/0x20
[  353.375823]  [<ffffffff81b1826d>] system_call_fastpath+0x16/0x1b

Release objects in this order: rules -> sets -> chains -> tables, to
make sure no references to chains are held anymore.

Reported-by: Asbjoern Sloth Toennesen <asbjorn@asbjorn.biz>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

Showing 1 changed file with 9 additions and 5 deletions Side-by-side Diff

net/netfilter/nf_tables_api.c
... ... @@ -713,16 +713,12 @@
713 713 struct nft_chain *chain, *nc;
714 714 struct nft_set *set, *ns;
715 715  
716   - list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) {
  716 + list_for_each_entry(chain, &ctx->table->chains, list) {
717 717 ctx->chain = chain;
718 718  
719 719 err = nft_delrule_by_chain(ctx);
720 720 if (err < 0)
721 721 goto out;
722   -
723   - err = nft_delchain(ctx);
724   - if (err < 0)
725   - goto out;
726 722 }
727 723  
728 724 list_for_each_entry_safe(set, ns, &ctx->table->sets, list) {
... ... @@ -731,6 +727,14 @@
731 727 continue;
732 728  
733 729 err = nft_delset(ctx, set);
  730 + if (err < 0)
  731 + goto out;
  732 + }
  733 +
  734 + list_for_each_entry_safe(chain, nc, &ctx->table->chains, list) {
  735 + ctx->chain = chain;
  736 +
  737 + err = nft_delchain(ctx);
734 738 if (err < 0)
735 739 goto out;
736 740 }