aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVinayak Menon <vinmenon@codeaurora.org>2018-03-28 19:01:16 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-03-28 19:42:05 -0400
commit914b6dfff790544d9b77dfd1723adb3745ec9700 (patch)
treeb82ce8d72d056642a749d72c866be4936cf059cf
parentb213b54fbf9d282dc545252313d727f3972be8e0 (diff)
mm/kmemleak.c: wait for scan completion before disabling free
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, and while at it fix the comment on stop_scan_thread. [vinmenon@codeaurora.org: fix stop_scan_thread comment] Link: http://lkml.kernel.org/r/1522219972-22809-1-git-send-email-vinmenon@codeaurora.org Link: http://lkml.kernel.org/r/1522063429-18992-1-git-send-email-vinmenon@codeaurora.org Signed-off-by: Vinayak Menon <vinmenon@codeaurora.org> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/kmemleak.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/mm/kmemleak.c b/mm/kmemleak.c
index e83987c55a08..46c2290a08f1 100644
--- a/mm/kmemleak.c
+++ b/mm/kmemleak.c
@@ -1657,8 +1657,7 @@ static void start_scan_thread(void)
1657} 1657}
1658 1658
1659/* 1659/*
1660 * Stop the automatic memory scanning thread. This function must be called 1660 * Stop the automatic memory scanning thread.
1661 * with the scan_mutex held.
1662 */ 1661 */
1663static void stop_scan_thread(void) 1662static void stop_scan_thread(void)
1664{ 1663{
@@ -1921,12 +1920,15 @@ static void kmemleak_do_cleanup(struct work_struct *work)
1921{ 1920{
1922 stop_scan_thread(); 1921 stop_scan_thread();
1923 1922
1923 mutex_lock(&scan_mutex);
1924 /* 1924 /*
1925 * Once the scan thread has stopped, it is safe to no longer track 1925 * Once it is made sure that kmemleak_scan has stopped, it is safe to no
1926 * object freeing. Ordering of the scan thread stopping and the memory 1926 * longer track object freeing. Ordering of the scan thread stopping and
1927 * accesses below is guaranteed by the kthread_stop() function. 1927 * the memory accesses below is guaranteed by the kthread_stop()
1928 * function.
1928 */ 1929 */
1929 kmemleak_free_enabled = 0; 1930 kmemleak_free_enabled = 0;
1931 mutex_unlock(&scan_mutex);
1930 1932
1931 if (!kmemleak_found_leaks) 1933 if (!kmemleak_found_leaks)
1932 __kmemleak_do_cleanup(); 1934 __kmemleak_do_cleanup();