oss-sec mailing list archives

Linux kernel: stack-out-of-bounds in profile_pc


From: 黄 晓 <NigelXiao () outlook com>
Date: Thu, 18 Aug 2022 05:41:30 +0000

Hello:
      
      I found a bug through the syzkaller fuzz tool, you need to set CONFIG_KASAN=y, the crash information is displayed 
as out-of-bounds reading, I am weak and unable to analyze the harm of this bug.
The bug program cannot be reproduced stably and needs to be run multiple times.

Kernel version: 5.18.14
gcc version: 9.4.0


[   49.449543] ==================================================================
[   49.463836] BUG: KASAN: stack-out-of-bounds in profile_pc+0x59/0x90
[   49.466434] Read of size 8 at addr ffff88800a137cd0 by task sh/105
[   49.466879]
[   49.467144] CPU: 2 PID: 105 Comm: sh Not tainted 5.17.9 #3
[   49.467436] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
[   49.467774] Call Trace:
[   49.467954]  <IRQ>
[   49.468121]  dump_stack_lvl+0x34/0x44
[   49.474368]  print_address_description.constprop.0+0x21/0x150
[   49.478895]  ? profile_pc+0x59/0x90
[   49.479192]  ? profile_pc+0x59/0x90
[   49.479479]  kasan_report.cold+0x7f/0x11b
[   49.479684]  ? profile_pc+0x59/0x90
[   49.479874]  ? _raw_spin_lock+0x92/0xd0
[   49.480112]  profile_pc+0x59/0x90
[   49.480438]  profile_tick+0x67/0x90
[   49.480974]  tick_sched_timer+0x7c/0xa0
[   49.482393]  __hrtimer_run_queues+0x1c6/0x420
[   49.482901]  ? tick_sched_handle.isra.0+0x80/0x80
[   49.483139]  ? enqueue_hrtimer+0xf0/0xf0
[   49.483329]  ? _raw_read_lock_bh+0x40/0x40
[   49.483669]  ? recalibrate_cpu_khz+0x10/0x10
[   49.483959]  ? recalibrate_cpu_khz+0x10/0x10
[   49.484137]  ? ktime_get_update_offsets_now+0x96/0x150
[   49.484531]  hrtimer_interrupt+0x1b6/0x350
[   49.484777]  __sysvec_apic_timer_interrupt+0xac/0x200
[   49.485025]  sysvec_apic_timer_interrupt+0x89/0xc0
[   49.485554]  </IRQ>
[   49.485759]  <TASK>
[   49.485879]  asm_sysvec_apic_timer_interrupt+0x12/0x20
[   49.486309] RIP: 0010:_raw_spin_lock+0x92/0xd0
[   49.486720] Code: 24 20 00 00 00 00 e8 0d 82 ee fe be 04 00 00 00 48 8d 7c 24 20 e8 fe 81 ee fe ba 01 00 00 00 8b 44 
24 20 f0 0f b1 55 00 75 29 <48> b8 00 00 00 00 00 fc ff df 48 c7 04 03 00 00 00 004
[   49.487645] RSP: 0000:ffff88800a137cd0 EFLAGS: 00000246
[   49.488392] RAX: 0000000000000000 RBX: 1ffff11001426f9a RCX: ffffffff82445932
[   49.488762] RDX: 0000000000000001 RSI: 0000000000000004 RDI: ffff88800a137cf0
[   49.489162] RBP: ffffea000027f228 R08: 0000000000000001 R09: ffffed1001426f9f
[   49.489577] R10: 0000000000000003 R11: ffffed1001426f9e R12: 0000000009fc8067
[   49.489926] R13: ffff888000000688 R14: 000fffffffe00000 R15: 0000000009fc8067
[   49.490285]  ? _raw_spin_lock+0x82/0xd0
[   49.490602]  ? _raw_spin_lock_irqsave+0xe0/0xe0
[   49.490844]  ? _raw_spin_unlock+0x16/0x30
[   49.491148]  ? do_wp_page+0x389/0x5f0
[   49.491368]  __handle_mm_fault+0x633/0x10d0
[   49.491576]  ? __pmd_alloc+0x240/0x240
[   49.491764]  ? down_read_trylock+0x102/0x160
[   49.491978]  handle_mm_fault+0x99/0x220
[   49.492183]  do_user_addr_fault+0x272/0x870
[   49.492380]  exc_page_fault+0x57/0xc0
[   49.492577]  ? asm_exc_page_fault+0x8/0x30
[   49.492775]  asm_exc_page_fault+0x1e/0x30
[   49.492975] RIP: 0033:0x44c5ba
[   49.493374] Code: 00 48 8d 57 07 48 83 fa 0e 76 09 48 c1 ff 03 e8 29 d2 ff ff 49 83 c7 08 eb b1 c6 83 d1 00 00 00 00 
e8 b4 c1 ff ff 41 83 fd 02 <c6> 05 38 4b 28 00 00 0f 84 a7 00 00 00 41 f6 44 24 1f5
[   49.494114] RSP: 002b:00007fff75b9d630 EFLAGS: 00000293
[   49.494334] RAX: 0000000001c5b010 RBX: 0000000001c5b010 RCX: 00007f6523d29760
[   49.494599] RDX: 0000000000000000 RSI: 0000000001c5b370 RDI: 0000000000000000
[   49.494922] RBP: 0000000001c5b370 R08: 00007f652424f740 R09: 0000000000000000
[   49.495274] R10: 00007f652424fa10 R11: 0000000000000246 R12: 0000000001c5d950
[   49.495550] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000001c5b2f0
[   49.495851]  </TASK>
[   49.496028]
[   49.496167] The buggy address belongs to the page:
[   49.496496] page:(____ptrval____) refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xa137
[   49.497096] flags: 0x100000000000000(node=0|zone=1)
[   49.497612] raw: 0100000000000000 ffffea0000284dc8 ffffea0000284dc8 0000000000000000
[   49.497851] raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000
[   49.498061] page dumped because: kasan: bad access detected
[   49.498263]
[   49.498325] addr ffff88800a137cd0 is located in stack of task sh/105 at offset 0 in frame:
[   49.498527]  _raw_spin_lock+0x0/0xd0
[   49.498920]
[   49.498992] this frame has 1 object:
[   49.501589]  [32, 36) 'val'
[   49.501741]
[   49.502017] Memory state around the buggy address:
[   49.502406]  ffff88800a137b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   49.502818]  ffff88800a137c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[   49.503125] >ffff88800a137c80: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 04 f3
[   49.503502]                                                  ^
[   49.504015]  ffff88800a137d00: f3 f3 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1
[   49.504269]  ffff88800a137d80: f1 f1 f1 00 00 00 00 00 00 00 00 00 00 00 00 00
[   49.504626] ==================================================================
[   49.504961] Disabling lock debugging due to kernel taint

POC:
'''
#define _GNU_SOURCE

#include <endian.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

uint64_t r[1] = {0xffffffffffffffff};

int main(void)
{
  syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
  syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
  syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
  intptr_t res = 0;
  memcpy((void*)0x20000040, "/sys/kernel/profiling", 21);
  res =
      syscall(__NR_openat, 0xffffffffffffff9cul, 0x20000040ul, 0xe8502ul, 0ul);
  if (res != -1)
    r[0] = res;
  sprintf((char*)0x200000c0, "%023llo", (long long)r[0]);
  sprintf((char*)0x200000d7, "%020llu", (long long)-1);
  sprintf((char*)0x200000eb, "%023llo", (long long)-1);
  sprintf((char*)0x20000102, "%020llu", (long long)-1);
  sprintf((char*)0x20000116, "%023llo", (long long)-1);
  sprintf((char*)0x2000012d, "%023llo", (long long)r[0]);
  while(1)syscall(__NR_write, r[0], 0x200000c0ul, 0xbul);
  return 0;
}
'''
GK



Current thread: