1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Test cases for KMSAN. 4 * For each test case checks the presence (or absence) of generated reports. 5 * Relies on 'console' tracepoint to capture reports as they appear in the 6 * kernel log. 7 * 8 * Copyright (C) 2021-2022, Google LLC. 9 * Author: Alexander Potapenko <glider@google.com> 10 * 11 */ 12 13 #include <kunit/test.h> 14 #include "kmsan.h" 15 16 #include <linux/jiffies.h> 17 #include <linux/kernel.h> 18 #include <linux/kmsan.h> 19 #include <linux/mm.h> 20 #include <linux/random.h> 21 #include <linux/slab.h> 22 #include <linux/spinlock.h> 23 #include <linux/string.h> 24 #include <linux/tracepoint.h> 25 #include <linux/vmalloc.h> 26 #include <trace/events/printk.h> 27 28 static DEFINE_PER_CPU(int, per_cpu_var); 29 30 /* Report as observed from console. */ 31 static struct { 32 spinlock_t lock; 33 bool available; 34 bool ignore; /* Stop console output collection. */ 35 char header[256]; 36 } observed = { 37 .lock = __SPIN_LOCK_UNLOCKED(observed.lock), 38 }; 39 40 /* Probe for console output: obtains observed lines of interest. */ 41 static void probe_console(void *ignore, const char *buf, size_t len) 42 { 43 unsigned long flags; 44 45 if (observed.ignore) 46 return; 47 spin_lock_irqsave(&observed.lock, flags); 48 49 if (strnstr(buf, "BUG: KMSAN: ", len)) { 50 /* 51 * KMSAN report and related to the test. 52 * 53 * The provided @buf is not NUL-terminated; copy no more than 54 * @len bytes and let strscpy() add the missing NUL-terminator. 55 */ 56 strscpy(observed.header, buf, 57 min(len + 1, sizeof(observed.header))); 58 WRITE_ONCE(observed.available, true); 59 observed.ignore = true; 60 } 61 spin_unlock_irqrestore(&observed.lock, flags); 62 } 63 64 /* Check if a report related to the test exists. */ 65 static bool report_available(void) 66 { 67 return READ_ONCE(observed.available); 68 } 69 70 /* Information we expect in a report. */ 71 struct expect_report { 72 const char *error_type; /* Error type. */ 73 /* 74 * Kernel symbol from the error header, or NULL if no report is 75 * expected. 76 */ 77 const char *symbol; 78 }; 79 80 /* Check observed report matches information in @r. */ 81 static bool report_matches(const struct expect_report *r) 82 { 83 typeof(observed.header) expected_header; 84 unsigned long flags; 85 bool ret = false; 86 const char *end; 87 char *cur; 88 89 /* Doubled-checked locking. */ 90 if (!report_available() || !r->symbol) 91 return (!report_available() && !r->symbol); 92 93 /* Generate expected report contents. */ 94 95 /* Title */ 96 cur = expected_header; 97 end = &expected_header[sizeof(expected_header) - 1]; 98 99 cur += scnprintf(cur, end - cur, "BUG: KMSAN: %s", r->error_type); 100 101 scnprintf(cur, end - cur, " in %s", r->symbol); 102 /* The exact offset won't match, remove it; also strip module name. */ 103 cur = strchr(expected_header, '+'); 104 if (cur) 105 *cur = '\0'; 106 107 spin_lock_irqsave(&observed.lock, flags); 108 if (!report_available()) 109 goto out; /* A new report is being captured. */ 110 111 /* Finally match expected output to what we actually observed. */ 112 ret = strstr(observed.header, expected_header); 113 out: 114 spin_unlock_irqrestore(&observed.lock, flags); 115 116 return ret; 117 } 118 119 /* ===== Test cases ===== */ 120 121 /* Prevent replacing branch with select in LLVM. */ 122 static noinline void check_true(char *arg) 123 { 124 pr_info("%s is true\n", arg); 125 } 126 127 static noinline void check_false(char *arg) 128 { 129 pr_info("%s is false\n", arg); 130 } 131 132 #define USE(x) \ 133 do { \ 134 if (x) \ 135 check_true(#x); \ 136 else \ 137 check_false(#x); \ 138 } while (0) 139 140 #define EXPECTATION_ETYPE_FN(e, reason, fn) \ 141 struct expect_report e = { \ 142 .error_type = reason, \ 143 .symbol = fn, \ 144 } 145 146 #define EXPECTATION_NO_REPORT(e) EXPECTATION_ETYPE_FN(e, NULL, NULL) 147 #define EXPECTATION_UNINIT_VALUE_FN(e, fn) \ 148 EXPECTATION_ETYPE_FN(e, "uninit-value", fn) 149 #define EXPECTATION_UNINIT_VALUE(e) EXPECTATION_UNINIT_VALUE_FN(e, __func__) 150 #define EXPECTATION_USE_AFTER_FREE(e) \ 151 EXPECTATION_ETYPE_FN(e, "use-after-free", __func__) 152 153 /* Test case: ensure that kmalloc() returns uninitialized memory. */ 154 static void test_uninit_kmalloc(struct kunit *test) 155 { 156 EXPECTATION_UNINIT_VALUE(expect); 157 int *ptr; 158 159 kunit_info(test, "uninitialized kmalloc test (UMR report)\n"); 160 ptr = kmalloc(sizeof(*ptr), GFP_KERNEL); 161 USE(*ptr); 162 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 163 } 164 165 /* 166 * Test case: ensure that kmalloc'ed memory becomes initialized after memset(). 167 */ 168 static void test_init_kmalloc(struct kunit *test) 169 { 170 EXPECTATION_NO_REPORT(expect); 171 int *ptr; 172 173 kunit_info(test, "initialized kmalloc test (no reports)\n"); 174 ptr = kmalloc(sizeof(*ptr), GFP_KERNEL); 175 memset(ptr, 0, sizeof(*ptr)); 176 USE(*ptr); 177 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 178 } 179 180 /* Test case: ensure that kzalloc() returns initialized memory. */ 181 static void test_init_kzalloc(struct kunit *test) 182 { 183 EXPECTATION_NO_REPORT(expect); 184 int *ptr; 185 186 kunit_info(test, "initialized kzalloc test (no reports)\n"); 187 ptr = kzalloc(sizeof(*ptr), GFP_KERNEL); 188 USE(*ptr); 189 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 190 } 191 192 /* Test case: ensure that local variables are uninitialized by default. */ 193 static void test_uninit_stack_var(struct kunit *test) 194 { 195 EXPECTATION_UNINIT_VALUE(expect); 196 volatile int cond; 197 198 kunit_info(test, "uninitialized stack variable (UMR report)\n"); 199 USE(cond); 200 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 201 } 202 203 /* Test case: ensure that local variables with initializers are initialized. */ 204 static void test_init_stack_var(struct kunit *test) 205 { 206 EXPECTATION_NO_REPORT(expect); 207 volatile int cond = 1; 208 209 kunit_info(test, "initialized stack variable (no reports)\n"); 210 USE(cond); 211 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 212 } 213 214 static noinline void two_param_fn_2(int arg1, int arg2) 215 { 216 USE(arg1); 217 USE(arg2); 218 } 219 220 static noinline void one_param_fn(int arg) 221 { 222 two_param_fn_2(arg, arg); 223 USE(arg); 224 } 225 226 static noinline void two_param_fn(int arg1, int arg2) 227 { 228 int init = 0; 229 230 one_param_fn(init); 231 USE(arg1); 232 USE(arg2); 233 } 234 235 static void test_params(struct kunit *test) 236 { 237 #ifdef CONFIG_KMSAN_CHECK_PARAM_RETVAL 238 /* 239 * With eager param/retval checking enabled, KMSAN will report an error 240 * before the call to two_param_fn(). 241 */ 242 EXPECTATION_UNINIT_VALUE_FN(expect, "test_params"); 243 #else 244 EXPECTATION_UNINIT_VALUE_FN(expect, "two_param_fn"); 245 #endif 246 volatile int uninit, init = 1; 247 248 kunit_info(test, 249 "uninit passed through a function parameter (UMR report)\n"); 250 two_param_fn(uninit, init); 251 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 252 } 253 254 static int signed_sum3(int a, int b, int c) 255 { 256 return a + b + c; 257 } 258 259 /* 260 * Test case: ensure that uninitialized values are tracked through function 261 * arguments. 262 */ 263 static void test_uninit_multiple_params(struct kunit *test) 264 { 265 EXPECTATION_UNINIT_VALUE(expect); 266 volatile char b = 3, c; 267 volatile int a; 268 269 kunit_info(test, "uninitialized local passed to fn (UMR report)\n"); 270 USE(signed_sum3(a, b, c)); 271 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 272 } 273 274 /* Helper function to make an array uninitialized. */ 275 static noinline void do_uninit_local_array(char *array, int start, int stop) 276 { 277 volatile char uninit; 278 279 for (int i = start; i < stop; i++) 280 array[i] = uninit; 281 } 282 283 /* 284 * Test case: ensure kmsan_check_memory() reports an error when checking 285 * uninitialized memory. 286 */ 287 static void test_uninit_kmsan_check_memory(struct kunit *test) 288 { 289 EXPECTATION_UNINIT_VALUE_FN(expect, "test_uninit_kmsan_check_memory"); 290 volatile char local_array[8]; 291 292 kunit_info( 293 test, 294 "kmsan_check_memory() called on uninit local (UMR report)\n"); 295 do_uninit_local_array((char *)local_array, 5, 7); 296 297 kmsan_check_memory((char *)local_array, 8); 298 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 299 } 300 301 /* 302 * Test case: check that a virtual memory range created with vmap() from 303 * initialized pages is still considered as initialized. 304 */ 305 static void test_init_kmsan_vmap_vunmap(struct kunit *test) 306 { 307 EXPECTATION_NO_REPORT(expect); 308 const int npages = 2; 309 struct page **pages; 310 void *vbuf; 311 312 kunit_info(test, "pages initialized via vmap (no reports)\n"); 313 314 pages = kmalloc_array(npages, sizeof(*pages), GFP_KERNEL); 315 for (int i = 0; i < npages; i++) 316 pages[i] = alloc_page(GFP_KERNEL); 317 vbuf = vmap(pages, npages, VM_MAP, PAGE_KERNEL); 318 memset(vbuf, 0xfe, npages * PAGE_SIZE); 319 for (int i = 0; i < npages; i++) 320 kmsan_check_memory(page_address(pages[i]), PAGE_SIZE); 321 322 if (vbuf) 323 vunmap(vbuf); 324 for (int i = 0; i < npages; i++) { 325 if (pages[i]) 326 __free_page(pages[i]); 327 } 328 kfree(pages); 329 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 330 } 331 332 /* 333 * Test case: ensure that memset() can initialize a buffer allocated via 334 * vmalloc(). 335 */ 336 static void test_init_vmalloc(struct kunit *test) 337 { 338 EXPECTATION_NO_REPORT(expect); 339 int npages = 8; 340 char *buf; 341 342 kunit_info(test, "vmalloc buffer can be initialized (no reports)\n"); 343 buf = vmalloc(PAGE_SIZE * npages); 344 buf[0] = 1; 345 memset(buf, 0xfe, PAGE_SIZE * npages); 346 USE(buf[0]); 347 for (int i = 0; i < npages; i++) 348 kmsan_check_memory(&buf[PAGE_SIZE * i], PAGE_SIZE); 349 vfree(buf); 350 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 351 } 352 353 /* Test case: ensure that use-after-free reporting works. */ 354 static void test_uaf(struct kunit *test) 355 { 356 EXPECTATION_USE_AFTER_FREE(expect); 357 volatile int value; 358 volatile int *var; 359 360 kunit_info(test, "use-after-free in kmalloc-ed buffer (UMR report)\n"); 361 var = kmalloc(80, GFP_KERNEL); 362 var[3] = 0xfeedface; 363 kfree((int *)var); 364 /* Copy the invalid value before checking it. */ 365 value = var[3]; 366 USE(value); 367 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 368 } 369 370 /* 371 * Test case: ensure that uninitialized values are propagated through per-CPU 372 * memory. 373 */ 374 static void test_percpu_propagate(struct kunit *test) 375 { 376 EXPECTATION_UNINIT_VALUE(expect); 377 volatile int uninit, check; 378 379 kunit_info(test, 380 "uninit local stored to per_cpu memory (UMR report)\n"); 381 382 this_cpu_write(per_cpu_var, uninit); 383 check = this_cpu_read(per_cpu_var); 384 USE(check); 385 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 386 } 387 388 /* 389 * Test case: ensure that passing uninitialized values to printk() leads to an 390 * error report. 391 */ 392 static void test_printk(struct kunit *test) 393 { 394 #ifdef CONFIG_KMSAN_CHECK_PARAM_RETVAL 395 /* 396 * With eager param/retval checking enabled, KMSAN will report an error 397 * before the call to pr_info(). 398 */ 399 EXPECTATION_UNINIT_VALUE_FN(expect, "test_printk"); 400 #else 401 EXPECTATION_UNINIT_VALUE_FN(expect, "number"); 402 #endif 403 volatile int uninit; 404 405 kunit_info(test, "uninit local passed to pr_info() (UMR report)\n"); 406 pr_info("%px contains %d\n", &uninit, uninit); 407 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 408 } 409 410 /* 411 * Test case: ensure that memcpy() correctly copies uninitialized values between 412 * aligned `src` and `dst`. 413 */ 414 static void test_memcpy_aligned_to_aligned(struct kunit *test) 415 { 416 EXPECTATION_UNINIT_VALUE_FN(expect, "test_memcpy_aligned_to_aligned"); 417 volatile int uninit_src; 418 volatile int dst = 0; 419 420 kunit_info( 421 test, 422 "memcpy()ing aligned uninit src to aligned dst (UMR report)\n"); 423 OPTIMIZER_HIDE_VAR(uninit_src); 424 memcpy((void *)&dst, (void *)&uninit_src, sizeof(uninit_src)); 425 kmsan_check_memory((void *)&dst, sizeof(dst)); 426 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 427 } 428 429 /* 430 * Test case: ensure that memcpy() correctly copies uninitialized values between 431 * aligned `src` and unaligned `dst`. 432 * 433 * Copying aligned 4-byte value to an unaligned one leads to touching two 434 * aligned 4-byte values. This test case checks that KMSAN correctly reports an 435 * error on the first of the two values. 436 */ 437 static void test_memcpy_aligned_to_unaligned(struct kunit *test) 438 { 439 EXPECTATION_UNINIT_VALUE_FN(expect, "test_memcpy_aligned_to_unaligned"); 440 volatile int uninit_src; 441 volatile char dst[8] = { 0 }; 442 443 kunit_info( 444 test, 445 "memcpy()ing aligned uninit src to unaligned dst (UMR report)\n"); 446 OPTIMIZER_HIDE_VAR(uninit_src); 447 memcpy((void *)&dst[1], (void *)&uninit_src, sizeof(uninit_src)); 448 kmsan_check_memory((void *)dst, 4); 449 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 450 } 451 452 /* 453 * Test case: ensure that memcpy() correctly copies uninitialized values between 454 * aligned `src` and unaligned `dst`. 455 * 456 * Copying aligned 4-byte value to an unaligned one leads to touching two 457 * aligned 4-byte values. This test case checks that KMSAN correctly reports an 458 * error on the second of the two values. 459 */ 460 static void test_memcpy_aligned_to_unaligned2(struct kunit *test) 461 { 462 EXPECTATION_UNINIT_VALUE_FN(expect, 463 "test_memcpy_aligned_to_unaligned2"); 464 volatile int uninit_src; 465 volatile char dst[8] = { 0 }; 466 467 kunit_info( 468 test, 469 "memcpy()ing aligned uninit src to unaligned dst - part 2 (UMR report)\n"); 470 OPTIMIZER_HIDE_VAR(uninit_src); 471 memcpy((void *)&dst[1], (void *)&uninit_src, sizeof(uninit_src)); 472 kmsan_check_memory((void *)&dst[4], sizeof(uninit_src)); 473 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 474 } 475 476 static noinline void fibonacci(int *array, int size, int start) { 477 if (start < 2 || (start == size)) 478 return; 479 array[start] = array[start - 1] + array[start - 2]; 480 fibonacci(array, size, start + 1); 481 } 482 483 static void test_long_origin_chain(struct kunit *test) 484 { 485 EXPECTATION_UNINIT_VALUE_FN(expect, 486 "test_long_origin_chain"); 487 /* (KMSAN_MAX_ORIGIN_DEPTH * 2) recursive calls to fibonacci(). */ 488 volatile int accum[KMSAN_MAX_ORIGIN_DEPTH * 2 + 2]; 489 int last = ARRAY_SIZE(accum) - 1; 490 491 kunit_info( 492 test, 493 "origin chain exceeding KMSAN_MAX_ORIGIN_DEPTH (UMR report)\n"); 494 /* 495 * We do not set accum[1] to 0, so the uninitializedness will be carried 496 * over to accum[2..last]. 497 */ 498 accum[0] = 1; 499 fibonacci((int *)accum, ARRAY_SIZE(accum), 2); 500 kmsan_check_memory((void *)&accum[last], sizeof(int)); 501 KUNIT_EXPECT_TRUE(test, report_matches(&expect)); 502 } 503 504 static struct kunit_case kmsan_test_cases[] = { 505 KUNIT_CASE(test_uninit_kmalloc), 506 KUNIT_CASE(test_init_kmalloc), 507 KUNIT_CASE(test_init_kzalloc), 508 KUNIT_CASE(test_uninit_stack_var), 509 KUNIT_CASE(test_init_stack_var), 510 KUNIT_CASE(test_params), 511 KUNIT_CASE(test_uninit_multiple_params), 512 KUNIT_CASE(test_uninit_kmsan_check_memory), 513 KUNIT_CASE(test_init_kmsan_vmap_vunmap), 514 KUNIT_CASE(test_init_vmalloc), 515 KUNIT_CASE(test_uaf), 516 KUNIT_CASE(test_percpu_propagate), 517 KUNIT_CASE(test_printk), 518 KUNIT_CASE(test_memcpy_aligned_to_aligned), 519 KUNIT_CASE(test_memcpy_aligned_to_unaligned), 520 KUNIT_CASE(test_memcpy_aligned_to_unaligned2), 521 KUNIT_CASE(test_long_origin_chain), 522 {}, 523 }; 524 525 /* ===== End test cases ===== */ 526 527 static int test_init(struct kunit *test) 528 { 529 unsigned long flags; 530 531 spin_lock_irqsave(&observed.lock, flags); 532 observed.header[0] = '\0'; 533 observed.ignore = false; 534 observed.available = false; 535 spin_unlock_irqrestore(&observed.lock, flags); 536 537 return 0; 538 } 539 540 static void test_exit(struct kunit *test) 541 { 542 } 543 544 static void register_tracepoints(struct tracepoint *tp, void *ignore) 545 { 546 check_trace_callback_type_console(probe_console); 547 if (!strcmp(tp->name, "console")) 548 WARN_ON(tracepoint_probe_register(tp, probe_console, NULL)); 549 } 550 551 static void unregister_tracepoints(struct tracepoint *tp, void *ignore) 552 { 553 if (!strcmp(tp->name, "console")) 554 tracepoint_probe_unregister(tp, probe_console, NULL); 555 } 556 557 static int kmsan_suite_init(struct kunit_suite *suite) 558 { 559 /* 560 * Because we want to be able to build the test as a module, we need to 561 * iterate through all known tracepoints, since the static registration 562 * won't work here. 563 */ 564 for_each_kernel_tracepoint(register_tracepoints, NULL); 565 return 0; 566 } 567 568 static void kmsan_suite_exit(struct kunit_suite *suite) 569 { 570 for_each_kernel_tracepoint(unregister_tracepoints, NULL); 571 tracepoint_synchronize_unregister(); 572 } 573 574 static struct kunit_suite kmsan_test_suite = { 575 .name = "kmsan", 576 .test_cases = kmsan_test_cases, 577 .init = test_init, 578 .exit = test_exit, 579 .suite_init = kmsan_suite_init, 580 .suite_exit = kmsan_suite_exit, 581 }; 582 kunit_test_suites(&kmsan_test_suite); 583 584 MODULE_LICENSE("GPL"); 585 MODULE_AUTHOR("Alexander Potapenko <glider@google.com>"); 586