selftests/powerpc: Don't use setaffinity in tm-tmspr
[linux-2.6-microblaze.git] / lib / test_kasan.c
index dc2c6a5..53e953b 100644 (file)
 
 #include <asm/page.h>
 
+#include "../mm/kasan/kasan.h"
+
+#define OOB_TAG_OFF (IS_ENABLED(CONFIG_KASAN_GENERIC) ? 0 : KASAN_SHADOW_SCALE_SIZE)
+
 /*
  * We assign some test results to these globals to make sure the tests
  * are not eliminated as dead code.
@@ -48,7 +52,8 @@ static noinline void __init kmalloc_oob_right(void)
                return;
        }
 
-       ptr[size] = 'x';
+       ptr[size + OOB_TAG_OFF] = 'x';
+
        kfree(ptr);
 }
 
@@ -100,7 +105,8 @@ static noinline void __init kmalloc_pagealloc_oob_right(void)
                return;
        }
 
-       ptr[size] = 0;
+       ptr[size + OOB_TAG_OFF] = 0;
+
        kfree(ptr);
 }
 
@@ -170,7 +176,8 @@ static noinline void __init kmalloc_oob_krealloc_more(void)
                return;
        }
 
-       ptr2[size2] = 'x';
+       ptr2[size2 + OOB_TAG_OFF] = 'x';
+
        kfree(ptr2);
 }
 
@@ -188,7 +195,9 @@ static noinline void __init kmalloc_oob_krealloc_less(void)
                kfree(ptr1);
                return;
        }
-       ptr2[size2] = 'x';
+
+       ptr2[size2 + OOB_TAG_OFF] = 'x';
+
        kfree(ptr2);
 }
 
@@ -224,7 +233,8 @@ static noinline void __init kmalloc_oob_memset_2(void)
                return;
        }
 
-       memset(ptr+7, 0, 2);
+       memset(ptr + 7 + OOB_TAG_OFF, 0, 2);
+
        kfree(ptr);
 }
 
@@ -240,7 +250,8 @@ static noinline void __init kmalloc_oob_memset_4(void)
                return;
        }
 
-       memset(ptr+5, 0, 4);
+       memset(ptr + 5 + OOB_TAG_OFF, 0, 4);
+
        kfree(ptr);
 }
 
@@ -257,7 +268,8 @@ static noinline void __init kmalloc_oob_memset_8(void)
                return;
        }
 
-       memset(ptr+1, 0, 8);
+       memset(ptr + 1 + OOB_TAG_OFF, 0, 8);
+
        kfree(ptr);
 }
 
@@ -273,7 +285,8 @@ static noinline void __init kmalloc_oob_memset_16(void)
                return;
        }
 
-       memset(ptr+1, 0, 16);
+       memset(ptr + 1 + OOB_TAG_OFF, 0, 16);
+
        kfree(ptr);
 }
 
@@ -289,7 +302,8 @@ static noinline void __init kmalloc_oob_in_memset(void)
                return;
        }
 
-       memset(ptr, 0, size+5);
+       memset(ptr, 0, size + 5 + OOB_TAG_OFF);
+
        kfree(ptr);
 }
 
@@ -423,7 +437,8 @@ static noinline void __init kmem_cache_oob(void)
                return;
        }
 
-       *p = p[size];
+       *p = p[size + OOB_TAG_OFF];
+
        kmem_cache_free(cache, p);
        kmem_cache_destroy(cache);
 }
@@ -473,7 +488,7 @@ static noinline void __init kasan_global_oob(void)
 static noinline void __init kasan_stack_oob(void)
 {
        char stack_array[10];
-       volatile int i = 0;
+       volatile int i = OOB_TAG_OFF;
        char *p = &stack_array[ARRAY_SIZE(stack_array) + i];
 
        pr_info("out-of-bounds on stack\n");
@@ -520,25 +535,25 @@ static noinline void __init copy_user_test(void)
        }
 
        pr_info("out-of-bounds in copy_from_user()\n");
-       unused = copy_from_user(kmem, usermem, size + 1);
+       unused = copy_from_user(kmem, usermem, size + 1 + OOB_TAG_OFF);
 
        pr_info("out-of-bounds in copy_to_user()\n");
-       unused = copy_to_user(usermem, kmem, size + 1);
+       unused = copy_to_user(usermem, kmem, size + 1 + OOB_TAG_OFF);
 
        pr_info("out-of-bounds in __copy_from_user()\n");
-       unused = __copy_from_user(kmem, usermem, size + 1);
+       unused = __copy_from_user(kmem, usermem, size + 1 + OOB_TAG_OFF);
 
        pr_info("out-of-bounds in __copy_to_user()\n");
-       unused = __copy_to_user(usermem, kmem, size + 1);
+       unused = __copy_to_user(usermem, kmem, size + 1 + OOB_TAG_OFF);
 
        pr_info("out-of-bounds in __copy_from_user_inatomic()\n");
-       unused = __copy_from_user_inatomic(kmem, usermem, size + 1);
+       unused = __copy_from_user_inatomic(kmem, usermem, size + 1 + OOB_TAG_OFF);
 
        pr_info("out-of-bounds in __copy_to_user_inatomic()\n");
-       unused = __copy_to_user_inatomic(usermem, kmem, size + 1);
+       unused = __copy_to_user_inatomic(usermem, kmem, size + 1 + OOB_TAG_OFF);
 
        pr_info("out-of-bounds in strncpy_from_user()\n");
-       unused = strncpy_from_user(kmem, usermem, size + 1);
+       unused = strncpy_from_user(kmem, usermem, size + 1 + OOB_TAG_OFF);
 
        vm_munmap((unsigned long)usermem, PAGE_SIZE);
        kfree(kmem);
@@ -766,15 +781,15 @@ static noinline void __init kmalloc_double_kzfree(void)
        char *ptr;
        size_t size = 16;
 
-       pr_info("double-free (kzfree)\n");
+       pr_info("double-free (kfree_sensitive)\n");
        ptr = kmalloc(size, GFP_KERNEL);
        if (!ptr) {
                pr_err("Allocation failed\n");
                return;
        }
 
-       kzfree(ptr);
-       kzfree(ptr);
+       kfree_sensitive(ptr);
+       kfree_sensitive(ptr);
 }
 
 #ifdef CONFIG_KASAN_VMALLOC
@@ -801,6 +816,35 @@ static noinline void __init vmalloc_oob(void)
 static void __init vmalloc_oob(void) {}
 #endif
 
+static struct kasan_rcu_info {
+       int i;
+       struct rcu_head rcu;
+} *global_rcu_ptr;
+
+static noinline void __init kasan_rcu_reclaim(struct rcu_head *rp)
+{
+       struct kasan_rcu_info *fp = container_of(rp,
+                                               struct kasan_rcu_info, rcu);
+
+       kfree(fp);
+       fp->i = 1;
+}
+
+static noinline void __init kasan_rcu_uaf(void)
+{
+       struct kasan_rcu_info *ptr;
+
+       pr_info("use-after-free in kasan_rcu_reclaim\n");
+       ptr = kmalloc(sizeof(struct kasan_rcu_info), GFP_KERNEL);
+       if (!ptr) {
+               pr_err("Allocation failed\n");
+               return;
+       }
+
+       global_rcu_ptr = rcu_dereference_protected(ptr, NULL);
+       call_rcu(&global_rcu_ptr->rcu, kasan_rcu_reclaim);
+}
+
 static int __init kmalloc_tests_init(void)
 {
        /*
@@ -848,6 +892,7 @@ static int __init kmalloc_tests_init(void)
        kasan_bitops();
        kmalloc_double_kzfree();
        vmalloc_oob();
+       kasan_rcu_uaf();
 
        kasan_restore_multi_shot(multishot);