Oscar Salvador d1a37f
From 153695d36ead0ccc4d0256953c751cabf673e621 Mon Sep 17 00:00:00 2001
Oscar Salvador d1a37f
From: Zeng Heng <zengheng4@huawei.com>
Oscar Salvador d1a37f
Date: Thu, 27 Oct 2022 20:45:28 +0800
Oscar Salvador d1a37f
Subject: [PATCH] cifs: fix use-after-free caused by invalid pointer `hostname`
Oscar Salvador d1a37f
References: bsc#1208971
Oscar Salvador d1a37f
Git-commit: 153695d36ead0ccc4d0256953c751cabf673e621
Oscar Salvador d1a37f
Patch-mainline: v6.1
Oscar Salvador d1a37f
Oscar Salvador d1a37f
`hostname` needs to be set as null-pointer after free in
Oscar Salvador d1a37f
`cifs_put_tcp_session` function, or when `cifsd` thread attempts
Oscar Salvador d1a37f
to resolve hostname and reconnect the host, the thread would deref
Oscar Salvador d1a37f
the invalid pointer.
Oscar Salvador d1a37f
Oscar Salvador d1a37f
Here is one of practical backtrace examples as reference:
Oscar Salvador d1a37f
Oscar Salvador d1a37f
Task 477
Oscar Salvador d1a37f
---------------------------
Oscar Salvador d1a37f
 do_mount
Oscar Salvador d1a37f
  path_mount
Oscar Salvador d1a37f
   do_new_mount
Oscar Salvador d1a37f
    vfs_get_tree
Oscar Salvador d1a37f
     smb3_get_tree
Oscar Salvador d1a37f
      smb3_get_tree_common
Oscar Salvador d1a37f
       cifs_smb3_do_mount
Oscar Salvador d1a37f
        cifs_mount
Oscar Salvador d1a37f
         mount_put_conns
Oscar Salvador d1a37f
          cifs_put_tcp_session
Oscar Salvador d1a37f
          --> kfree(server->hostname)
Oscar Salvador d1a37f
Oscar Salvador d1a37f
cifsd
Oscar Salvador d1a37f
---------------------------
Oscar Salvador d1a37f
 kthread
Oscar Salvador d1a37f
  cifs_demultiplex_thread
Oscar Salvador d1a37f
   cifs_reconnect
Oscar Salvador d1a37f
    reconn_set_ipaddr_from_hostname
Oscar Salvador d1a37f
    --> if (!server->hostname)
Oscar Salvador d1a37f
    --> if (server->hostname[0] == '\0')  // !! UAF fault here
Oscar Salvador d1a37f
Oscar Salvador d1a37f
CIFS: VFS: cifs_mount failed w/return code = -112
Oscar Salvador d1a37f
mount error(112): Host is down
Oscar Salvador d1a37f
BUG: KASAN: use-after-free in reconn_set_ipaddr_from_hostname+0x2ba/0x310
Oscar Salvador d1a37f
Read of size 1 at addr ffff888108f35380 by task cifsd/480
Oscar Salvador d1a37f
CPU: 2 PID: 480 Comm: cifsd Not tainted 6.1.0-rc2-00106-gf705792f89dd-dirty #25
Oscar Salvador d1a37f
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
Oscar Salvador d1a37f
Call Trace:
Oscar Salvador d1a37f
 <TASK>
Oscar Salvador d1a37f
 dump_stack_lvl+0x68/0x85
Oscar Salvador d1a37f
 print_report+0x16c/0x4a3
Oscar Salvador d1a37f
 kasan_report+0x95/0x190
Oscar Salvador d1a37f
 reconn_set_ipaddr_from_hostname+0x2ba/0x310
Oscar Salvador d1a37f
 __cifs_reconnect.part.0+0x241/0x800
Oscar Salvador d1a37f
 cifs_reconnect+0x65f/0xb60
Oscar Salvador d1a37f
 cifs_demultiplex_thread+0x1570/0x2570
Oscar Salvador d1a37f
 kthread+0x2c5/0x380
Oscar Salvador d1a37f
 ret_from_fork+0x22/0x30
Oscar Salvador d1a37f
 </TASK>
Oscar Salvador d1a37f
Allocated by task 477:
Oscar Salvador d1a37f
 kasan_save_stack+0x1e/0x40
Oscar Salvador d1a37f
 kasan_set_track+0x21/0x30
Oscar Salvador d1a37f
 __kasan_kmalloc+0x7e/0x90
Oscar Salvador d1a37f
 __kmalloc_node_track_caller+0x52/0x1b0
Oscar Salvador d1a37f
 kstrdup+0x3b/0x70
Oscar Salvador d1a37f
 cifs_get_tcp_session+0xbc/0x19b0
Oscar Salvador d1a37f
 mount_get_conns+0xa9/0x10c0
Oscar Salvador d1a37f
 cifs_mount+0xdf/0x1970
Oscar Salvador d1a37f
 cifs_smb3_do_mount+0x295/0x1660
Oscar Salvador d1a37f
 smb3_get_tree+0x352/0x5e0
Oscar Salvador d1a37f
 vfs_get_tree+0x8e/0x2e0
Oscar Salvador d1a37f
 path_mount+0xf8c/0x1990
Oscar Salvador d1a37f
 do_mount+0xee/0x110
Oscar Salvador d1a37f
 __x64_sys_mount+0x14b/0x1f0
Oscar Salvador d1a37f
 do_syscall_64+0x3b/0x90
Oscar Salvador d1a37f
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Oscar Salvador d1a37f
Freed by task 477:
Oscar Salvador d1a37f
 kasan_save_stack+0x1e/0x40
Oscar Salvador d1a37f
 kasan_set_track+0x21/0x30
Oscar Salvador d1a37f
 kasan_save_free_info+0x2a/0x50
Oscar Salvador d1a37f
 __kasan_slab_free+0x10a/0x190
Oscar Salvador d1a37f
 __kmem_cache_free+0xca/0x3f0
Oscar Salvador d1a37f
 cifs_put_tcp_session+0x30c/0x450
Oscar Salvador d1a37f
 cifs_mount+0xf95/0x1970
Oscar Salvador d1a37f
 cifs_smb3_do_mount+0x295/0x1660
Oscar Salvador d1a37f
 smb3_get_tree+0x352/0x5e0
Oscar Salvador d1a37f
 vfs_get_tree+0x8e/0x2e0
Oscar Salvador d1a37f
 path_mount+0xf8c/0x1990
Oscar Salvador d1a37f
 do_mount+0xee/0x110
Oscar Salvador d1a37f
 __x64_sys_mount+0x14b/0x1f0
Oscar Salvador d1a37f
 do_syscall_64+0x3b/0x90
Oscar Salvador d1a37f
 entry_SYSCALL_64_after_hwframe+0x63/0xcd
Oscar Salvador d1a37f
The buggy address belongs to the object at ffff888108f35380
Oscar Salvador d1a37f
 which belongs to the cache kmalloc-16 of size 16
Oscar Salvador d1a37f
The buggy address is located 0 bytes inside of
Oscar Salvador d1a37f
 16-byte region [ffff888108f35380, ffff888108f35390)
Oscar Salvador d1a37f
The buggy address belongs to the physical page:
Oscar Salvador d1a37f
page:00000000333f8e58 refcount:1 mapcount:0 mapping:0000000000000000 index:0xffff888108f350e0 pfn:0x108f35
Oscar Salvador d1a37f
flags: 0x200000000000200(slab|node=0|zone=2)
Oscar Salvador d1a37f
raw: 0200000000000200 0000000000000000 dead000000000122 ffff8881000423c0
Oscar Salvador d1a37f
raw: ffff888108f350e0 000000008080007a 00000001ffffffff 0000000000000000
Oscar Salvador d1a37f
page dumped because: kasan: bad access detected
Oscar Salvador d1a37f
Memory state around the buggy address:
Oscar Salvador d1a37f
 ffff888108f35280: fa fb fc fc fa fb fc fc fa fb fc fc fa fb fc fc
Oscar Salvador d1a37f
 ffff888108f35300: fa fb fc fc fa fb fc fc fa fb fc fc fa fb fc fc
Oscar Salvador d1a37f
>ffff888108f35380: fa fb fc fc fa fb fc fc fa fb fc fc fa fb fc fc
Oscar Salvador d1a37f
                   ^
Oscar Salvador d1a37f
 ffff888108f35400: fa fb fc fc fc fc fc fc fc fc fc fc fc fc fc fc
Oscar Salvador d1a37f
 ffff888108f35480: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
Oscar Salvador d1a37f
Oscar Salvador d1a37f
Fixes: 7be3248f3139 ("cifs: To match file servers, make sure the server hostname matches")
Oscar Salvador d1a37f
Signed-off-by: Zeng Heng <zengheng4@huawei.com>
Oscar Salvador d1a37f
Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Oscar Salvador d1a37f
Signed-off-by: Steve French <stfrench@microsoft.com>
Oscar Salvador d1a37f
Signed-off-by: Oscar Salvador <osalvador@suse.de>
Oscar Salvador d1a37f
---
Oscar Salvador d1a37f
 fs/cifs/connect.c | 1 +
Oscar Salvador d1a37f
 1 file changed, 1 insertion(+)
Oscar Salvador d1a37f
Oscar Salvador d1a37f
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
Oscar Salvador d1a37f
index ffb291579bb9..1cc47dd3b4d6 100644
Oscar Salvador d1a37f
--- a/fs/cifs/connect.c
Oscar Salvador d1a37f
+++ b/fs/cifs/connect.c
Oscar Salvador d1a37f
@@ -1584,6 +1584,7 @@ cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
Oscar Salvador d1a37f
 	server->session_key.response = NULL;
Oscar Salvador d1a37f
 	server->session_key.len = 0;
Oscar Salvador d1a37f
 	kfree(server->hostname);
Oscar Salvador d1a37f
+	server->hostname = NULL;
Oscar Salvador d1a37f
 
Oscar Salvador d1a37f
 	task = xchg(&server->tsk, NULL);
Oscar Salvador d1a37f
 	if (task)
Oscar Salvador d1a37f
-- 
Oscar Salvador d1a37f
2.35.3
Oscar Salvador d1a37f