1 // SPDX-License-Identifier: GPL-2.0
2 #include <kunit/test.h>
3 #include <kunit/test-bug.h>
4 #include <linux/mm.h>
5 #include <linux/slab.h>
6 #include <linux/module.h>
7 #include <linux/kernel.h>
8 #include <linux/rcupdate.h>
9 #include <linux/delay.h>
10 #include <linux/perf_event.h>
11 #include <linux/kprobes.h>
12 #include "../mm/slab.h"
13
14 static struct kunit_resource resource;
15 static int slab_errors;
16
17 /*
18 * Wrapper function for kmem_cache_create(), which reduces 2 parameters:
19 * 'align' and 'ctor', and sets SLAB_SKIP_KFENCE flag to avoid getting an
20 * object from kfence pool, where the operation could be caught by both
21 * our test and kfence sanity check.
22 */
test_kmem_cache_create(const char * name,unsigned int size,slab_flags_t flags)23 static struct kmem_cache *test_kmem_cache_create(const char *name,
24 unsigned int size, slab_flags_t flags)
25 {
26 struct kmem_cache *s = kmem_cache_create(name, size, 0,
27 (flags | SLAB_NO_USER_FLAGS), NULL);
28 s->flags |= SLAB_SKIP_KFENCE;
29 return s;
30 }
31
test_clobber_zone(struct kunit * test)32 static void test_clobber_zone(struct kunit *test)
33 {
34 struct kmem_cache *s = test_kmem_cache_create("TestSlub_RZ_alloc", 64,
35 SLAB_RED_ZONE);
36 u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
37
38 kasan_disable_current();
39 p[64] = 0x12;
40
41 validate_slab_cache(s);
42 KUNIT_EXPECT_EQ(test, 2, slab_errors);
43
44 kasan_enable_current();
45 kmem_cache_free(s, p);
46 kmem_cache_destroy(s);
47 }
48
49 #ifndef CONFIG_KASAN
test_next_pointer(struct kunit * test)50 static void test_next_pointer(struct kunit *test)
51 {
52 struct kmem_cache *s = test_kmem_cache_create("TestSlub_next_ptr_free",
53 64, SLAB_POISON);
54 u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
55 unsigned long tmp;
56 unsigned long *ptr_addr;
57
58 kmem_cache_free(s, p);
59
60 ptr_addr = (unsigned long *)(p + s->offset);
61 tmp = *ptr_addr;
62 p[s->offset] = ~p[s->offset];
63
64 /*
65 * Expecting three errors.
66 * One for the corrupted freechain and the other one for the wrong
67 * count of objects in use. The third error is fixing broken cache.
68 */
69 validate_slab_cache(s);
70 KUNIT_EXPECT_EQ(test, 3, slab_errors);
71
72 /*
73 * Try to repair corrupted freepointer.
74 * Still expecting two errors. The first for the wrong count
75 * of objects in use.
76 * The second error is for fixing broken cache.
77 */
78 *ptr_addr = tmp;
79 slab_errors = 0;
80
81 validate_slab_cache(s);
82 KUNIT_EXPECT_EQ(test, 2, slab_errors);
83
84 /*
85 * Previous validation repaired the count of objects in use.
86 * Now expecting no error.
87 */
88 slab_errors = 0;
89 validate_slab_cache(s);
90 KUNIT_EXPECT_EQ(test, 0, slab_errors);
91
92 kmem_cache_destroy(s);
93 }
94
test_first_word(struct kunit * test)95 static void test_first_word(struct kunit *test)
96 {
97 struct kmem_cache *s = test_kmem_cache_create("TestSlub_1th_word_free",
98 64, SLAB_POISON);
99 u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
100
101 kmem_cache_free(s, p);
102 *p = 0x78;
103
104 validate_slab_cache(s);
105 KUNIT_EXPECT_EQ(test, 2, slab_errors);
106
107 kmem_cache_destroy(s);
108 }
109
test_clobber_50th_byte(struct kunit * test)110 static void test_clobber_50th_byte(struct kunit *test)
111 {
112 struct kmem_cache *s = test_kmem_cache_create("TestSlub_50th_word_free",
113 64, SLAB_POISON);
114 u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
115
116 kmem_cache_free(s, p);
117 p[50] = 0x9a;
118
119 validate_slab_cache(s);
120 KUNIT_EXPECT_EQ(test, 2, slab_errors);
121
122 kmem_cache_destroy(s);
123 }
124 #endif
125
test_clobber_redzone_free(struct kunit * test)126 static void test_clobber_redzone_free(struct kunit *test)
127 {
128 struct kmem_cache *s = test_kmem_cache_create("TestSlub_RZ_free", 64,
129 SLAB_RED_ZONE);
130 u8 *p = kmem_cache_alloc(s, GFP_KERNEL);
131
132 kasan_disable_current();
133 kmem_cache_free(s, p);
134 p[64] = 0xab;
135
136 validate_slab_cache(s);
137 KUNIT_EXPECT_EQ(test, 2, slab_errors);
138
139 kasan_enable_current();
140 kmem_cache_destroy(s);
141 }
142
test_kmalloc_redzone_access(struct kunit * test)143 static void test_kmalloc_redzone_access(struct kunit *test)
144 {
145 struct kmem_cache *s = test_kmem_cache_create("TestSlub_RZ_kmalloc", 32,
146 SLAB_KMALLOC|SLAB_STORE_USER|SLAB_RED_ZONE);
147 u8 *p = alloc_hooks(__kmalloc_cache_noprof(s, GFP_KERNEL, 18));
148
149 kasan_disable_current();
150
151 /* Suppress the -Warray-bounds warning */
152 OPTIMIZER_HIDE_VAR(p);
153 p[18] = 0xab;
154 p[19] = 0xab;
155
156 validate_slab_cache(s);
157 KUNIT_EXPECT_EQ(test, 2, slab_errors);
158
159 kasan_enable_current();
160 kmem_cache_free(s, p);
161 kmem_cache_destroy(s);
162 }
163
164 struct test_kfree_rcu_struct {
165 union {
166 struct rcu_head rcu;
167 struct kvfree_rcu_head kvrcu;
168 };
169 };
170
test_kfree_rcu(struct kunit * test)171 static void test_kfree_rcu(struct kunit *test)
172 {
173 struct kmem_cache *s;
174 struct test_kfree_rcu_struct *p;
175
176 if (IS_BUILTIN(CONFIG_SLUB_KUNIT_TEST))
177 kunit_skip(test, "can't do kfree_rcu() when test is built-in");
178
179 s = test_kmem_cache_create("TestSlub_kfree_rcu",
180 sizeof(struct test_kfree_rcu_struct),
181 SLAB_NO_MERGE);
182 p = kmem_cache_alloc(s, GFP_KERNEL);
183
184 kfree_rcu(p, rcu);
185 kmem_cache_destroy(s);
186
187 KUNIT_EXPECT_EQ(test, 0, slab_errors);
188 }
189
190 struct cache_destroy_work {
191 struct work_struct work;
192 struct kmem_cache *s;
193 };
194
cache_destroy_workfn(struct work_struct * w)195 static void cache_destroy_workfn(struct work_struct *w)
196 {
197 struct cache_destroy_work *cdw;
198
199 cdw = container_of(w, struct cache_destroy_work, work);
200 kmem_cache_destroy(cdw->s);
201 }
202
203 #define KMEM_CACHE_DESTROY_NR 10
204
test_kfree_rcu_wq_destroy(struct kunit * test)205 static void test_kfree_rcu_wq_destroy(struct kunit *test)
206 {
207 struct test_kfree_rcu_struct *p;
208 struct cache_destroy_work cdw;
209 struct workqueue_struct *wq;
210 struct kmem_cache *s;
211 unsigned int delay;
212 int i;
213
214 if (IS_BUILTIN(CONFIG_SLUB_KUNIT_TEST))
215 kunit_skip(test, "can't do kfree_rcu() when test is built-in");
216
217 INIT_WORK_ONSTACK(&cdw.work, cache_destroy_workfn);
218 wq = alloc_workqueue("test_kfree_rcu_destroy_wq",
219 WQ_HIGHPRI | WQ_UNBOUND | WQ_MEM_RECLAIM, 0);
220
221 if (!wq)
222 kunit_skip(test, "failed to alloc wq");
223
224 for (i = 0; i < KMEM_CACHE_DESTROY_NR; i++) {
225 s = test_kmem_cache_create("TestSlub_kfree_rcu_wq_destroy",
226 sizeof(struct test_kfree_rcu_struct),
227 SLAB_NO_MERGE);
228
229 if (!s)
230 kunit_skip(test, "failed to create cache");
231
232 delay = get_random_u8();
233 p = kmem_cache_alloc(s, GFP_KERNEL);
234 kfree_rcu(p, rcu);
235
236 cdw.s = s;
237
238 msleep(delay);
239 queue_work(wq, &cdw.work);
240 flush_work(&cdw.work);
241 }
242
243 destroy_workqueue(wq);
244 KUNIT_EXPECT_EQ(test, 0, slab_errors);
245 }
246
test_leak_destroy(struct kunit * test)247 static void test_leak_destroy(struct kunit *test)
248 {
249 struct kmem_cache *s = test_kmem_cache_create("TestSlub_leak_destroy",
250 64, SLAB_NO_MERGE);
251 kmem_cache_alloc(s, GFP_KERNEL);
252
253 kmem_cache_destroy(s);
254
255 KUNIT_EXPECT_EQ(test, 2, slab_errors);
256 }
257
test_krealloc_redzone_zeroing(struct kunit * test)258 static void test_krealloc_redzone_zeroing(struct kunit *test)
259 {
260 u8 *p;
261 int i;
262 struct kmem_cache *s = test_kmem_cache_create("TestSlub_krealloc", 64,
263 SLAB_KMALLOC|SLAB_STORE_USER|SLAB_RED_ZONE);
264
265 p = alloc_hooks(__kmalloc_cache_noprof(s, GFP_KERNEL, 48));
266 memset(p, 0xff, 48);
267
268 kasan_disable_current();
269 OPTIMIZER_HIDE_VAR(p);
270
271 /* Test shrink */
272 p = krealloc(p, 40, GFP_KERNEL | __GFP_ZERO);
273 for (i = 40; i < 64; i++)
274 KUNIT_EXPECT_EQ(test, p[i], SLUB_RED_ACTIVE);
275
276 /* Test grow within the same 64B kmalloc object */
277 p = krealloc(p, 56, GFP_KERNEL | __GFP_ZERO);
278 for (i = 40; i < 56; i++)
279 KUNIT_EXPECT_EQ(test, p[i], 0);
280 for (i = 56; i < 64; i++)
281 KUNIT_EXPECT_EQ(test, p[i], SLUB_RED_ACTIVE);
282
283 validate_slab_cache(s);
284 KUNIT_EXPECT_EQ(test, 0, slab_errors);
285
286 memset(p, 0xff, 56);
287 /* Test grow with allocating a bigger 128B object */
288 p = krealloc(p, 112, GFP_KERNEL | __GFP_ZERO);
289 for (i = 0; i < 56; i++)
290 KUNIT_EXPECT_EQ(test, p[i], 0xff);
291 for (i = 56; i < 112; i++)
292 KUNIT_EXPECT_EQ(test, p[i], 0);
293
294 kfree(p);
295 kasan_enable_current();
296 kmem_cache_destroy(s);
297 }
298
299 #if defined(CONFIG_PERF_EVENTS) || (defined(CONFIG_KPROBES) && defined(CONFIG_SMP))
300 #define NR_ITERATIONS 1000
301 #define NR_OBJECTS 1000
302 static struct test_kfree_rcu_struct *objects[NR_OBJECTS];
303
304 struct test_nolock_context {
305 struct kunit *test;
306 int callback_count;
307 int alloc_ok;
308 int alloc_fail;
309 #ifdef CONFIG_PERF_EVENTS
310 struct perf_event *event;
311 #endif
312 #if defined(CONFIG_KPROBES) && defined(CONFIG_SMP)
313 struct kprobe kprobe;
314 #endif
315 };
316
test_kmalloc_and_friends(void)317 static void test_kmalloc_and_friends(void)
318 {
319 int i, j;
320 bool can_use_kfree_rcu = !IS_BUILTIN(CONFIG_SLUB_KUNIT_TEST);
321
322 for (i = 0; i < NR_ITERATIONS; i++) {
323 for (j = 0; j < NR_OBJECTS; j++) {
324 gfp_t gfp = (i & 1) ? GFP_KERNEL : GFP_KERNEL_ACCOUNT;
325
326 objects[j] = kmalloc_obj(*objects[j], gfp);
327 if (!objects[j]) {
328 j--;
329 while (j >= 0)
330 kfree(objects[j--]);
331 return;
332 }
333 }
334
335 for (j = 0; j < NR_OBJECTS; j++) {
336 if (can_use_kfree_rcu && (i & 2))
337 kfree_rcu(objects[j], rcu);
338 else
339 kfree(objects[j]);
340 }
341 }
342 }
343
test_nolock(struct test_nolock_context * ctx)344 static void test_nolock(struct test_nolock_context *ctx)
345 {
346 struct test_kfree_rcu_struct *objp;
347 gfp_t gfp;
348 bool can_use_kfree_rcu = !IS_BUILTIN(CONFIG_SLUB_KUNIT_TEST);
349
350 /* __GFP_ACCOUNT to test kmalloc_nolock() in alloc_slab_obj_exts() */
351 gfp = (ctx->callback_count & 1) ? 0 : __GFP_ACCOUNT;
352 objp = kmalloc_nolock(sizeof(*objp), gfp, NUMA_NO_NODE);
353
354 if (objp)
355 ctx->alloc_ok++;
356 else
357 ctx->alloc_fail++;
358
359 if (can_use_kfree_rcu && (ctx->callback_count & 2))
360 kfree_rcu_nolock(objp, kvrcu);
361 else
362 kfree_nolock(objp);
363
364 ctx->callback_count++;
365 }
366 #endif
367
368 #ifdef CONFIG_PERF_EVENTS
369 static struct perf_event_attr hw_attr = {
370 .type = PERF_TYPE_HARDWARE,
371 .config = PERF_COUNT_HW_CPU_CYCLES,
372 .size = sizeof(struct perf_event_attr),
373 .pinned = 1,
374 .disabled = 1,
375 .freq = 1,
376 .sample_freq = 100000,
377 };
378
overflow_handler_test_nolock(struct perf_event * event,struct perf_sample_data * data,struct pt_regs * regs)379 static void overflow_handler_test_nolock(struct perf_event *event,
380 struct perf_sample_data *data,
381 struct pt_regs *regs)
382 {
383 struct test_nolock_context *ctx = event->overflow_handler_context;
384
385 test_nolock(ctx);
386 }
387
enable_perf_events(struct test_nolock_context * ctx)388 static bool enable_perf_events(struct test_nolock_context *ctx)
389 {
390 struct perf_event *event;
391
392 event = perf_event_create_kernel_counter(&hw_attr, -1, current,
393 overflow_handler_test_nolock,
394 ctx);
395
396 if (IS_ERR(event))
397 return false;
398
399 ctx->event = event;
400 perf_event_enable(ctx->event);
401 return true;
402 }
403
disable_perf_events(struct test_nolock_context * ctx)404 static void disable_perf_events(struct test_nolock_context *ctx)
405 {
406 kunit_info(ctx->test, "HW perf events: callback_count: %d, alloc_ok: %d, alloc_fail: %d\n",
407 ctx->callback_count, ctx->alloc_ok, ctx->alloc_fail);
408
409 perf_event_disable(ctx->event);
410 perf_event_release_kernel(ctx->event);
411 }
412
test_kmalloc_nolock_and_friends_perf(struct kunit * test)413 static void test_kmalloc_nolock_and_friends_perf(struct kunit *test)
414 {
415 struct test_nolock_context ctx = { .test = test };
416
417 if (!enable_perf_events(&ctx))
418 kunit_skip(test, "Failed to enable perf event, skipping");
419
420 test_kmalloc_and_friends();
421
422 disable_perf_events(&ctx);
423 KUNIT_EXPECT_EQ(test, 0, slab_errors);
424 }
425 #endif
426
427 #if defined(CONFIG_KPROBES) && defined(CONFIG_SMP)
slab_kprobe_pre_handler(struct kprobe * p,struct pt_regs * regs)428 static int slab_kprobe_pre_handler(struct kprobe *p, struct pt_regs *regs)
429 {
430 struct test_nolock_context *ctx;
431
432 ctx = container_of(p, struct test_nolock_context, kprobe);
433 test_nolock(ctx);
434 return 0;
435 }
436
register_slab_kprobes(struct test_nolock_context * ctx)437 static bool register_slab_kprobes(struct test_nolock_context *ctx)
438 {
439 ctx->kprobe.symbol_name = "slab_attach_kprobe_locked";
440 ctx->kprobe.pre_handler = slab_kprobe_pre_handler;
441
442 if (register_kprobe(&ctx->kprobe))
443 return false;
444 return true;
445 }
446
unregister_slab_kprobes(struct test_nolock_context * ctx)447 static void unregister_slab_kprobes(struct test_nolock_context *ctx)
448 {
449 kunit_info(ctx->test, "kprobes: callback_count: %d, alloc_ok: %d, alloc_fail: %d\n",
450 ctx->callback_count, ctx->alloc_ok, ctx->alloc_fail);
451 unregister_kprobe(&ctx->kprobe);
452 }
453
test_kmalloc_nolock_and_friends_kprobe(struct kunit * test)454 static void test_kmalloc_nolock_and_friends_kprobe(struct kunit *test)
455 {
456 struct test_nolock_context ctx = { .test = test };
457
458 if (!register_slab_kprobes(&ctx))
459 kunit_skip(test, "Failed to register kprobe, skipping");
460
461 test_kmalloc_and_friends();
462
463 unregister_slab_kprobes(&ctx);
464 KUNIT_EXPECT_EQ(test, 0, slab_errors);
465 }
466 #endif
467
test_init(struct kunit * test)468 static int test_init(struct kunit *test)
469 {
470 slab_errors = 0;
471
472 kunit_add_named_resource(test, NULL, NULL, &resource,
473 "slab_errors", &slab_errors);
474 return 0;
475 }
476
477 static struct kunit_case test_cases[] = {
478 KUNIT_CASE(test_clobber_zone),
479
480 #ifndef CONFIG_KASAN
481 KUNIT_CASE(test_next_pointer),
482 KUNIT_CASE(test_first_word),
483 KUNIT_CASE(test_clobber_50th_byte),
484 #endif
485
486 KUNIT_CASE(test_clobber_redzone_free),
487 KUNIT_CASE(test_kmalloc_redzone_access),
488 KUNIT_CASE(test_kfree_rcu),
489 KUNIT_CASE(test_kfree_rcu_wq_destroy),
490 KUNIT_CASE(test_leak_destroy),
491 KUNIT_CASE(test_krealloc_redzone_zeroing),
492 #ifdef CONFIG_PERF_EVENTS
493 KUNIT_CASE_SLOW(test_kmalloc_nolock_and_friends_perf),
494 #endif
495 #if defined(CONFIG_KPROBES) && defined(CONFIG_SMP)
496 KUNIT_CASE_SLOW(test_kmalloc_nolock_and_friends_kprobe),
497 #endif
498 {}
499 };
500
501 static struct kunit_suite test_suite = {
502 .name = "slub_test",
503 .init = test_init,
504 .test_cases = test_cases,
505 };
506 kunit_test_suite(test_suite);
507
508 MODULE_DESCRIPTION("Kunit tests for slub allocator");
509 MODULE_LICENSE("GPL");
510