Bug 203967

Summary: KASAN: incorrect alloc/free stacks for alloc_pages memory
Product: Memory Management Reporter: Dmitry Vyukov (dvyukov)
Component: SanitizersAssignee: Dmitry Vyukov (dvyukov)
Status: NEW ---    
Severity: enhancement CC: andreyknvl, kasan-dev, melver
Priority: P2    
Hardware: All   
OS: Linux   
Kernel Version: ALL Subsystem:
Regression: No Bisected commit-id:

Description Dmitry Vyukov 2019-06-24 08:48:36 UTC
Example of a bug report:
https://syzkaller.appspot.com/bug?extid=372f5b98ac3765e3a314
https://groups.google.com/forum/#!msg/syzkaller-upstream-moderation/hdpFfR_MfmY/djyDOB86BgAJ
KASAN report is also copied below for convenience.

There is a large 8160-byte access that presumably overflows an alloc_pages-allocated page. It seems there are several problems here:
1. alloc_pages-allocated pages don't have redzones, we take alloc/free stacks and page info for the "first bad byte", which is different and most likely irrelevant page. In case of a memset overflow, we could use the original page instead (memset base).
2. We don't memorize alloc/free stacks for page allocator. We should.

Addressing both of these things would result in a much more useful report: we would say where the original page starts, size of compound page, provide alloc and free stacks for it.

================================================================== 
BUG: KASAN: use-after-free in memset include/linux/string.h:344 [inline] 
BUG: KASAN: use-after-free in __ext4_expand_extra_isize+0x16c/0x240   
fs/ext4/inode.c:5930 
Write of size 8160 at addr ffff888061f844a0 by task syz-executor.2/19044 

CPU: 1 PID: 19044 Comm: syz-executor.2 Not tainted 5.2.0-rc4-next-20190614   
#15 
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS   
Google 01/01/2011 
Call Trace: 
  __dump_stack lib/dump_stack.c:77 [inline] 
  dump_stack+0x172/0x1f0 lib/dump_stack.c:113 
  print_address_description.cold+0xd4/0x306 mm/kasan/report.c:351 
  __kasan_report.cold+0x1b/0x36 mm/kasan/report.c:482 
  kasan_report+0x12/0x20 mm/kasan/common.c:614 
  check_memory_region_inline mm/kasan/generic.c:185 [inline] 
  check_memory_region+0x123/0x190 mm/kasan/generic.c:191 
  memset+0x24/0x40 mm/kasan/common.c:107 
  memset include/linux/string.h:344 [inline] 
  __ext4_expand_extra_isize+0x16c/0x240 fs/ext4/inode.c:5930 
  ext4_try_to_expand_extra_isize fs/ext4/inode.c:5982 [inline] 
  ext4_mark_inode_dirty+0x6e7/0x940 fs/ext4/inode.c:6058 
  ext4_dirty_inode+0x8f/0xc0 fs/ext4/inode.c:6092 
  __mark_inode_dirty+0x915/0x1280 fs/fs-writeback.c:2161 
  generic_update_time+0x21c/0x370 fs/inode.c:1664 
  update_time fs/inode.c:1680 [inline] 
  touch_atime+0x23c/0x2a0 fs/inode.c:1751 
  file_accessed include/linux/fs.h:2175 [inline] 
  iterate_dir+0x36d/0x5e0 fs/readdir.c:56 
  __do_sys_getdents fs/readdir.c:231 [inline] 
  __se_sys_getdents fs/readdir.c:212 [inline] 
  __x64_sys_getdents+0x226/0x3c0 fs/readdir.c:212 
  do_syscall_64+0xfd/0x680 arch/x86/entry/common.c:301 
  entry_SYSCALL_64_after_hwframe+0x49/0xbe 
RIP: 0033:0x45761b 
Code: 02 74 b6 31 f6 eb b9 0f 1f 84 00 00 00 00 00 41 57 41 56 48 63 ff 41   
55 41 54 b8 4e 00 00 00 55 53 48 89 f3 48 83 ec 08 0f 05 <48> 3d 00 f0 ff   
ff 77 55 4c 8d 24 06 49 89 c5 4c 39 e6 73 33 90 0f 
RSP: 002b:00007fff60de2ce0 EFLAGS: 00000202 ORIG_RAX: 000000000000004e 
RAX: ffffffffffffffda RBX: 0000555556115970 RCX: 000000000045761b 
RDX: 0000000000008000 RSI: 0000555556115970 RDI: 0000000000000003 
RBP: 0000555556115970 R08: 0000000000000001 R09: 0000555556114940 
R10: 0000000000000000 R11: 0000000000000202 R12: ffffffffffffffd4 
R13: 0000000000000016 R14: 0000000000000000 R15: 00007fff60de3e80 

The buggy address belongs to the page: 
page:ffffea000187e100 refcount:2 mapcount:0 mapping:ffff8880a10e3558   
index:0x453 
def_blk_aops 
flags: 0x1fffc000000203a(referenced|dirty|lru|active|private) 
raw: 01fffc000000203a ffffea0001fe6488 ffffea0001d8ae48 ffff8880a10e3558 
raw: 0000000000000453 ffff888094c2cf18 00000002ffffffff ffff88805ca5aac0 
page dumped because: kasan: bad access detected 
page->mem_cgroup:ffff88805ca5aac0 

Memory state around the buggy address: 
  ffff888061f85f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
  ffff888061f85f80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
> ffff888061f86000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
                    ^ 
  ffff888061f86080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
  ffff888061f86100: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 
==================================================================
Comment 1 Andrey Konovalov 2020-05-22 14:37:35 UTC
See https://groups.google.com/g/syzkaller/c/lWNU99juENk for a related discussion.
Comment 2 Andrey Konovalov 2021-03-09 16:02:23 UTC
CONFIG_PAGE_OWNER=y + page_owner=y supposedly should be saving alloc/free stack traces for pages, but I only see dummy stack traces in KASAN test reports for some reason.
Comment 3 Andrey Konovalov 2023-11-06 17:37:16 UTC
Also see https://bugzilla.kernel.org/show_bug.cgi?id=216762 wrt detecting page_alloc OOB.