oss-sec mailing list archives
CVE-2023-6817: Linux kernel: use-after-free in nf_tables
From: Xingyuan Mo <hdthky0 () gmail com>
Date: Fri, 22 Dec 2023 10:16:24 +0800
Hello, I found a use-after-free vulnerability in the implementation of pipapo set in Linux kernel nf_tables, which can lead to DoS or local privilege escalation, with CAP_NET_ADMIN capability required. The bug is fixed in v6.7-rc5 kernel and the patch is: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=317eb9685095678f2c9f5a8189de698c5354316a =*=*=*=*=*=*=*=*= Bug Details =*=*=*=*=*=*=*=*= According to the design of nf_tables, when calling NFT_MSG_DELSETELEM command without a set element specified, all elements in the target set will be deleted. During this process, nft_set_flush() is called, which calls set->ops->walk() at (0). static int nft_set_flush(struct nft_ctx *ctx, struct nft_set *set, u8 genmask) { struct nft_set_iter iter = { .genmask = genmask, .fn = nft_setelem_flush, }; set->ops->walk(ctx, set, &iter); <==== (0) if (!iter.err) iter.err = nft_set_catchall_flush(ctx, set); return iter.err; } If the backend is a pipapo set, nft_pipapo_walk() will be called. This function does not check the activeness of an element before operating on it, just like similar functions in other set backend such as nft_rhash_walk(). Thus NFT_MSG_DELSETELEM command can be called twice in one transaction to deleted every element in that set twice, resulting in double free. A POC is attached, which can be compiled with: gcc -o poc poc.c -lnftnl -lmnl I tested against v6.7-rc4 kernel and got a KASAN report as follows: [ 286.833955] ================================================================== [ 286.834580] BUG: KASAN: slab-use-after-free in nf_tables_trans_destroy_work+0x43c/0x630 [ 286.835253] Read of size 1 at addr ffff88800754ba88 by task kworker/0:0/8 [ 286.835931] CPU: 0 PID: 8 Comm: kworker/0:0 Not tainted 6.7.0-rc4 #1 [ 286.836440] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014 [ 286.837167] Workqueue: events nf_tables_trans_destroy_work [ 286.837619] Call Trace: [ 286.837825] <TASK> [ 286.838005] dump_stack_lvl+0x3b/0x50 [ 286.838316] print_report+0xcf/0x620 [ 286.838621] ? __virt_addr_valid+0xf7/0x180 [ 286.838974] ? nf_tables_trans_destroy_work+0x43c/0x630 [ 286.839397] ? kasan_complete_mode_report_info+0x80/0x210 [ 286.839839] ? nf_tables_trans_destroy_work+0x43c/0x630 [ 286.840269] kasan_report+0xbd/0x100 [ 286.840573] ? nf_tables_trans_destroy_work+0x43c/0x630 [ 286.841001] __asan_load1+0x66/0x70 [ 286.841297] nf_tables_trans_destroy_work+0x43c/0x630 [ 286.841719] ? __pfx_nf_tables_trans_destroy_work+0x10/0x10 [ 286.842175] ? read_word_at_a_time+0x12/0x20 [ 286.842528] ? kick_pool+0x39/0x1a0 [ 286.842829] process_one_work+0x2e4/0x5c0 [ 286.843167] worker_thread+0x520/0x790 [ 286.843491] ? __pfx_worker_thread+0x10/0x10 [ 286.843849] kthread+0x16e/0x1b0 [ 286.844119] ? __pfx_kthread+0x10/0x10 [ 286.844433] ret_from_fork+0x3b/0x70 [ 286.844750] ? __pfx_kthread+0x10/0x10 [ 286.845069] ret_from_fork_asm+0x1b/0x30 [ 286.845400] </TASK> [ 286.845735] Allocated by task 279: [ 286.846028] kasan_save_stack+0x2a/0x50 [ 286.846352] kasan_set_track+0x29/0x40 [ 286.846669] kasan_save_alloc_info+0x1f/0x30 [ 286.847030] __kasan_kmalloc+0x88/0xa0 [ 286.847344] __kmalloc+0x61/0x140 [ 286.847630] nft_set_elem_init+0x72/0x270 [ 286.847971] nft_add_set_elem+0xf7b/0x1bb0 [ 286.848315] nf_tables_newsetelem+0x3fb/0x4d0 [ 286.848699] nfnetlink_rcv_batch+0xcba/0xe90 [ 286.849055] nfnetlink_rcv+0x1df/0x220 [ 286.849375] netlink_unicast+0x3eb/0x540 [ 286.849703] netlink_sendmsg+0x44d/0x7d0 [ 286.850039] __sys_sendto+0x347/0x360 [ 286.850353] __x64_sys_sendto+0x7f/0xa0 [ 286.850681] do_syscall_64+0x46/0xf0 [ 286.850980] entry_SYSCALL_64_after_hwframe+0x6f/0x77 [ 286.851546] Freed by task 8: [ 286.851795] kasan_save_stack+0x2a/0x50 [ 286.852121] kasan_set_track+0x29/0x40 [ 286.852447] kasan_save_free_info+0x2f/0x50 [ 286.852804] __kasan_slab_free+0x113/0x1a0 [ 286.853155] __kmem_cache_free+0x82/0x1b0 [ 286.853496] kfree+0x78/0x120 [ 286.853752] nf_tables_trans_destroy_work+0x460/0x630 [ 286.854177] process_one_work+0x2e4/0x5c0 [ 286.854513] worker_thread+0x520/0x790 [ 286.854840] kthread+0x16e/0x1b0 [ 286.855113] ret_from_fork+0x3b/0x70 [ 286.855424] ret_from_fork_asm+0x1b/0x30 [ 286.855890] Last potentially related work creation: [ 286.856296] kasan_save_stack+0x2a/0x50 [ 286.856630] __kasan_record_aux_stack+0x92/0xa0 [ 286.857028] kasan_record_aux_stack_noalloc+0xf/0x20 [ 286.857449] kvfree_call_rcu+0x2c/0x470 [ 286.857769] kernfs_unlink_open_file+0x19c/0x1b0 [ 286.858155] kernfs_fop_release+0x6b/0x180 [ 286.858500] __fput+0x132/0x4e0 [ 286.858765] __fput_sync+0x35/0x40 [ 286.859065] __x64_sys_close+0x56/0xa0 [ 286.859390] do_syscall_64+0x46/0xf0 [ 286.859695] entry_SYSCALL_64_after_hwframe+0x6f/0x77 [ 286.860259] The buggy address belongs to the object at ffff88800754ba80 which belongs to the cache kmalloc-96 of size 96 [ 286.861228] The buggy address is located 8 bytes inside of freed 96-byte region [ffff88800754ba80, ffff88800754bae0) [ 286.862296] The buggy address belongs to the physical page: [ 286.862745] page:00000000f0d84d4e refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x754b [ 286.863468] anon flags: 0x100000000000800(slab|node=0|zone=1) [ 286.863929] page_type: 0xffffffff() [ 286.864219] raw: 0100000000000800 ffff888004c41780 ffffea00001bcb40 dead000000000005 [ 286.864849] raw: 0000000000000000 0000000000200020 00000001ffffffff 0000000000000000 [ 286.865451] page dumped because: kasan: bad access detected [ 286.866030] Memory state around the buggy address: [ 286.866412] ffff88800754b980: 00 00 00 00 00 00 00 00 00 00 04 fc fc fc fc fc [ 286.866977] ffff88800754ba00: 00 00 00 00 00 00 00 00 00 04 fc fc fc fc fc fc [ 286.867577] >ffff88800754ba80: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc [ 286.868185] ^ [ 286.868489] ffff88800754bb00: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc [ 286.869089] ffff88800754bb80: fa fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc [ 286.869690] ================================================================== =*=*=*=*=*=*=*=*= Discoverer =*=*=*=*=*=*=*=*= Xingyuan Mo of IceSword Lab Best, Xingyuan Mo
Attachment:
poc.c
Description:
Current thread:
- CVE-2023-6817: Linux kernel: use-after-free in nf_tables Xingyuan Mo (Dec 22)
- Re: CVE-2023-6817: Linux kernel: use-after-free in nf_tables Dominique Martinet (Dec 22)