[Devel] [PATCH VZ10 v2 2/6] ve/namespace: Fix UAF in alloc_mnt_ns
Pavel Tikhomirov
ptikhomirov at virtuozzo.com
Tue Jul 21 18:57:01 MSK 2026
On 7/16/26 22:50, Vladimir Riabchun wrote:
> 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] <TASK>
> [ 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] </TASK>
>
> [ 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")
I think it should actually be:
Fixes: e9d24527e7897 ("ve/mntns: make mnt_namespace->ve_owner present in not CONFIG_VE case")
The mentioned above 229fd15908fe is the reason why it started to fail,
but it's not the patch we are fixing, we want to fix our patches which
add ve related stuff to free_mnt_ns().
Except that looks good.
Reviewed-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
> Signed-off-by: Vladimir Riabchun <vladimir.riabchun at virtuozzo.com>
> ---
> fs/namespace.c | 15 ++++++++++-----
> 1 file changed, 10 insertions(+), 5 deletions(-)
>
> diff --git a/fs/namespace.c b/fs/namespace.c
> index 0f4a3668e558..cd6aa2127203 100644
> --- a/fs/namespace.c
> +++ b/fs/namespace.c
> @@ -4179,17 +4179,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);
> }
> @@ -4283,6 +4287,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);
> }
--
Best regards, Pavel Tikhomirov
Senior Software Developer, Virtuozzo.
More information about the Devel
mailing list