Skip to content
  • Kuan-Ying Lee's avatar
    kasan, kmemleak: reset tags when scanning block · 6c7a00b8
    Kuan-Ying Lee authored
    Patch series "kasan, slub: reset tag when printing address", v3.
    
    With hardware tag-based kasan enabled, we reset the tag when we access
    metadata to avoid from false alarm.
    
    This patch (of 2):
    
    Kmemleak needs to scan kernel memory to check memory leak.  With hardware
    tag-based kasan enabled, when it scans on the invalid slab and
    dereference, the issue will occur as below.
    
    Hardware tag-based KASAN doesn't use compiler instrumentation, we can not
    use kasan_disable_current() to ignore tag check.
    
    Based on the below report, there are 11 0xf7 granules, which amounts to
    176 bytes, and the object is allocated from the kmalloc-256 cache.  So
    when kmemleak accesses the last 256-176 bytes, it causes faults, as those
    are marked with KASAN_KMALLOC_REDZONE == KASAN_TAG_INVALID == 0xfe.
    
    Thus, we reset tags before accessing metadata to avoid from false positives.
    
      BUG: KASAN: out-of-bounds in scan_block+0x58/0x170
      Read at addr f7ff0000c0074eb0 by task kmemleak/138
      Pointer tag: [f7], memory tag: [fe]
    
      CPU: 7 PID: 138 Comm: kmemleak Not tainted 5.14.0-rc2-00001-g8cae8cd8-dirty #134
      Hardware name: linux,dummy-virt (DT)
      Call trace:
       dump_backtrace+0x0/0x1b0
       show_stack+0x1c/0x30
       dump_stack_lvl+0x68/0x84
       print_address_description+0x7c/0x2b4
       kasan_report+0x138/0x38c
       __do_kernel_fault+0x190/0x1c4
       do_tag_check_fault+0x78/0x90
       do_mem_abort+0x44/0xb4
       el1_abort+0x40/0x60
       el1h_64_sync_handler+0xb4/0xd0
       el1h_64_sync+0x78/0x7c
       scan_block+0x58/0x170
       scan_gray_list+0xdc/0x1a0
       kmemleak_scan+0x2ac/0x560
       kmemleak_scan_thread+0xb0/0xe0
       kthread+0x154/0x160
       ret_from_fork+0x10/0x18
    
      Allocated by task 0:
       kasan_save_stack+0x2c/0x60
       __kasan_kmalloc+0xec/0x104
       __kmalloc+0x224/0x3c4
       __register_sysctl_paths+0x200/0x290
       register_sysctl_table+0x2c/0x40
       sysctl_init+0x20/0x34
       proc_sys_init+0x3c/0x48
       proc_root_init+0x80/0x9c
       start_kernel+0x648/0x6a4
       __primary_switched+0xc0/0xc8
    
      Freed by task 0:
       kasan_save_stack+0x2c/0x60
       kasan_set_track+0x2c/0x40
       kasan_set_free_info+0x44/0x54
       ____kasan_slab_free.constprop.0+0x150/0x1b0
       __kasan_slab_free+0x14/0x20
       slab_free_freelist_hook+0xa4/0x1fc
       kfree+0x1e8/0x30c
       put_fs_context+0x124/0x220
       vfs_kern_mount.part.0+0x60/0xd4
       kern_mount+0x24/0x4c
       bdev_cache_init+0x70/0x9c
       vfs_caches_init+0xdc/0xf4
       start_kernel+0x638/0x6a4
       __primary_switched+0xc0/0xc8
    
      The buggy address belongs to the object at ffff0000c0074e00
       which belongs to the cache kmalloc-256 of size 256
      The buggy address is located 176 bytes inside of
       256-byte region [ffff0000c0074e00, ffff0000c0074f00)
      The buggy address belongs to the page:
      page:(____ptrval____) refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x100074
      head:(____ptrval____) order:2 compound_mapcount:0 compound_pincount:0
      flags: 0xbfffc0000010200(slab|head|node=0|zone=2|lastcpupid=0xffff|kasantag=0x0)
      raw: 0bfffc0000010200 0000000000000000 dead000000000122 f5ff0000c0002300
      raw: 0000000000000000 0000000000200020 00000001ffffffff 0000000000000000
      page dumped because: kasan: bad access detected
    
      Memory state around the buggy address:
       ffff0000c0074c00: f0 f0 f0 f0 f0 f0 f0 f0 f0 fe fe fe fe fe fe fe
       ffff0000c0074d00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
      >ffff0000c0074e00: f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 f7 fe fe fe fe fe
                                                          ^
       ffff0000c0074f00: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
       ffff0000c0075000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
      ==================================================================
      Disabling lock debugging due to kernel taint
      kmemleak: 181 new suspected memory leaks (see /sys/kernel/debug/kmemleak)
    
    Link: https://lkml.kernel.org/r/20210804090957.12393-1-Kuan-Ying.Lee@mediatek.com
    Link: https://lkml.kernel.org/r/20210804090957.12393-2-Kuan-Ying.Lee@mediatek.com
    
    
    Signed-off-by: default avatarKuan-Ying Lee <Kuan-Ying.Lee@mediatek.com>
    Acked-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
    Reviewed-by: default avatarAndrey Konovalov <andreyknvl@gmail.com>
    Cc: Marco Elver <elver@google.com>
    Cc: Nicholas Tang <nicholas.tang@mediatek.com>
    Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
    Cc: Alexander Potapenko <glider@google.com>
    Cc: Chinwen Chang <chinwen.chang@mediatek.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
    6c7a00b8