Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lkdtm: Add FAM_BOUNDS test for __counted_by

Add new CONFIG_UBSAN_BOUNDS test for __counted_by attribute.

Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Kees Cook <keescook@chromium.org>

+44 -3
+44 -3
drivers/misc/lkdtm/bugs.c
··· 273 273 schedule(); 274 274 } 275 275 276 - volatile unsigned int huge = INT_MAX - 2; 277 - volatile unsigned int ignored; 276 + static volatile unsigned int huge = INT_MAX - 2; 277 + static volatile unsigned int ignored; 278 278 279 279 static void lkdtm_OVERFLOW_SIGNED(void) 280 280 { ··· 305 305 ignored = value; 306 306 } 307 307 308 - /* Intentionally using old-style flex array definition of 1 byte. */ 308 + /* Intentionally using unannotated flex array definition. */ 309 309 struct array_bounds_flex_array { 310 310 int one; 311 311 int two; ··· 352 352 kfree(checked); 353 353 pr_err("FAIL: survived array bounds overflow!\n"); 354 354 if (IS_ENABLED(CONFIG_UBSAN_BOUNDS)) 355 + pr_expected_config(CONFIG_UBSAN_TRAP); 356 + else 357 + pr_expected_config(CONFIG_UBSAN_BOUNDS); 358 + } 359 + 360 + struct lkdtm_annotated { 361 + unsigned long flags; 362 + int count; 363 + int array[] __counted_by(count); 364 + }; 365 + 366 + static volatile int fam_count = 4; 367 + 368 + static void lkdtm_FAM_BOUNDS(void) 369 + { 370 + struct lkdtm_annotated *inst; 371 + 372 + inst = kzalloc(struct_size(inst, array, fam_count + 1), GFP_KERNEL); 373 + if (!inst) { 374 + pr_err("FAIL: could not allocate test struct!\n"); 375 + return; 376 + } 377 + 378 + inst->count = fam_count; 379 + pr_info("Array access within bounds ...\n"); 380 + inst->array[1] = fam_count; 381 + ignored = inst->array[1]; 382 + 383 + pr_info("Array access beyond bounds ...\n"); 384 + inst->array[fam_count] = fam_count; 385 + ignored = inst->array[fam_count]; 386 + 387 + kfree(inst); 388 + 389 + pr_err("FAIL: survived access of invalid flexible array member index!\n"); 390 + 391 + if (!__has_attribute(__counted_by__)) 392 + pr_warn("This is expected since this %s was built a compiler supporting __counted_by\n", 393 + lkdtm_kernel_info); 394 + else if (IS_ENABLED(CONFIG_UBSAN_BOUNDS)) 355 395 pr_expected_config(CONFIG_UBSAN_TRAP); 356 396 else 357 397 pr_expected_config(CONFIG_UBSAN_BOUNDS); ··· 656 616 CRASHTYPE(OVERFLOW_SIGNED), 657 617 CRASHTYPE(OVERFLOW_UNSIGNED), 658 618 CRASHTYPE(ARRAY_BOUNDS), 619 + CRASHTYPE(FAM_BOUNDS), 659 620 CRASHTYPE(CORRUPT_LIST_ADD), 660 621 CRASHTYPE(CORRUPT_LIST_DEL), 661 622 CRASHTYPE(STACK_GUARD_PAGE_LEADING),