Patch "netfilter: nf_tables: unregister flowtable hooks on netns exit" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    netfilter: nf_tables: unregister flowtable hooks on netns exit

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     netfilter-nf_tables-unregister-flowtable-hooks-on-ne.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit d4e0e230dc64b104adbbc089f94d8f09e086d95d
Author: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
Date:   Wed Sep 27 17:30:06 2023 +0200

    netfilter: nf_tables: unregister flowtable hooks on netns exit
    
    commit 6069da443bf65f513bb507bb21e2f87cfb1ad0b6 upstream.
    
    Unregister flowtable hooks before they are releases via
    nf_tables_flowtable_destroy() otherwise hook core reports UAF.
    
    BUG: KASAN: use-after-free in nf_hook_entries_grow+0x5a7/0x700 net/netfilter/core.c:142 net/netfilter/core.c:142
    Read of size 4 at addr ffff8880736f7438 by task syz-executor579/3666
    
    CPU: 0 PID: 3666 Comm: syz-executor579 Not tainted 5.16.0-rc5-syzkaller #0
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
    Call Trace:
     <TASK>
     __dump_stack lib/dump_stack.c:88 [inline]
     __dump_stack lib/dump_stack.c:88 [inline] lib/dump_stack.c:106
     dump_stack_lvl+0x1dc/0x2d8 lib/dump_stack.c:106 lib/dump_stack.c:106
     print_address_description+0x65/0x380 mm/kasan/report.c:247 mm/kasan/report.c:247
     __kasan_report mm/kasan/report.c:433 [inline]
     __kasan_report mm/kasan/report.c:433 [inline] mm/kasan/report.c:450
     kasan_report+0x19a/0x1f0 mm/kasan/report.c:450 mm/kasan/report.c:450
     nf_hook_entries_grow+0x5a7/0x700 net/netfilter/core.c:142 net/netfilter/core.c:142
     __nf_register_net_hook+0x27e/0x8d0 net/netfilter/core.c:429 net/netfilter/core.c:429
     nf_register_net_hook+0xaa/0x180 net/netfilter/core.c:571 net/netfilter/core.c:571
     nft_register_flowtable_net_hooks+0x3c5/0x730 net/netfilter/nf_tables_api.c:7232 net/netfilter/nf_tables_api.c:7232
     nf_tables_newflowtable+0x2022/0x2cf0 net/netfilter/nf_tables_api.c:7430 net/netfilter/nf_tables_api.c:7430
     nfnetlink_rcv_batch net/netfilter/nfnetlink.c:513 [inline]
     nfnetlink_rcv_skb_batch net/netfilter/nfnetlink.c:634 [inline]
     nfnetlink_rcv_batch net/netfilter/nfnetlink.c:513 [inline] net/netfilter/nfnetlink.c:652
     nfnetlink_rcv_skb_batch net/netfilter/nfnetlink.c:634 [inline] net/netfilter/nfnetlink.c:652
     nfnetlink_rcv+0x10e6/0x2550 net/netfilter/nfnetlink.c:652 net/netfilter/nfnetlink.c:652
    
    __nft_release_hook() calls nft_unregister_flowtable_net_hooks() which
    only unregisters the hooks, then after RCU grace period, it is
    guaranteed that no packets add new entries to the flowtable (no flow
    offload rules and flowtable hooks are reachable from packet path), so it
    is safe to call nf_flow_table_free() which cleans up the remaining
    entries from the flowtable (both software and hardware) and it unbinds
    the flow_block.
    
    Fixes: ff4bf2f42a40 ("netfilter: nf_tables: add nft_unregister_flowtable_hook()")
    Reported-by: syzbot+e918523f77e62790d6d9@xxxxxxxxxxxxxxxxxxxxxxxxx
    Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 52c776b5967ef..efbcf85cd6b7a 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -9466,16 +9466,24 @@ int __nft_release_basechain(struct nft_ctx *ctx)
 }
 EXPORT_SYMBOL_GPL(__nft_release_basechain);
 
+static void __nft_release_hook(struct net *net, struct nft_table *table)
+{
+	struct nft_flowtable *flowtable;
+	struct nft_chain *chain;
+
+	list_for_each_entry(chain, &table->chains, list)
+		nf_tables_unregister_hook(net, table, chain);
+	list_for_each_entry(flowtable, &table->flowtables, list)
+		nft_unregister_flowtable_net_hooks(net, &flowtable->hook_list);
+}
+
 static void __nft_release_hooks(struct net *net)
 {
 	struct nftables_pernet *nft_net = net_generic(net, nf_tables_net_id);
 	struct nft_table *table;
-	struct nft_chain *chain;
 
-	list_for_each_entry(table, &nft_net->tables, list) {
-		list_for_each_entry(chain, &table->chains, list)
-			nf_tables_unregister_hook(net, table, chain);
-	}
+	list_for_each_entry(table, &nft_net->tables, list)
+		__nft_release_hook(net, table);
 }
 
 static void __nft_release_table(struct net *net, struct nft_table *table)



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux