This patch adds new tests for KASAN double-free error detection when the
same slab object is concurrently deallocated.

Signed-off-by: Kuthonuzo Luruo <kuthonuzo.lu...@hpe.com>
---

Changes in v3:
- concurrent double-free test simplified to use on_each_cpu_mask() instead
  of custom threads.
- reduced #threads and removed CONFIG_SMP guards per suggestion from Dmitry
  Vyukov.

---
 lib/test_kasan.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 47 insertions(+), 0 deletions(-)

diff --git a/lib/test_kasan.c b/lib/test_kasan.c
index 5e51872..0f589e7 100644
--- a/lib/test_kasan.c
+++ b/lib/test_kasan.c
@@ -411,6 +411,49 @@ static noinline void __init copy_user_test(void)
        kfree(kmem);
 }
 
+#ifdef CONFIG_SLAB
+static void try_free(void *p)
+{
+       kfree(p);
+}
+
+static void __init kasan_double_free_concurrent(void)
+{
+#define MAX_THREADS 3
+       char *p;
+       int cpu, cnt = num_online_cpus();
+       cpumask_t mask = { CPU_BITS_NONE };
+       size_t size = 4097;     /* must be <= KMALLOC_MAX_CACHE_SIZE/2 */
+
+       if (cnt == 1)
+               return;
+       cnt = cnt < MAX_THREADS ? cnt : MAX_THREADS;
+       pr_info("concurrent double-free (%d threads)\n", cnt);
+       p = kmalloc(size, GFP_KERNEL);
+       if (!p)
+               return;
+       for_each_online_cpu(cpu) {
+               cpumask_set_cpu(cpu, &mask);
+               if (!--cnt)
+                       break;
+       }
+       on_each_cpu_mask(&mask, try_free, p, 0);
+}
+
+static noinline void __init kasan_double_free(void)
+{
+       char *p;
+       size_t size = 2049;
+
+       pr_info("double-free\n");
+       p = kmalloc(size, GFP_KERNEL);
+       if (!p)
+               return;
+       kfree(p);
+       kfree(p);
+}
+#endif
+
 static int __init kmalloc_tests_init(void)
 {
        kmalloc_oob_right();
@@ -436,6 +479,10 @@ static int __init kmalloc_tests_init(void)
        kasan_global_oob();
        ksize_unpoisons_memory();
        copy_user_test();
+#ifdef CONFIG_SLAB
+       kasan_double_free();
+       kasan_double_free_concurrent();
+#endif
        return -EAGAIN;
 }
 
-- 
1.7.1

Reply via email to