Overview
Some operation(with crafted f2fs filesystem image) can cause out of bounds read in ttm_put_pages
It may needs reboot(after run poc binary, not umount), or more tries to reproduce this vulnerability.
Same image and binary in CVE-2018-14616, but that was Null-Deref vulnerability and patched. This is Revoked vulnerability or other related slab-out-of-bounds read vulnerability in linux kernel vmwgfx or ttm module.
Target
Linux kernel f2fs FileSystem (Tested on 11/13/2019, used source with git clone git://kernel.ubuntu.com/ubuntu/linux.git, emulated on VMWare 15 WorkStation with VMWare tools)
| Linux Version | Availablity |
|---|---|
| 5.0.0-rc7 | True |
Reproduce
gcc -o poc poc_2019_19927.c
mkdir mnt
mount poc_2019_19927.img ./mnt
cp poc ./mnt
cd mnt
./poc
cd ..
sync
umount mntRoot cause
/* Put all pages in pages list to correct pool to wait for reuse */
static void ttm_put_pages(struct page **pages, unsigned npages, int flags,
enum ttm_caching_state cstate)
{
struct ttm_page_pool *pool = ttm_get_pool(flags, false, cstate);
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
struct ttm_page_pool *huge = ttm_get_pool(flags, true, cstate);
#endif
unsigned long irq_flags;
unsigned i;
if (pool == NULL) {
/* No pool for this memory type so free the pages */
i = 0;
while (i < npages) {
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
struct page *p = pages[i];
#endif
unsigned order = 0, j;
if (!pages[i]) {
++i;
continue;
}
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
if (!(flags & TTM_PAGE_FLAG_DMA32)) {
for (j = 0; j < HPAGE_PMD_NR; ++j)
[1] if (p++ != pages[i + j]) // CRASH HERE
break;
if (j == HPAGE_PMD_NR)
order = HPAGE_PMD_ORDER;
}
#endifIn line [1], pages[i+j] occurs out-of-bounds read.
Debugger / KASAN
KASAN log (the trailing repeated f2fs warning traces are truncated):
[ 12.920937] ==================================================================
[ 12.920954] BUG: KASAN: slab-out-of-bounds in ttm_put_pages+0x8bf/0x9c0 [ttm]
[ 12.920958] Read of size 8 at addr ffff888032301fa8 by task Xorg/891
[ 12.920964] CPU: 2 PID: 891 Comm: Xorg Not tainted 5.0.0-rc7-custom #1
[ 12.920966] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 04/13/2018
[ 12.920968] Call Trace:
[ 12.920974] dump_stack+0xd6/0x165
[ 12.920977] ? show_regs_print_info+0xb/0xb
[ 12.920981] ? printk+0x9c/0xc3
[ 12.920984] ? kmsg_dump_rewind_nolock+0x64/0x64
[ 12.920994] ? ttm_put_pages+0x8bf/0x9c0 [ttm]
[ 12.920998] print_address_description+0x78/0x290
[ 12.921007] ? ttm_put_pages+0x8bf/0x9c0 [ttm]
[ 12.921016] ? ttm_put_pages+0x8bf/0x9c0 [ttm]
[ 12.921019] kasan_report+0x149/0x18c
[ 12.921028] ? ttm_put_pages+0x8bf/0x9c0 [ttm]
[ 12.921032] __asan_load8+0x54/0x90
[ 12.921041] ttm_put_pages+0x8bf/0x9c0 [ttm]
[ 12.921051] ? ttm_pool_shrink_scan+0x170/0x170 [ttm]
[ 12.921055] ? kasan_check_write+0x14/0x20
[ 12.921059] ? iomem_map_sanity_check+0xd0/0x120
[ 12.921062] ? kasan_check_read+0x11/0x20
[ 12.921064] ? _raw_spin_lock+0x90/0xe0
[ 12.921067] ? _raw_write_lock_irq+0xf0/0xf0
[ 12.921076] ? ttm_mem_reg_ioremap+0x147/0x1c0 [ttm]
[ 12.921085] ? ttm_mem_global_free_zone+0x77/0xb0 [ttm]
[ 12.921096] ttm_pool_unpopulate_helper+0xd9/0x100 [ttm]
[ 12.921105] ttm_pool_unpopulate+0x21/0x30 [ttm]
[ 12.921123] vmw_ttm_unpopulate+0x70/0xe0 [vmwgfx]
[ 12.921132] ttm_tt_unpopulate.part.10+0xbc/0xd0 [ttm]
[ 12.921142] ttm_tt_destroy.part.11+0x8d/0x90 [ttm]
[ 12.921151] ttm_tt_destroy+0x13/0x20 [ttm]
[ 12.921160] ttm_bo_move_memcpy+0x90e/0x960 [ttm]
[ 12.921170] ? ttm_bo_kunmap+0x150/0x150 [ttm]
[ 12.921174] ? __mutex_lock_slowpath+0x20/0x20
[ 12.921184] ? ttm_mem_io_free_vm+0x196/0x1e0 [ttm]
[ 12.921187] ? kasan_check_write+0x14/0x20
[ 12.921190] ? mutex_unlock+0x22/0x40
[ 12.921202] ttm_bo_handle_move_mem+0xc90/0xcb0 [ttm]
[ 12.921204] ? _raw_write_lock_irq+0xf0/0xf0
[ 12.921214] ? ttm_bo_man_get_node+0xef/0x160 [ttm]
[ 12.921224] ? ttm_bo_add_move_fence.isra.18+0x31/0xc0 [ttm]
[ 12.921254] ? ttm_bo_mem_space+0x2a7/0x670 [ttm]
[ 12.921273] ttm_bo_validate+0x2a7/0x2e0 [ttm]
[ 12.921285] ? ttm_bo_evict_mm+0x70/0x70 [ttm]
[ 12.921288] ? _raw_write_lock_irq+0xf0/0xf0
[ 12.921299] ? ttm_eu_fence_buffer_objects+0x1c0/0x1c0 [ttm]
[ 12.921318] vmw_validation_bo_validate_single+0x116/0x160 [vmwgfx]
[ 12.921335] ? vmw_validation_res_reserve+0x2c0/0x2c0 [vmwgfx]
[ 12.921353] ? vmw_validation_res_reserve+0x210/0x2c0 [vmwgfx]
[ 12.921370] vmw_validation_bo_validate+0x178/0x1d0 [vmwgfx]
[ 12.921387] ? vmw_validation_bo_validate_single+0x160/0x160 [vmwgfx]
[ 12.921402] ? vmw_cmd_wait_query+0x220/0x220 [vmwgfx]
[ 12.921406] ? vzalloc+0x75/0x80
[ 12.921439] ? drm_ht_create+0x76/0xa0 [drm]
[ 12.921455] vmw_execbuf_process+0xf8a/0x1ec0 [vmwgfx]
[ 12.921490] ? vmw_cmd_wait_query+0x220/0x220 [vmwgfx]
[ 12.921511] ? __vmw_execbuf_release_pinned_bo+0x560/0x560 [vmwgfx]
[ 12.921516] ? unlock_page+0x86/0xf0
[ 12.921518] ? wake_up_page_bit+0x330/0x330
[ 12.921522] ? kasan_check_write+0x14/0x20
[ 12.921525] ? do_wp_page+0x51e/0x10a0
[ 12.921529] ? finish_mkwrite_fault+0x280/0x280
[ 12.921532] ? switch_mm_irqs_off+0x494/0xa80
[ 12.921538] ? __switch_to_asm+0x34/0x70
[ 12.921540] ? __switch_to_asm+0x34/0x70
[ 12.921543] ? __switch_to_asm+0x34/0x70
[ 12.921545] ? __switch_to_asm+0x34/0x70
[ 12.921548] ? __switch_to_asm+0x40/0x70
[ 12.921550] ? __switch_to_asm+0x34/0x70
[ 12.921552] ? __switch_to_asm+0x40/0x70
[ 12.921554] ? __switch_to_asm+0x34/0x70
[ 12.921556] ? __switch_to_asm+0x34/0x70
[ 12.921558] ? __switch_to_asm+0x40/0x70
[ 12.921561] ? __switch_to_asm+0x34/0x70
[ 12.921563] ? __switch_to_asm+0x40/0x70
[ 12.921566] ? _raw_spin_lock+0x90/0xe0
[ 12.921584] ? _raw_write_lock_irq+0xf0/0xf0
[ 12.921587] ? __schedule+0x529/0xe90
[ 12.921589] ? __account_cfs_rq_runtime+0x2f0/0x2f0
[ 12.921604] ? __ttm_read_lock+0x47/0x90 [vmwgfx]
[ 12.921651] ? ttm_read_lock+0x91/0x1a0 [vmwgfx]
[ 12.921668] ? ttm_read_unlock+0x50/0x50 [vmwgfx]
[ 12.921672] ? avc_has_extended_perms+0x4b6/0xa40
[ 12.921676] ? trace_event_raw_event_sched_process_exec+0x270/0x270
[ 12.921693] vmw_execbuf_ioctl+0x241/0x350 [vmwgfx]
[ 12.921710] ? vmw_execbuf_release_pinned_bo+0x50/0x50 [vmwgfx]
[ 12.921713] ? __rwsem_mark_wake+0x50c/0x5e0
[ 12.921717] ? kasan_check_read+0x11/0x20
[ 12.921720] ? __fget+0x2b1/0x350
[ 12.921737] vmw_generic_ioctl+0x3c2/0x440 [vmwgfx]
[ 12.921781] ? drm_ioctl_kernel+0x1d0/0x1d0 [drm]
[ 12.921795] ? vmw_probe+0x20/0x20 [vmwgfx]
[ 12.921798] ? rcu_cleanup_dead_rnp+0xa0/0xa0
[ 12.921801] ? kasan_check_read+0x11/0x20
[ 12.921815] vmw_unlocked_ioctl+0x15/0x20 [vmwgfx]
[ 12.921818] do_vfs_ioctl+0x150/0xad0
[ 12.921821] ? ioctl_preallocate+0x1b0/0x1b0
[ 12.921824] ? selinux_capable+0x30/0x30
[ 12.921827] ? handle_mm_fault+0x29b/0x4a0
[ 12.921831] ksys_ioctl+0x75/0x80
[ 12.921833] __x64_sys_ioctl+0x43/0x50
[ 12.921837] do_syscall_64+0x133/0x300
[ 12.921839] ? syscall_return_slowpath+0x200/0x200
[ 12.921842] ? do_page_fault+0x9a/0x270
[ 12.921844] ? __do_page_fault+0x600/0x600
[ 12.921847] ? prepare_exit_to_usermode+0xf8/0x170
[ 12.921849] ? perf_trace_sys_enter+0x500/0x500
[ 12.921852] ? calculate_sigpending+0x48/0x70
[ 12.921856] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 12.921858] RIP: 0033:0x7fe155b495d7
[ 12.921861] Code: b3 66 90 48 8b 05 b1 48 2d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 81 48 2d 00 f7 d8 64 89 01 48
[ 12.921863] RSP: 002b:00007ffd864c2a28 EFLAGS: 00003246 ORIG_RAX: 0000000000000010
[ 12.921865] RAX: ffffffffffffffda RBX: 00007ffd864c2bb8 RCX: 00007fe155b495d7
[ 12.921867] RDX: 00007ffd864c2aa0 RSI: 000000004020644c RDI: 000000000000000f
[ 12.921868] RBP: 00007ffd864c2aa0 R08: 0000000000000c80 R09: 0000000000000005
[ 12.921870] R10: 0000000000000039 R11: 0000000000003246 R12: 000000004020644c
[ 12.921871] R13: 000000000000000f R14: 000000000000004c R15: 0000000000000001
[ 12.921877] Allocated by task 891:
[ 12.921881] save_stack+0x43/0xd0
[ 12.921883] __kasan_kmalloc.constprop.8+0xa7/0xd0
[ 12.921885] kasan_kmalloc+0x9/0x10
[ 12.921887] __kmalloc_node+0x121/0x2f0
[ 12.921890] kvmalloc_node+0x31/0x80
[ 12.921897] ttm_tt_init+0xcb/0x130 [ttm]
[ 12.921910] vmw_ttm_tt_create+0xa8/0xe0 [vmwgfx]
[ 12.921917] ttm_tt_create+0xa3/0x110 [ttm]
[ 12.921925] ttm_bo_validate+0x28e/0x2e0 [ttm]
[ 12.921932] ttm_bo_init_reserved+0x8e5/0xa30 [ttm]
[ 12.921961] ttm_bo_init+0x138/0x210 [ttm]
[ 12.921978] vmw_bo_init+0x1b2/0x260 [vmwgfx]
[ 12.921995] vmw_user_bo_alloc+0x112/0x220 [vmwgfx]
[ 12.922012] vmw_bo_alloc_ioctl+0x117/0x280 [vmwgfx]
[ 12.922069] drm_ioctl_kernel+0x176/0x1d0 [drm]
[ 12.922119] drm_ioctl+0x58d/0x680 [drm]
[ 12.922135] vmw_generic_ioctl+0x2ed/0x440 [vmwgfx]
[ 12.922150] vmw_unlocked_ioctl+0x15/0x20 [vmwgfx]
[ 12.922153] do_vfs_ioctl+0x150/0xad0
[ 12.922155] ksys_ioctl+0x75/0x80
[ 12.922158] __x64_sys_ioctl+0x43/0x50
[ 12.922160] do_syscall_64+0x133/0x300
[ 12.922163] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 12.922166] Freed by task 442:
[ 12.922170] save_stack+0x43/0xd0
[ 12.922173] __kasan_slab_free+0x135/0x190
[ 12.922175] kasan_slab_free+0xe/0x10
[ 12.922178] kfree+0x98/0x1d0
[ 12.922180] kvfree+0x2a/0x40
[ 12.922183] single_release+0x3f/0x60
[ 12.922185] __fput+0x21a/0x510
[ 12.922187] ____fput+0xe/0x10
[ 12.922206] task_work_run+0x14a/0x1a0
[ 12.922208] exit_to_usermode_loop+0x227/0x240
[ 12.922210] do_syscall_64+0x2d8/0x300
[ 12.922212] entry_SYSCALL_64_after_hwframe+0x44/0xa9
[ 12.922215] The buggy address belongs to the object at ffff888032301100
which belongs to the cache kmalloc-4k of size 4096
[ 12.922219] The buggy address is located 3752 bytes inside of
4096-byte region [ffff888032301100, ffff888032302100)
[ 12.922220] The buggy address belongs to the page:
[ 12.922244] page:ffffea0000c8c000 count:1 mapcount:0 mapping:ffff88805a80e840 index:0x0 compound_mapcount: 0
[ 12.922248] flags: 0xfffffc0010200(slab|head)
[ 12.922252] raw: 000fffffc0010200 0000000000000000 0000000100000001 ffff88805a80e840
[ 12.922255] raw: 0000000000000000 0000000000070007 00000001ffffffff 0000000000000000
[ 12.922256] page dumped because: kasan: bad access detected
[ 12.922258] Memory state around the buggy address:
[ 12.922262] ffff888032301e80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 12.922265] ffff888032301f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 12.922268] >ffff888032301f80: 00 00 00 00 00 fc fc fc fc fc fc fc fc fc fc fc
[ 12.922270] ^
[ 12.922273] ffff888032302000: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 12.922276] ffff888032302080: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[ 12.922277] ==================================================================
[ 12.922279] Disabling lock debugging due to kernel taint
...
Details
CVSS 6.0 (CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:H/I:N/A:H), CWE-125, published 2019-12-31, last modified 2024-11-21.
Attribution
Found as part of the Best of the Best (BoB) 8th bobfuzzer team project — a five-person team that ported the JANUS file-system fuzzer. This is team work, not sole authorship.