• Marco Elver's avatar
    kfence: fix stack trace pruning · 747c0f35
    Marco Elver authored
    Commit b1405135 ("mm/sl[au]b: generalize kmalloc subsystem")
    refactored large parts of the kmalloc subsystem, resulting in the stack
    trace pruning logic done by KFENCE to no longer work.
    
    While b1405135 attempted to fix the situation by including
    '__kmem_cache_free' in the list of functions KFENCE should skip through,
    this only works when the compiler actually optimized the tail call from
    kfree() to __kmem_cache_free() into a jump (and thus kfree() _not_
    appearing in the full stack trace to begin with).
    
    In some configurations, the compiler no longer optimizes the tail call
    into a jump, and __kmem_cache_free() appears in the stack trace.  This
    means that the pruned stack trace shown by KFENCE would include kfree()
    which is not intended - for example:
    
     | BUG: KFENCE: invalid free in kfree+0x7c/0x120
     |
     | Invalid free of 0xffff8883ed8fefe0 (in kfence-#126):
     |  kfree+0x7c/0x120
     |  test_double_free+0x116/0x1a9
     |  kunit_try_run_case+0x90/0xd0
     | [...]
    
    Fix it by moving __kmem_cache_free() to the list of functions that may be
    tail called by an allocator entry function, making the pruning logic work
    in both the optimized and unoptimized tail call cases.
    
    Link: https://lkml.kernel.org/r/20221118152216.3914899-1-elver@google.com
    Fixes: b1405135 ("mm/sl[au]b: generalize kmalloc subsystem")
    Signed-off-by: default avatarMarco Elver <elver@google.com>
    Reviewed-by: default avatarAlexander Potapenko <glider@google.com>
    Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com>
    Cc: Feng Tang <feng.tang@intel.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    747c0f35
report.c 9.93 KB