On Mon, 26 Mar 2018 16:44:21 +0100 Catalin Marinas <catalin.marinas@xxxxxxx> wrote: > On Mon, Mar 26, 2018 at 04:53:49PM +0530, Vinayak Menon wrote: > > A crash is observed when kmemleak_scan accesses the > > object->pointer, likely due to the following race. > > > > TASK A TASK B TASK C > > kmemleak_write > > (with "scan" and > > NOT "scan=on") > > kmemleak_scan() > > create_object > > kmem_cache_alloc fails > > kmemleak_disable > > kmemleak_do_cleanup > > kmemleak_free_enabled = 0 > > kfree > > kmemleak_free bails out > > (kmemleak_free_enabled is 0) > > slub frees object->pointer > > update_checksum > > crash - object->pointer > > freed (DEBUG_PAGEALLOC) > > > > kmemleak_do_cleanup waits for the scan thread to complete, but not for > > direct call to kmemleak_scan via kmemleak_write. So add a wait for > > kmemleak_scan completion before disabling kmemleak_free. > > > > Signed-off-by: Vinayak Menon <vinmenon@xxxxxxxxxxxxxx> > > It looks fine to me. Maybe Andrew can pick it up. > > Reviewed-by: Catalin Marinas <catalin.marinas@xxxxxxx> Well, the comment says: /* * Stop the automatic memory scanning thread. This function must be called * with the scan_mutex held. */ static void stop_scan_thread(void) So shouldn't we do it this way? --- a/mm/kmemleak.c~mm-kmemleak-wait-for-scan-completion-before-disabling-free-fix +++ a/mm/kmemleak.c @@ -1919,9 +1919,9 @@ static void __kmemleak_do_cleanup(void) */ static void kmemleak_do_cleanup(struct work_struct *work) { + mutex_lock(&scan_mutex); stop_scan_thread(); - mutex_lock(&scan_mutex); /* * Once it is made sure that kmemleak_scan has stopped, it is safe to no * longer track object freeing. Ordering of the scan thread stopping and _