Bug 205713 - Linux Kernel 4.19.83 - debugfs_remove use-after-free
Summary: Linux Kernel 4.19.83 - debugfs_remove use-after-free
Status: NEW
Alias: None
Product: File System
Classification: Unclassified
Component: Other (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: fs_other
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-11-29 17:37 UTC by Tristan Madani
Modified: 2020-02-06 07:50 UTC (History)
0 users

See Also:
Kernel Version: 4.19.83
Tree: Mainline
Regression: No


Attachments

Description Tristan Madani 2019-11-29 17:37:46 UTC
LINUX KERNEL 4.19.83 - debugfs_remove use-after-free

0x01 - Introduction
===

# Product: Linux Kernel 
# Version: 4.19.83 (and probably other versions)
# Bug: UAF (Read)
# Tested on: GNU/Linux Debian 9 x86_64


0x02 - Details
===

There is a UAF read in the debugfs_remove function which is used to removes a file or directory in 
debugfs that was previously created with a call to another debugfs function (like debugfs_create_file())

Code analysis (fs/debugfs/inode.c):

void debugfs_remove(struct dentry *dentry)
{
	struct dentry *parent;
	int ret;

	if (IS_ERR_OR_NULL(dentry))
		return;

	parent = dentry->d_parent; 		// UAF occurs here
	inode_lock(d_inode(parent));
	ret = __debugfs_remove(dentry, parent);
	inode_unlock(d_inode(parent));
	if (!ret)
		simple_release_fs(&debugfs_mount, &debugfs_mount_count);
}
../..


0x03 - Crash report
===

hpet1: lost 1 rtc interrupts
==================================================================
BUG: KASAN: use-after-free in debugfs_remove+0xfd/0x120 fs/debugfs/inode.c:687
Read of size 8 at addr ffff8880275e70c0 by task kworker/1:1/24

CPU: 1 PID: 24 Comm: kworker/1:1 Not tainted 4.19.83 #1
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-1 04/01/2014
Workqueue: events __blk_release_queue
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x138/0x22e lib/dump_stack.c:113
 print_address_description+0x67/0x26a mm/kasan/report.c:256
 kasan_report_error mm/kasan/report.c:354 [inline]
 kasan_report mm/kasan/report.c:412 [inline]
 kasan_report.cold.7+0x241/0x2fe mm/kasan/report.c:396
 debugfs_remove+0xfd/0x120 fs/debugfs/inode.c:687
 blk_trace_free+0x31/0x130 kernel/trace/blktrace.c:312
 blk_trace_cleanup kernel/trace/blktrace.c:339 [inline]
 __blk_trace_remove+0x70/0xa0 kernel/trace/blktrace.c:352
 blk_trace_shutdown+0x5e/0x80 kernel/trace/blktrace.c:752
 __blk_release_queue+0x21a/0x4b0 block/blk-sysfs.c:855
 process_one_work+0xbcd/0x1b50 kernel/workqueue.c:2153
 worker_thread+0x176/0x1200 kernel/workqueue.c:2296
 kthread+0x347/0x410 kernel/kthread.c:246
 ret_from_fork+0x3a/0x50 arch/x86/entry/entry_64.S:415

Allocated by task 4702:			// <--- where it has been allocated
 set_track mm/kasan/kasan.c:460 [inline]
 kasan_kmalloc mm/kasan/kasan.c:553 [inline]
 kasan_kmalloc+0xbf/0xe0 mm/kasan/kasan.c:531
 slab_post_alloc_hook mm/slab.h:445 [inline]
 slab_alloc_node mm/slub.c:2706 [inline]
 slab_alloc mm/slub.c:2714 [inline]
 kmem_cache_alloc+0xef/0x290 mm/slub.c:2719
 __d_alloc+0xbe/0xc60 fs/dcache.c:1610
 d_alloc+0x8f/0x300 fs/dcache.c:1694
 d_alloc_parallel+0x149/0x1c70 fs/dcache.c:2441
 __lookup_slow+0x1e6/0x510 fs/namei.c:1654
 lookup_one_len+0x1bd/0x200 fs/namei.c:2543
 start_creating fs/debugfs/inode.c:313 [inline]
 start_creating+0xbf/0x1f0 fs/debugfs/inode.c:289
 __debugfs_create_file+0x5e/0x3f0 fs/debugfs/inode.c:352
 do_blk_trace_setup+0x427/0xc80 kernel/trace/blktrace.c:528
 __blk_trace_setup+0xbc/0x170 kernel/trace/blktrace.c:577
 blk_trace_ioctl+0x161/0x2d0 kernel/trace/blktrace.c:716
 blkdev_ioctl+0x3fa/0x1fa0 block/ioctl.c:587
 block_ioctl+0xe9/0x130 fs/block_dev.c:1891
 vfs_ioctl fs/ioctl.c:46 [inline]
 file_ioctl fs/ioctl.c:501 [inline]
 do_vfs_ioctl+0x1c6/0x16f0 fs/ioctl.c:688
 ksys_ioctl+0x9b/0xc0 fs/ioctl.c:705
 __do_sys_ioctl fs/ioctl.c:712 [inline]
 __se_sys_ioctl fs/ioctl.c:710 [inline]
 __x64_sys_ioctl+0x6f/0xb0 fs/ioctl.c:710
 do_syscall_64+0x167/0x6c0 arch/x86/entry/common.c:293
 entry_SYSCALL_64_after_hwframe+0x49/0xbe

Freed by task 2115:					// <--- where it has been freed
 set_track mm/kasan/kasan.c:460 [inline]
 __kasan_slab_free+0x12e/0x180 mm/kasan/kasan.c:521
 slab_free_hook mm/slub.c:1371 [inline]
 slab_free_freelist_hook mm/slub.c:1398 [inline]
 slab_free mm/slub.c:2953 [inline]
 kmem_cache_free+0xc8/0x2e0 mm/slub.c:2969
 __rcu_reclaim kernel/rcu/rcu.h:236 [inline]
 rcu_do_batch kernel/rcu/tree.c:2584 [inline]
 invoke_rcu_callbacks kernel/rcu/tree.c:2897 [inline]
 __rcu_process_callbacks kernel/rcu/tree.c:2864 [inline]
 rcu_process_callbacks+0x133a/0x3350 kernel/rcu/tree.c:2881
 __do_softirq+0x2ae/0xa09 kernel/softirq.c:292

The buggy address belongs to the object at ffff8880275e7080
 which belongs to the cache dentry of size 288			// <--- the object's cache
The buggy address is located 64 bytes inside of
 288-byte region [ffff8880275e7080, ffff8880275e71a0)
The buggy address belongs to the page:
page:ffffea00009d7980 count:1 mapcount:0 mapping:ffff888035a5cc00 index:0xffff8880275e74a0 compound_mapcount: 0
flags: 0x100000000008100(slab|head)
raw: 0100000000008100 ffffea00009d5f08 ffffea00009d2088 ffff888035a5cc00
raw: ffff8880275e74a0 000000000017000a 00000001ffffffff 0000000000000000
hpet1: lost 1 rtc interrupts
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff8880275e6f80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff8880275e7000: fb fb fb fb fb fb fb fb fc fc fc fc fc fc fc fc
>ffff8880275e7080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                                           ^
 ffff8880275e7100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff8880275e7180: fb fb fb fb fc fc fc fc fc fc fc fc 00 00 00 00
==================================================================

Note You need to log in before you can comment on or make changes to this bug.