Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
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      * Expecting three errors.
0046      * One for the corrupted freechain and the other one for the wrong
0047      * count of objects in use. The third error is fixing broken cache.
0048      */
0049     validate_slab_cache(s);
0050     KUNIT_EXPECT_EQ(test, 3, slab_errors);
0051 
0052     /*
0053      * Try to repair corrupted freepointer.
0054      * Still expecting two errors. The first for the wrong count
0055      * of objects in use.
0056      * The second error is for fixing broken cache.
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      * Previous validation repaired the count of objects in use.
0066      * Now expecting no error.
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");