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 <[email protected]>
---
 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);
        }
-- 
2.47.1

_______________________________________________
Devel mailing list
[email protected]
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to