kasan: test: fix compatibility with FORTIFY_SOURCE
[linux-2.6-microblaze.git] / lib / test_kasan.c
index 8835e07..26a5c90 100644 (file)
@@ -88,7 +88,7 @@ static void kasan_test_exit(struct kunit *test)
  */
 #define KUNIT_EXPECT_KASAN_FAIL(test, expression) do {                 \
        if (IS_ENABLED(CONFIG_KASAN_HW_TAGS) &&                         \
-           !kasan_async_mode_enabled())                                \
+           kasan_sync_fault_possible())                                \
                migrate_disable();                                      \
        KUNIT_EXPECT_FALSE(test, READ_ONCE(fail_data.report_found));    \
        barrier();                                                      \
@@ -440,6 +440,7 @@ static void kmalloc_oob_memset_2(struct kunit *test)
        ptr = kmalloc(size, GFP_KERNEL);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
 
+       OPTIMIZER_HIDE_VAR(size);
        KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + size - 1, 0, 2));
        kfree(ptr);
 }
@@ -452,6 +453,7 @@ static void kmalloc_oob_memset_4(struct kunit *test)
        ptr = kmalloc(size, GFP_KERNEL);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
 
+       OPTIMIZER_HIDE_VAR(size);
        KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + size - 3, 0, 4));
        kfree(ptr);
 }
@@ -464,6 +466,7 @@ static void kmalloc_oob_memset_8(struct kunit *test)
        ptr = kmalloc(size, GFP_KERNEL);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
 
+       OPTIMIZER_HIDE_VAR(size);
        KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + size - 7, 0, 8));
        kfree(ptr);
 }
@@ -476,6 +479,7 @@ static void kmalloc_oob_memset_16(struct kunit *test)
        ptr = kmalloc(size, GFP_KERNEL);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
 
+       OPTIMIZER_HIDE_VAR(size);
        KUNIT_EXPECT_KASAN_FAIL(test, memset(ptr + size - 15, 0, 16));
        kfree(ptr);
 }
@@ -488,16 +492,18 @@ static void kmalloc_oob_in_memset(struct kunit *test)
        ptr = kmalloc(size, GFP_KERNEL);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
 
+       OPTIMIZER_HIDE_VAR(ptr);
+       OPTIMIZER_HIDE_VAR(size);
        KUNIT_EXPECT_KASAN_FAIL(test,
                                memset(ptr, 0, size + KASAN_GRANULE_SIZE));
        kfree(ptr);
 }
 
-static void kmalloc_memmove_invalid_size(struct kunit *test)
+static void kmalloc_memmove_negative_size(struct kunit *test)
 {
        char *ptr;
        size_t size = 64;
-       volatile size_t invalid_size = -2;
+       size_t invalid_size = -2;
 
        /*
         * Hardware tag-based mode doesn't check memmove for negative size.
@@ -510,6 +516,24 @@ static void kmalloc_memmove_invalid_size(struct kunit *test)
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
 
        memset((char *)ptr, 0, 64);
+       OPTIMIZER_HIDE_VAR(ptr);
+       OPTIMIZER_HIDE_VAR(invalid_size);
+       KUNIT_EXPECT_KASAN_FAIL(test,
+               memmove((char *)ptr, (char *)ptr + 4, invalid_size));
+       kfree(ptr);
+}
+
+static void kmalloc_memmove_invalid_size(struct kunit *test)
+{
+       char *ptr;
+       size_t size = 64;
+       volatile size_t invalid_size = size;
+
+       ptr = kmalloc(size, GFP_KERNEL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
+
+       memset((char *)ptr, 0, 64);
+       OPTIMIZER_HIDE_VAR(ptr);
        KUNIT_EXPECT_KASAN_FAIL(test,
                memmove((char *)ptr, (char *)ptr + 4, invalid_size));
        kfree(ptr);
@@ -679,7 +703,7 @@ static void kmem_cache_bulk(struct kunit *test)
 
 static char global_array[10];
 
-static void kasan_global_oob(struct kunit *test)
+static void kasan_global_oob_right(struct kunit *test)
 {
        /*
         * Deliberate out-of-bounds access. To prevent CONFIG_UBSAN_LOCAL_BOUNDS
@@ -702,6 +726,20 @@ static void kasan_global_oob(struct kunit *test)
        KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)p);
 }
 
+static void kasan_global_oob_left(struct kunit *test)
+{
+       char *volatile array = global_array;
+       char *p = array - 3;
+
+       /*
+        * GCC is known to fail this test, skip it.
+        * See https://bugzilla.kernel.org/show_bug.cgi?id=215051.
+        */
+       KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_CC_IS_CLANG);
+       KASAN_TEST_NEEDS_CONFIG_ON(test, CONFIG_KASAN_GENERIC);
+       KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)p);
+}
+
 /* Check that ksize() makes the whole object accessible. */
 static void ksize_unpoisons_memory(struct kunit *test)
 {
@@ -831,6 +869,16 @@ static void kmem_cache_invalid_free(struct kunit *test)
        kmem_cache_destroy(cache);
 }
 
+static void kmem_cache_double_destroy(struct kunit *test)
+{
+       struct kmem_cache *cache;
+
+       cache = kmem_cache_create("test_cache", 200, 0, 0, NULL);
+       KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cache);
+       kmem_cache_destroy(cache);
+       KUNIT_EXPECT_KASAN_FAIL(test, kmem_cache_destroy(cache));
+}
+
 static void kasan_memchr(struct kunit *test)
 {
        char *ptr;
@@ -848,6 +896,8 @@ static void kasan_memchr(struct kunit *test)
        ptr = kmalloc(size, GFP_KERNEL | __GFP_ZERO);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
 
+       OPTIMIZER_HIDE_VAR(ptr);
+       OPTIMIZER_HIDE_VAR(size);
        KUNIT_EXPECT_KASAN_FAIL(test,
                kasan_ptr_result = memchr(ptr, '1', size + 1));
 
@@ -873,6 +923,8 @@ static void kasan_memcmp(struct kunit *test)
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
        memset(arr, 0, sizeof(arr));
 
+       OPTIMIZER_HIDE_VAR(ptr);
+       OPTIMIZER_HIDE_VAR(size);
        KUNIT_EXPECT_KASAN_FAIL(test,
                kasan_int_result = memcmp(ptr, arr, size+1));
        kfree(ptr);
@@ -1129,6 +1181,7 @@ static struct kunit_case kasan_kunit_test_cases[] = {
        KUNIT_CASE(kmalloc_oob_memset_4),
        KUNIT_CASE(kmalloc_oob_memset_8),
        KUNIT_CASE(kmalloc_oob_memset_16),
+       KUNIT_CASE(kmalloc_memmove_negative_size),
        KUNIT_CASE(kmalloc_memmove_invalid_size),
        KUNIT_CASE(kmalloc_uaf),
        KUNIT_CASE(kmalloc_uaf_memset),
@@ -1138,7 +1191,8 @@ static struct kunit_case kasan_kunit_test_cases[] = {
        KUNIT_CASE(kmem_cache_oob),
        KUNIT_CASE(kmem_cache_accounted),
        KUNIT_CASE(kmem_cache_bulk),
-       KUNIT_CASE(kasan_global_oob),
+       KUNIT_CASE(kasan_global_oob_right),
+       KUNIT_CASE(kasan_global_oob_left),
        KUNIT_CASE(kasan_stack_oob),
        KUNIT_CASE(kasan_alloca_oob_left),
        KUNIT_CASE(kasan_alloca_oob_right),
@@ -1146,6 +1200,7 @@ static struct kunit_case kasan_kunit_test_cases[] = {
        KUNIT_CASE(ksize_uaf),
        KUNIT_CASE(kmem_cache_double_free),
        KUNIT_CASE(kmem_cache_invalid_free),
+       KUNIT_CASE(kmem_cache_double_destroy),
        KUNIT_CASE(kasan_memchr),
        KUNIT_CASE(kasan_memcmp),
        KUNIT_CASE(kasan_strings),