[Devel] [PATCH VZ10 2/6] ve/namespace: Fix UAF in alloc_mnt_ns
Vladimir Riabchun
vladimir.riabchun at virtuozzo.com
Tue Jun 30 20:13:28 MSK 2026
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")
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 566f11a222fc..d2fa363b9a56 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);
}
--
2.47.1
More information about the Devel
mailing list