0001
0002 #include <kunit/test.h>
0003 #include <linux/mm.h>
0004 #include <linux/slab.h>
0005 #include <linux/module.h>
0006 #include <linux/kernel.h>
0007 #include "../mm/slab.h"
0008
0009 static struct kunit_resource resource;
0010 static int slab_errors;
0011
0012 static void test_clobber_zone(struct kunit *test)
0013 {
0014 struct kmem_cache *s = kmem_cache_create("TestSlub_RZ_alloc", 64, 0,
0015 SLAB_RED_ZONE|SLAB_NO_USER_FLAGS, NULL);
0016 u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
0017
0018 kasan_disable_current();
0019 p[64] = 0x12;
0020
0021 validate_slab_cache(s);
0022 KUNIT_EXPECT_EQ(test, 2, slab_errors);
0023
0024 kasan_enable_current();
0025 kmem_cache_free(s, p);
0026 kmem_cache_destroy(s);
0027 }
0028
0029 #ifndef CONFIG_KASAN
0030 static void test_next_pointer(struct kunit *test)
0031 {
0032 struct kmem_cache *s = kmem_cache_create("TestSlub_next_ptr_free", 64, 0,
0033 SLAB_POISON|SLAB_NO_USER_FLAGS, NULL);
0034 u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
0035 unsigned long tmp;
0036 unsigned long *ptr_addr;
0037
0038 kmem_cache_free(s, p);
0039
0040 ptr_addr = (unsigned long *)(p + s->offset);
0041 tmp = *ptr_addr;
0042 p[s->offset] = 0x12;
0043
0044
0045
0046
0047
0048
0049 validate_slab_cache(s);
0050 KUNIT_EXPECT_EQ(test, 3, slab_errors);
0051
0052
0053
0054
0055
0056
0057
0058 *ptr_addr = tmp;
0059 slab_errors = 0;
0060
0061 validate_slab_cache(s);
0062 KUNIT_EXPECT_EQ(test, 2, slab_errors);
0063
0064
0065
0066
0067
0068 slab_errors = 0;
0069 validate_slab_cache(s);
0070 KUNIT_EXPECT_EQ(test, 0, slab_errors);
0071
0072 kmem_cache_destroy(s);
0073 }
0074
0075 static void test_first_word(struct kunit *test)
0076 {
0077 struct kmem_cache *s = kmem_cache_create("TestSlub_1th_word_free", 64, 0,
0078 SLAB_POISON|SLAB_NO_USER_FLAGS, NULL);
0079 u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
0080
0081 kmem_cache_free(s, p);
0082 *p = 0x78;
0083
0084 validate_slab_cache(s);
0085 KUNIT_EXPECT_EQ(test, 2, slab_errors);
0086
0087 kmem_cache_destroy(s);
0088 }
0089
0090 static void test_clobber_50th_byte(struct kunit *test)
0091 {
0092 struct kmem_cache *s = kmem_cache_create("TestSlub_50th_word_free", 64, 0,
0093 SLAB_POISON|SLAB_NO_USER_FLAGS, NULL);
0094 u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
0095
0096 kmem_cache_free(s, p);
0097 p[50] = 0x9a;
0098
0099 validate_slab_cache(s);
0100 KUNIT_EXPECT_EQ(test, 2, slab_errors);
0101
0102 kmem_cache_destroy(s);
0103 }
0104 #endif
0105
0106 static void test_clobber_redzone_free(struct kunit *test)
0107 {
0108 struct kmem_cache *s = kmem_cache_create("TestSlub_RZ_free", 64, 0,
0109 SLAB_RED_ZONE|SLAB_NO_USER_FLAGS, NULL);
0110 u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
0111
0112 kasan_disable_current();
0113 kmem_cache_free(s, p);
0114 p[64] = 0xab;
0115
0116 validate_slab_cache(s);
0117 KUNIT_EXPECT_EQ(test, 2, slab_errors);
0118
0119 kasan_enable_current();
0120 kmem_cache_destroy(s);
0121 }
0122
0123 static int test_init(struct kunit *test)
0124 {
0125 slab_errors = 0;
0126
0127 kunit_add_named_resource(test, NULL, NULL, &resource,
0128 "slab_errors", &slab_errors);
0129 return 0;
0130 }
0131
0132 static struct kunit_case test_cases[] = {
0133 KUNIT_CASE(test_clobber_zone),
0134
0135 #ifndef CONFIG_KASAN
0136 KUNIT_CASE(test_next_pointer),
0137 KUNIT_CASE(test_first_word),
0138 KUNIT_CASE(test_clobber_50th_byte),
0139 #endif
0140
0141 KUNIT_CASE(test_clobber_redzone_free),
0142 {}
0143 };
0144
0145 static struct kunit_suite test_suite = {
0146 .name = "slub_test",
0147 .init = test_init,
0148 .test_cases = test_cases,
0149 };
0150 kunit_test_suite(test_suite);
0151
0152 MODULE_LICENSE("GPL");