From mboxrd@z Thu Jan 1 00:00:00 1970 From: Vladimir Riabchun Date: Mon, 24 Aug 2026 13:54:44 +0000 Subject: [Devel] [PATCH VZ10 v7 2/9] ve/namespace: Fix UAF in alloc_mnt_ns In-Reply-To: References: Message-ID: <1e9eba2a0242904a51efa8211cc3ab0e29116ad7.1787579160.git.vladimir.riabchun@virtuozzo.com> List-Id: KASAN reports a UAF in alloc_mnt_ns when running ve_ns_owner_test selftest with low per-VE mount limit: [ 2011.939093] CT#0 reached the limit on mounts. [ 2012.049101] ================================================================== [ 2012.050328] BUG: KASAN: slab-use-after-free in __list_add_valid_or_report+0xaa/0xb0 [ 2012.051686] Read of size 8 at addr ffff8881f4321cd0 by task (coredump)/6230 [ 2012.053069] CPU: 1 UID: 0 PID: 6230 Comm: (coredump) ve: 0 Kdump: loaded Not tainted 6.12.0-211.16.1.12.5.ovz10-v3-debug #1 12.5.ovz10 PREEMPT(voluntary) [ 2012.053076] Hardware name: Acronis OpenStack Compute/Virtuozzo, BIOS 1.16.1-1.vz9.2 04/01/2014 [ 2012.053079] Call Trace: [ 2012.053083] [ 2012.053087] dump_stack_lvl+0x6f/0xb0 [ 2012.053097] ? __list_add_valid_or_report+0xaa/0xb0 [ 2012.053102] print_address_description.constprop.0+0x88/0x380 [ 2012.053109] ? __list_add_valid_or_report+0xaa/0xb0 [ 2012.053113] print_report+0x108/0x209 [ 2012.053117] ? __virt_addr_valid+0x1a3/0x370 [ 2012.053123] ? __list_add_valid_or_report+0xaa/0xb0 [ 2012.053127] kasan_report+0xa3/0xe0 [ 2012.053133] ? __list_add_valid_or_report+0xaa/0xb0 [ 2012.053139] __list_add_valid_or_report+0xaa/0xb0 [ 2012.053143] alloc_mnt_ns+0x25c/0x620 [ 2012.053149] open_detached_copy+0xa4/0x480 [ 2012.053155] __x64_sys_open_tree+0x2c2/0x330 [ 2012.053161] ? __pfx___x64_sys_open_tree+0x10/0x10 [ 2012.053168] do_syscall_64+0x92/0x180 [ 2012.053175] ? rcu_is_watching+0x15/0xb0 [ 2012.053180] ? trace_irq_enable.constprop.0+0x14d/0x1c0 [ 2012.053187] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 2012.053193] RIP: 0033:0x7f096c12db3b [ 2012.053219] Code: 73 01 c3 48 8b 0d d5 82 0c 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa b8 ac 01 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d a5 82 0c 00 f7 d8 64 89 01 48 [ 2012.053223] RSP: 002b:00007ffce7d6dff8 EFLAGS: 00000206 ORIG_RAX: 00000000000001ac [ 2012.053230] RAX: ffffffffffffffda RBX: 000055ab331ebdc0 RCX: 00007f096c12db3b [ 2012.053234] RDX: 0000000000081001 RSI: 000055ab220012fb RDI: 0000000000000003 [ 2012.053237] RBP: 00007ffce7d6e190 R08: 0000000000000000 R09: 000055ab331f12e0 [ 2012.053241] R10: 000055ab331ebe40 R11: 0000000000000206 R12: 000055ab331ecd50 [ 2012.053244] R13: 00007ffce7d6e7f0 R14: 00007ffce7d6e900 R15: 000055ab331ebdc0 [ 2012.053256] [ 2012.080481] Allocated by task 6228: [ 2012.081075] kasan_save_stack+0x30/0x50 [ 2012.081723] kasan_save_track+0x14/0x30 [ 2012.082358] __kasan_kmalloc+0x8f/0xa0 [ 2012.082976] alloc_mnt_ns+0xcf/0x620 [ 2012.083576] copy_mnt_ns+0xb2/0xa30 [ 2012.084159] create_new_namespaces+0xd7/0x940 [ 2012.084946] copy_namespaces+0x323/0x3f0 [ 2012.085605] copy_process+0x1d3c/0x53e0 [ 2012.086235] kernel_clone+0xc8/0x5f0 [ 2012.086928] __do_sys_clone3+0x172/0x1c0 [ 2012.087599] do_syscall_64+0x92/0x180 [ 2012.088218] entry_SYSCALL_64_after_hwframe+0x76/0x7e [ 2012.089332] Freed by task 6228: [ 2012.089871] kasan_save_stack+0x30/0x50 [ 2012.090497] kasan_save_track+0x14/0x30 [ 2012.091262] kasan_save_free_info+0x3b/0x70 [ 2012.091944] __kasan_slab_free+0x37/0x50 [ 2012.092631] kfree+0x129/0x3f0 [ 2012.093194] copy_mnt_ns+0x74e/0xa30 [ 2012.093817] create_new_namespaces+0xd7/0x940 [ 2012.094554] copy_namespaces+0x323/0x3f0 [ 2012.095215] copy_process+0x1d3c/0x53e0 [ 2012.095868] kernel_clone+0xc8/0x5f0 [ 2012.096503] __do_sys_clone3+0x172/0x1c0 [ 2012.097174] do_syscall_64+0x92/0x180 [ 2012.097770] entry_SYSCALL_64_after_hwframe+0x76/0x7e The root cause is an incorrect rebase in commit 229fd15908fe ("fs: don't try and remove empty rbtree node"). The error path in copy_mnt_ns didn't include list removal, so after the free list contained an invalid element. To reduce the probability of such issues in the future, extract ve-specific logic in a special helper and use it in free_mnt_ns and copy_mnt_ns error path. https://virtuozzo.atlassian.net/browse/VSTOR-135520 Fixes: 229fd15908fe ("fs: don't try and remove empty rbtree node") Signed-off-by: Vladimir Riabchun --- fs/namespace.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/fs/namespace.c b/fs/namespace.c index 4d4dc5290350..68e0efb73d7c 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -4243,17 +4243,21 @@ static void dec_mnt_namespaces(struct ucounts *ucounts) static LIST_HEAD(all_mntns_list); static DEFINE_SPINLOCK(all_mntns_list_lock); -static void free_mnt_ns(struct mnt_namespace *ns) +static void ve_cleanup_mnt_ns(struct mnt_namespace *ns) { - if (!is_anon_ns(ns)) - ns_free_inum(&ns->ns); - dec_mnt_namespaces(ns->ucounts); - spin_lock(&all_mntns_list_lock); list_del(&ns->mntns_list); spin_unlock(&all_mntns_list_lock); put_ve(ns->ve_owner); +} + +static void free_mnt_ns(struct mnt_namespace *ns) +{ + if (!is_anon_ns(ns)) + ns_free_inum(&ns->ns); + dec_mnt_namespaces(ns->ucounts); + ve_cleanup_mnt_ns(ns); mnt_ns_tree_remove(ns); } @@ -4347,6 +4351,7 @@ struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns, namespace_unlock(); ns_free_inum(&new_ns->ns); dec_mnt_namespaces(new_ns->ucounts); + ve_cleanup_mnt_ns(new_ns); mnt_ns_release(new_ns); return ERR_CAST(new); } -- 2.47.1