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

Merge tag 'hardening-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux

Pull hardening updates from Kees Cook:
"The bulk of the changes here are related to refactoring and expanding
the KUnit tests for string helper and fortify behavior.

Some trivial strncpy replacements in fs/ were carried in my tree. Also
some fixes to SCSI string handling were carried in my tree since the
helper for those was introduce here. Beyond that, just little fixes
all around: objtool getting confused about LKDTM+KCFI, preparing for
future refactors (constification of sysctl tables, additional
__counted_by annotations), a Clang UBSAN+i386 crash fix, and adding
more options in the hardening.config Kconfig fragment.

Summary:

- selftests: Add str*cmp tests (Ivan Orlov)

- __counted_by: provide UAPI for _le/_be variants (Erick Archer)

- Various strncpy deprecation refactors (Justin Stitt)

- stackleak: Use a copy of soon-to-be-const sysctl table (Thomas
Weißschuh)

- UBSAN: Work around i386 -regparm=3 bug with Clang prior to
version 19

- Provide helper to deal with non-NUL-terminated string copying

- SCSI: Fix older string copying bugs (with new helper)

- selftests: Consolidate string helper behavioral tests

- selftests: add memcpy() fortify tests

- string: Add additional __realloc_size() annotations for "dup"
helpers

- LKDTM: Fix KCFI+rodata+objtool confusion

- hardening.config: Enable KCFI"

* tag 'hardening-6.10-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: (29 commits)
uapi: stddef.h: Provide UAPI macros for __counted_by_{le, be}
stackleak: Use a copy of the ctl_table argument
string: Add additional __realloc_size() annotations for "dup" helpers
kunit/fortify: Fix replaced failure path to unbreak __alloc_size
hardening: Enable KCFI and some other options
lkdtm: Disable CFI checking for perms functions
kunit/fortify: Add memcpy() tests
kunit/fortify: Do not spam logs with fortify WARNs
kunit/fortify: Rename tests to use recommended conventions
init: replace deprecated strncpy with strscpy_pad
kunit/fortify: Fix mismatched kvalloc()/vfree() usage
scsi: qla2xxx: Avoid possible run-time warning with long model_num
scsi: mpi3mr: Avoid possible run-time warning with long manufacturer strings
scsi: mptfusion: Avoid possible run-time warning with long manufacturer strings
fs: ecryptfs: replace deprecated strncpy with strscpy
hfsplus: refactor copy_name to not use strncpy
reiserfs: replace deprecated strncpy with scnprintf
virt: acrn: replace deprecated strncpy with strscpy
ubsan: Avoid i386 UBSAN handler crashes with Clang
ubsan: Remove 1-element array usage in debug reporting
...

+768 -477
+1 -2
MAINTAINERS
··· 8463 8463 F: include/linux/fortify-string.h 8464 8464 F: lib/fortify_kunit.c 8465 8465 F: lib/memcpy_kunit.c 8466 - F: lib/strcat_kunit.c 8467 - F: lib/strscpy_kunit.c 8468 8466 F: lib/test_fortify/* 8469 8467 F: scripts/test_fortify.sh 8470 8468 K: \b__NO_FORTIFY\b ··· 22689 22691 F: lib/Kconfig.ubsan 22690 22692 F: lib/test_ubsan.c 22691 22693 F: lib/ubsan.c 22694 + F: lib/ubsan.h 22692 22695 F: scripts/Makefile.ubsan 22693 22696 K: \bARCH_HAS_UBSAN\b 22694 22697
+1
arch/arm64/configs/hardening.config
··· 5 5 6 6 # Software Shadow Stack or PAC 7 7 CONFIG_SHADOW_CALL_STACK=y 8 + CONFIG_UNWIND_PATCH_PAC_INTO_SCS=y 8 9 9 10 # Pointer authentication (ARMv8.3 and later). If hardware actually supports 10 11 # it, one can turn off CONFIG_STACKPROTECTOR_STRONG with this enabled.
+3
arch/x86/configs/hardening.config
··· 10 10 CONFIG_INTEL_IOMMU_SVM=y 11 11 CONFIG_AMD_IOMMU=y 12 12 13 + # Enforce CET Indirect Branch Tracking in the kernel. 14 + CONFIG_X86_KERNEL_IBT=y 15 + 13 16 # Enable CET Shadow Stack for userspace. 14 17 CONFIG_X86_USER_SHADOW_STACK=y
+5 -9
drivers/message/fusion/mptsas.c
··· 2964 2964 goto out_free; 2965 2965 2966 2966 manufacture_reply = data_out + sizeof(struct rep_manu_request); 2967 - strscpy(edev->vendor_id, manufacture_reply->vendor_id, 2968 - sizeof(edev->vendor_id)); 2969 - strscpy(edev->product_id, manufacture_reply->product_id, 2970 - sizeof(edev->product_id)); 2971 - strscpy(edev->product_rev, manufacture_reply->product_rev, 2972 - sizeof(edev->product_rev)); 2967 + memtostr(edev->vendor_id, manufacture_reply->vendor_id); 2968 + memtostr(edev->product_id, manufacture_reply->product_id); 2969 + memtostr(edev->product_rev, manufacture_reply->product_rev); 2973 2970 edev->level = manufacture_reply->sas_format; 2974 2971 if (manufacture_reply->sas_format) { 2975 - strscpy(edev->component_vendor_id, 2976 - manufacture_reply->component_vendor_id, 2977 - sizeof(edev->component_vendor_id)); 2972 + memtostr(edev->component_vendor_id, 2973 + manufacture_reply->component_vendor_id); 2978 2974 tmp = (u8 *)&manufacture_reply->component_id; 2979 2975 edev->component_id = tmp[0] << 8 | tmp[1]; 2980 2976 edev->component_revision_id =
+1 -1
drivers/misc/lkdtm/Makefile
··· 19 19 KCSAN_SANITIZE_rodata.o := n 20 20 KCOV_INSTRUMENT_rodata.o := n 21 21 OBJECT_FILES_NON_STANDARD_rodata.o := y 22 - CFLAGS_REMOVE_rodata.o += $(CC_FLAGS_LTO) $(RETHUNK_CFLAGS) 22 + CFLAGS_REMOVE_rodata.o += $(CC_FLAGS_LTO) $(RETHUNK_CFLAGS) $(CC_FLAGS_CFI) 23 23 24 24 OBJCOPYFLAGS := 25 25 OBJCOPYFLAGS_rodata_objcopy.o := \
+1 -1
drivers/misc/lkdtm/perms.c
··· 61 61 return fdesc; 62 62 } 63 63 64 - static noinline void execute_location(void *dst, bool write) 64 + static noinline __nocfi void execute_location(void *dst, bool write) 65 65 { 66 66 void (*func)(void); 67 67 func_desc_t fdesc;
+5 -9
drivers/scsi/mpi3mr/mpi3mr_transport.c
··· 209 209 goto out; 210 210 } 211 211 212 - strscpy(edev->vendor_id, manufacture_reply->vendor_id, 213 - SAS_EXPANDER_VENDOR_ID_LEN); 214 - strscpy(edev->product_id, manufacture_reply->product_id, 215 - SAS_EXPANDER_PRODUCT_ID_LEN); 216 - strscpy(edev->product_rev, manufacture_reply->product_rev, 217 - SAS_EXPANDER_PRODUCT_REV_LEN); 212 + memtostr(edev->vendor_id, manufacture_reply->vendor_id); 213 + memtostr(edev->product_id, manufacture_reply->product_id); 214 + memtostr(edev->product_rev, manufacture_reply->product_rev); 218 215 edev->level = manufacture_reply->sas_format & 1; 219 216 if (edev->level) { 220 - strscpy(edev->component_vendor_id, 221 - manufacture_reply->component_vendor_id, 222 - SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN); 217 + memtostr(edev->component_vendor_id, 218 + manufacture_reply->component_vendor_id); 223 219 tmp = (u8 *)&manufacture_reply->component_id; 224 220 edev->component_id = tmp[0] << 8 | tmp[1]; 225 221 edev->component_revision_id =
+2 -4
drivers/scsi/qla2xxx/qla_mr.c
··· 1909 1909 if (fx_type == FXDISC_GET_CONFIG_INFO) { 1910 1910 struct config_info_data *pinfo = 1911 1911 (struct config_info_data *) fdisc->u.fxiocb.rsp_addr; 1912 - strscpy(vha->hw->model_number, pinfo->model_num, 1913 - ARRAY_SIZE(vha->hw->model_number)); 1914 - strscpy(vha->hw->model_desc, pinfo->model_description, 1915 - ARRAY_SIZE(vha->hw->model_desc)); 1912 + memtostr(vha->hw->model_number, pinfo->model_num); 1913 + memtostr(vha->hw->model_desc, pinfo->model_description); 1916 1914 memcpy(&vha->hw->mr.symbolic_name, pinfo->symbolic_name, 1917 1915 sizeof(vha->hw->mr.symbolic_name)); 1918 1916 memcpy(&vha->hw->mr.serial_num, pinfo->serial_num,
+1 -1
drivers/virt/acrn/ioreq.c
··· 433 433 client->priv = priv; 434 434 client->is_default = is_default; 435 435 if (name) 436 - strncpy(client->name, name, sizeof(client->name) - 1); 436 + strscpy(client->name, name); 437 437 rwlock_init(&client->range_lock); 438 438 INIT_LIST_HEAD(&client->range_list); 439 439 init_waitqueue_head(&client->wq);
+1 -3
fs/ecryptfs/crypto.c
··· 1606 1606 goto out; 1607 1607 } 1608 1608 mutex_init(&tmp_tfm->key_tfm_mutex); 1609 - strncpy(tmp_tfm->cipher_name, cipher_name, 1610 - ECRYPTFS_MAX_CIPHER_NAME_SIZE); 1611 - tmp_tfm->cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; 1609 + strscpy(tmp_tfm->cipher_name, cipher_name); 1612 1610 tmp_tfm->key_size = key_size; 1613 1611 rc = ecryptfs_process_key_cipher(&tmp_tfm->key_tfm, 1614 1612 tmp_tfm->cipher_name,
+6 -20
fs/ecryptfs/main.c
··· 256 256 substring_t args[MAX_OPT_ARGS]; 257 257 int token; 258 258 char *sig_src; 259 - char *cipher_name_dst; 260 259 char *cipher_name_src; 261 - char *fn_cipher_name_dst; 262 260 char *fn_cipher_name_src; 263 - char *fnek_dst; 264 261 char *fnek_src; 265 262 char *cipher_key_bytes_src; 266 263 char *fn_cipher_key_bytes_src; ··· 290 293 case ecryptfs_opt_cipher: 291 294 case ecryptfs_opt_ecryptfs_cipher: 292 295 cipher_name_src = args[0].from; 293 - cipher_name_dst = 294 - mount_crypt_stat-> 295 - global_default_cipher_name; 296 - strncpy(cipher_name_dst, cipher_name_src, 297 - ECRYPTFS_MAX_CIPHER_NAME_SIZE); 298 - cipher_name_dst[ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; 296 + strscpy(mount_crypt_stat->global_default_cipher_name, 297 + cipher_name_src); 299 298 cipher_name_set = 1; 300 299 break; 301 300 case ecryptfs_opt_ecryptfs_key_bytes: ··· 319 326 break; 320 327 case ecryptfs_opt_fnek_sig: 321 328 fnek_src = args[0].from; 322 - fnek_dst = 323 - mount_crypt_stat->global_default_fnek_sig; 324 - strncpy(fnek_dst, fnek_src, ECRYPTFS_SIG_SIZE_HEX); 325 - mount_crypt_stat->global_default_fnek_sig[ 326 - ECRYPTFS_SIG_SIZE_HEX] = '\0'; 329 + strscpy(mount_crypt_stat->global_default_fnek_sig, 330 + fnek_src); 327 331 rc = ecryptfs_add_global_auth_tok( 328 332 mount_crypt_stat, 329 333 mount_crypt_stat->global_default_fnek_sig, ··· 338 348 break; 339 349 case ecryptfs_opt_fn_cipher: 340 350 fn_cipher_name_src = args[0].from; 341 - fn_cipher_name_dst = 342 - mount_crypt_stat->global_default_fn_cipher_name; 343 - strncpy(fn_cipher_name_dst, fn_cipher_name_src, 344 - ECRYPTFS_MAX_CIPHER_NAME_SIZE); 345 - mount_crypt_stat->global_default_fn_cipher_name[ 346 - ECRYPTFS_MAX_CIPHER_NAME_SIZE] = '\0'; 351 + strscpy(mount_crypt_stat->global_default_fn_cipher_name, 352 + fn_cipher_name_src); 347 353 fn_cipher_name_set = 1; 348 354 break; 349 355 case ecryptfs_opt_fn_cipher_key_bytes:
+10 -12
fs/hfsplus/xattr.c
··· 400 400 return len; 401 401 } 402 402 403 - static int copy_name(char *buffer, const char *xattr_name, int name_len) 403 + static ssize_t copy_name(char *buffer, const char *xattr_name, int name_len) 404 404 { 405 - int len = name_len; 406 - int offset = 0; 405 + ssize_t len; 407 406 408 - if (!is_known_namespace(xattr_name)) { 409 - memcpy(buffer, XATTR_MAC_OSX_PREFIX, XATTR_MAC_OSX_PREFIX_LEN); 410 - offset += XATTR_MAC_OSX_PREFIX_LEN; 411 - len += XATTR_MAC_OSX_PREFIX_LEN; 412 - } 407 + if (!is_known_namespace(xattr_name)) 408 + len = scnprintf(buffer, name_len + XATTR_MAC_OSX_PREFIX_LEN, 409 + "%s%s", XATTR_MAC_OSX_PREFIX, xattr_name); 410 + else 411 + len = strscpy(buffer, xattr_name, name_len + 1); 413 412 414 - strncpy(buffer + offset, xattr_name, name_len); 415 - memset(buffer + offset + name_len, 0, 1); 416 - len += 1; 417 - 413 + /* include NUL-byte in length for non-empty name */ 414 + if (len >= 0) 415 + len++; 418 416 return len; 419 417 } 420 418
+3 -10
fs/reiserfs/item_ops.c
··· 389 389 name = item + deh_location(deh); 390 390 if (name[namelen - 1] == 0) 391 391 namelen = strlen(name); 392 - namebuf[0] = '"'; 393 - if (namelen > sizeof(namebuf) - 3) { 394 - strncpy(namebuf + 1, name, sizeof(namebuf) - 3); 395 - namebuf[sizeof(namebuf) - 2] = '"'; 396 - namebuf[sizeof(namebuf) - 1] = 0; 397 - } else { 398 - memcpy(namebuf + 1, name, namelen); 399 - namebuf[namelen + 1] = '"'; 400 - namebuf[namelen + 2] = 0; 401 - } 392 + 393 + scnprintf(namebuf, sizeof(namebuf), "\"%.*s\"", 394 + (int)sizeof(namebuf)-3, name); 402 395 403 396 printk("%d: %-15s%-15d%-15d%-15lld%-15lld(%s)\n", 404 397 i, namebuf,
+7 -2
include/linux/fortify-string.h
··· 15 15 #define FORTIFY_REASON(func, write) (FIELD_PREP(BIT(0), write) | \ 16 16 FIELD_PREP(GENMASK(7, 1), func)) 17 17 18 + /* Overridden by KUnit tests. */ 18 19 #ifndef fortify_panic 19 20 # define fortify_panic(func, write, avail, size, retfail) \ 20 21 __fortify_panic(FORTIFY_REASON(func, write), avail, size) 22 + #endif 23 + #ifndef fortify_warn_once 24 + # define fortify_warn_once(x...) WARN_ONCE(x) 21 25 #endif 22 26 23 27 #define FORTIFY_READ 0 ··· 613 609 const size_t __q_size = (q_size); \ 614 610 const size_t __p_size_field = (p_size_field); \ 615 611 const size_t __q_size_field = (q_size_field); \ 616 - WARN_ONCE(fortify_memcpy_chk(__fortify_size, __p_size, \ 612 + fortify_warn_once(fortify_memcpy_chk(__fortify_size, __p_size, \ 617 613 __q_size, __p_size_field, \ 618 614 __q_size_field, FORTIFY_FUNC_ ##op), \ 619 615 #op ": detected field-spanning write (size %zu) of single %s (size %zu)\n", \ ··· 738 734 if (__compiletime_lessthan(p_size, size)) 739 735 __read_overflow(); 740 736 if (p_size < size) 741 - fortify_panic(FORTIFY_FUNC_kmemdup, FORTIFY_READ, p_size, size, NULL); 737 + fortify_panic(FORTIFY_FUNC_kmemdup, FORTIFY_READ, p_size, size, 738 + __real_kmemdup(p, 0, gfp)); 742 739 return __real_kmemdup(p, size, gfp); 743 740 } 744 741
+57 -5
include/linux/string.h
··· 14 14 #include <uapi/linux/string.h> 15 15 16 16 extern char *strndup_user(const char __user *, long); 17 - extern void *memdup_user(const void __user *, size_t); 18 - extern void *vmemdup_user(const void __user *, size_t); 17 + extern void *memdup_user(const void __user *, size_t) __realloc_size(2); 18 + extern void *vmemdup_user(const void __user *, size_t) __realloc_size(2); 19 19 extern void *memdup_user_nul(const void __user *, size_t); 20 20 21 21 /** ··· 27 27 * Return: an ERR_PTR() on failure. Result is physically 28 28 * contiguous, to be freed by kfree(). 29 29 */ 30 - static inline void *memdup_array_user(const void __user *src, size_t n, size_t size) 30 + static inline __realloc_size(2, 3) 31 + void *memdup_array_user(const void __user *src, size_t n, size_t size) 31 32 { 32 33 size_t nbytes; 33 34 ··· 47 46 * Return: an ERR_PTR() on failure. Result may be not 48 47 * physically contiguous. Use kvfree() to free. 49 48 */ 50 - static inline void *vmemdup_array_user(const void __user *src, size_t n, size_t size) 49 + static inline __realloc_size(2, 3) 50 + void *vmemdup_array_user(const void __user *src, size_t n, size_t size) 51 51 { 52 52 size_t nbytes; 53 53 ··· 287 285 extern void *kmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2); 288 286 extern void *kvmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2); 289 287 extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp); 290 - extern void *kmemdup_array(const void *src, size_t element_size, size_t count, gfp_t gfp); 288 + extern void *kmemdup_array(const void *src, size_t element_size, size_t count, gfp_t gfp) 289 + __realloc_size(2, 3); 291 290 292 291 /* lib/argv_split.c */ 293 292 extern char **argv_split(gfp_t gfp, const char *str, int *argcp); ··· 423 420 BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ 424 421 _dest_len == (size_t)-1); \ 425 422 memcpy(dest, src, strnlen(src, min(_src_len, _dest_len))); \ 423 + } while (0) 424 + 425 + /** 426 + * memtostr - Copy a possibly non-NUL-term string to a NUL-term string 427 + * @dest: Pointer to destination NUL-terminates string 428 + * @src: Pointer to character array (likely marked as __nonstring) 429 + * 430 + * This is a replacement for strncpy() uses where the source is not 431 + * a NUL-terminated string. 432 + * 433 + * Note that sizes of @dest and @src must be known at compile-time. 434 + */ 435 + #define memtostr(dest, src) do { \ 436 + const size_t _dest_len = __builtin_object_size(dest, 1); \ 437 + const size_t _src_len = __builtin_object_size(src, 1); \ 438 + const size_t _src_chars = strnlen(src, _src_len); \ 439 + const size_t _copy_len = min(_dest_len - 1, _src_chars); \ 440 + \ 441 + BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ 442 + !__builtin_constant_p(_src_len) || \ 443 + _dest_len == 0 || _dest_len == (size_t)-1 || \ 444 + _src_len == 0 || _src_len == (size_t)-1); \ 445 + memcpy(dest, src, _copy_len); \ 446 + dest[_copy_len] = '\0'; \ 447 + } while (0) 448 + 449 + /** 450 + * memtostr_pad - Copy a possibly non-NUL-term string to a NUL-term string 451 + * with NUL padding in the destination 452 + * @dest: Pointer to destination NUL-terminates string 453 + * @src: Pointer to character array (likely marked as __nonstring) 454 + * 455 + * This is a replacement for strncpy() uses where the source is not 456 + * a NUL-terminated string. 457 + * 458 + * Note that sizes of @dest and @src must be known at compile-time. 459 + */ 460 + #define memtostr_pad(dest, src) do { \ 461 + const size_t _dest_len = __builtin_object_size(dest, 1); \ 462 + const size_t _src_len = __builtin_object_size(src, 1); \ 463 + const size_t _src_chars = strnlen(src, _src_len); \ 464 + const size_t _copy_len = min(_dest_len - 1, _src_chars); \ 465 + \ 466 + BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ 467 + !__builtin_constant_p(_src_len) || \ 468 + _dest_len == 0 || _dest_len == (size_t)-1 || \ 469 + _src_len == 0 || _src_len == (size_t)-1); \ 470 + memcpy(dest, src, _copy_len); \ 471 + memset(&dest[_copy_len], 0, _dest_len - _copy_len); \ 426 472 } while (0) 427 473 428 474 /**
+8
include/uapi/linux/stddef.h
··· 55 55 #define __counted_by(m) 56 56 #endif 57 57 58 + #ifndef __counted_by_le 59 + #define __counted_by_le(m) 60 + #endif 61 + 62 + #ifndef __counted_by_be 63 + #define __counted_by_be(m) 64 + #endif 65 + 58 66 #endif /* _UAPI_LINUX_STDDEF_H */
+1 -2
init/do_mounts.c
··· 159 159 if (!p) 160 160 return -ENOMEM; 161 161 data_page = page_address(p); 162 - /* zero-pad. init_mount() will make sure it's terminated */ 163 - strncpy(data_page, data, PAGE_SIZE); 162 + strscpy_pad(data_page, data, PAGE_SIZE); 164 163 } 165 164 166 165 ret = init_mount(name, "/root", fs, flags, data_page);
+8
kernel/configs/hardening.config
··· 23 23 CONFIG_SHUFFLE_PAGE_ALLOCATOR=y 24 24 CONFIG_RANDOM_KMALLOC_CACHES=y 25 25 26 + # Sanity check userspace page table mappings. 27 + CONFIG_PAGE_TABLE_CHECK=y 28 + CONFIG_PAGE_TABLE_CHECK_ENFORCED=y 29 + 26 30 # Randomize kernel stack offset on syscall entry. 27 31 CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y 28 32 ··· 85 81 86 82 # Provides some protections against SYN flooding. 87 83 CONFIG_SYN_COOKIES=y 84 + 85 + # Enable Kernel Control Flow Integrity (currently Clang only). 86 + CONFIG_CFI_CLANG=y 87 + # CONFIG_CFI_PERMISSIVE is not set 88 88 89 89 # Attack surface reduction: do not autoload TTY line disciplines. 90 90 # CONFIG_LDISC_AUTOLOAD is not set
+3 -3
kernel/stackleak.c
··· 27 27 int ret = 0; 28 28 int state = !static_branch_unlikely(&stack_erasing_bypass); 29 29 int prev_state = state; 30 + struct ctl_table table_copy = *table; 30 31 31 - table->data = &state; 32 - table->maxlen = sizeof(int); 33 - ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos); 32 + table_copy.data = &state; 33 + ret = proc_dointvec_minmax(&table_copy, write, buffer, lenp, ppos); 34 34 state = !!state; 35 35 if (ret || !write || state == prev_state) 36 36 return ret;
-10
lib/Kconfig.debug
··· 2759 2759 2760 2760 If unsure, say N. 2761 2761 2762 - config STRCAT_KUNIT_TEST 2763 - tristate "Test strcat() family of functions at runtime" if !KUNIT_ALL_TESTS 2764 - depends on KUNIT 2765 - default KUNIT_ALL_TESTS 2766 - 2767 - config STRSCPY_KUNIT_TEST 2768 - tristate "Test strscpy*() family of functions at runtime" if !KUNIT_ALL_TESTS 2769 - depends on KUNIT 2770 - default KUNIT_ALL_TESTS 2771 - 2772 2762 config SIPHASH_KUNIT_TEST 2773 2763 tristate "Perform selftest on siphash functions" if !KUNIT_ALL_TESTS 2774 2764 depends on KUNIT
-2
lib/Makefile
··· 404 404 CFLAGS_fortify_kunit.o += $(call cc-disable-warning, stringop-truncation) 405 405 CFLAGS_fortify_kunit.o += $(DISABLE_STRUCTLEAK_PLUGIN) 406 406 obj-$(CONFIG_FORTIFY_KUNIT_TEST) += fortify_kunit.o 407 - obj-$(CONFIG_STRCAT_KUNIT_TEST) += strcat_kunit.o 408 - obj-$(CONFIG_STRSCPY_KUNIT_TEST) += strscpy_kunit.o 409 407 obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o 410 408 411 409 obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
+167 -55
lib/fortify_kunit.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 - * Runtime test cases for CONFIG_FORTIFY_SOURCE. For testing memcpy(), 4 - * see FORTIFY_MEM_* tests in LKDTM (drivers/misc/lkdtm/fortify.c). 3 + * Runtime test cases for CONFIG_FORTIFY_SOURCE. For additional memcpy() 4 + * testing see FORTIFY_MEM_* tests in LKDTM (drivers/misc/lkdtm/fortify.c). 5 5 * 6 6 * For corner cases with UBSAN, try testing with: 7 7 * ··· 15 15 */ 16 16 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 17 17 18 + /* We don't need to fill dmesg with the fortify WARNs during testing. */ 19 + #ifdef DEBUG 20 + # define FORTIFY_REPORT_KUNIT(x...) __fortify_report(x) 21 + # define FORTIFY_WARN_KUNIT(x...) WARN_ONCE(x) 22 + #else 23 + # define FORTIFY_REPORT_KUNIT(x...) do { } while (0) 24 + # define FORTIFY_WARN_KUNIT(x...) do { } while (0) 25 + #endif 26 + 18 27 /* Redefine fortify_panic() to track failures. */ 19 28 void fortify_add_kunit_error(int write); 20 29 #define fortify_panic(func, write, avail, size, retfail) do { \ 21 - __fortify_report(FORTIFY_REASON(func, write), avail, size); \ 30 + FORTIFY_REPORT_KUNIT(FORTIFY_REASON(func, write), avail, size); \ 22 31 fortify_add_kunit_error(write); \ 23 32 return (retfail); \ 33 + } while (0) 34 + 35 + /* Redefine fortify_warn_once() to track memcpy() failures. */ 36 + #define fortify_warn_once(chk_func, x...) do { \ 37 + bool __result = chk_func; \ 38 + FORTIFY_WARN_KUNIT(__result, x); \ 39 + if (__result) \ 40 + fortify_add_kunit_error(1); \ 24 41 } while (0) 25 42 26 43 #include <kunit/device.h> ··· 81 64 kunit_put_resource(resource); 82 65 } 83 66 84 - static void known_sizes_test(struct kunit *test) 67 + static void fortify_test_known_sizes(struct kunit *test) 85 68 { 86 69 KUNIT_EXPECT_EQ(test, __compiletime_strlen("88888888"), 8); 87 70 KUNIT_EXPECT_EQ(test, __compiletime_strlen(array_of_10), 10); ··· 114 97 return __compiletime_strlen(str); 115 98 } 116 99 117 - static void control_flow_split_test(struct kunit *test) 100 + static void fortify_test_control_flow_split(struct kunit *test) 118 101 { 119 102 KUNIT_EXPECT_EQ(test, want_minus_one(pick), SIZE_MAX); 120 103 } ··· 190 173 #endif 191 174 192 175 #define DEFINE_ALLOC_SIZE_TEST_PAIR(allocator) \ 193 - static void alloc_size_##allocator##_const_test(struct kunit *test) \ 176 + static void fortify_test_alloc_size_##allocator##_const(struct kunit *test) \ 194 177 { \ 195 178 CONST_TEST_BODY(TEST_##allocator); \ 196 179 } \ 197 - static void alloc_size_##allocator##_dynamic_test(struct kunit *test) \ 180 + static void fortify_test_alloc_size_##allocator##_dynamic(struct kunit *test) \ 198 181 { \ 199 182 DYNAMIC_TEST_BODY(TEST_##allocator); \ 200 183 } ··· 284 267 \ 285 268 checker((expected_pages) * PAGE_SIZE, \ 286 269 kvmalloc((alloc_pages) * PAGE_SIZE, gfp), \ 287 - vfree(p)); \ 270 + kvfree(p)); \ 288 271 checker((expected_pages) * PAGE_SIZE, \ 289 272 kvmalloc_node((alloc_pages) * PAGE_SIZE, gfp, NUMA_NO_NODE), \ 290 - vfree(p)); \ 273 + kvfree(p)); \ 291 274 checker((expected_pages) * PAGE_SIZE, \ 292 275 kvzalloc((alloc_pages) * PAGE_SIZE, gfp), \ 293 - vfree(p)); \ 276 + kvfree(p)); \ 294 277 checker((expected_pages) * PAGE_SIZE, \ 295 278 kvzalloc_node((alloc_pages) * PAGE_SIZE, gfp, NUMA_NO_NODE), \ 296 - vfree(p)); \ 279 + kvfree(p)); \ 297 280 checker((expected_pages) * PAGE_SIZE, \ 298 281 kvcalloc(1, (alloc_pages) * PAGE_SIZE, gfp), \ 299 - vfree(p)); \ 282 + kvfree(p)); \ 300 283 checker((expected_pages) * PAGE_SIZE, \ 301 284 kvcalloc((alloc_pages) * PAGE_SIZE, 1, gfp), \ 302 - vfree(p)); \ 285 + kvfree(p)); \ 303 286 checker((expected_pages) * PAGE_SIZE, \ 304 287 kvmalloc_array(1, (alloc_pages) * PAGE_SIZE, gfp), \ 305 - vfree(p)); \ 288 + kvfree(p)); \ 306 289 checker((expected_pages) * PAGE_SIZE, \ 307 290 kvmalloc_array((alloc_pages) * PAGE_SIZE, 1, gfp), \ 308 - vfree(p)); \ 291 + kvfree(p)); \ 309 292 \ 310 293 prev_size = (expected_pages) * PAGE_SIZE; \ 311 294 orig = kvmalloc(prev_size, gfp); \ ··· 363 346 } while (0) 364 347 DEFINE_ALLOC_SIZE_TEST_PAIR(devm_kmalloc) 365 348 349 + static const char * const test_strs[] = { 350 + "", 351 + "Hello there", 352 + "A longer string, just for variety", 353 + }; 354 + 355 + #define TEST_realloc(checker) do { \ 356 + gfp_t gfp = GFP_KERNEL; \ 357 + size_t len; \ 358 + int i; \ 359 + \ 360 + for (i = 0; i < ARRAY_SIZE(test_strs); i++) { \ 361 + len = strlen(test_strs[i]); \ 362 + KUNIT_EXPECT_EQ(test, __builtin_constant_p(len), 0); \ 363 + checker(len, kmemdup_array(test_strs[i], len, 1, gfp), \ 364 + kfree(p)); \ 365 + checker(len, kmemdup(test_strs[i], len, gfp), \ 366 + kfree(p)); \ 367 + } \ 368 + } while (0) 369 + static void fortify_test_realloc_size(struct kunit *test) 370 + { 371 + TEST_realloc(check_dynamic); 372 + } 373 + 366 374 /* 367 375 * We can't have an array at the end of a structure or else 368 376 * builds without -fstrict-flex-arrays=3 will report them as ··· 403 361 /* Force compiler into not being able to resolve size at compile-time. */ 404 362 static volatile int unconst; 405 363 406 - static void strlen_test(struct kunit *test) 364 + static void fortify_test_strlen(struct kunit *test) 407 365 { 408 366 struct fortify_padding pad = { }; 409 367 int i, end = sizeof(pad.buf) - 1; ··· 426 384 KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1); 427 385 } 428 386 429 - static void strnlen_test(struct kunit *test) 387 + static void fortify_test_strnlen(struct kunit *test) 430 388 { 431 389 struct fortify_padding pad = { }; 432 390 int i, end = sizeof(pad.buf) - 1; ··· 464 422 KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 465 423 } 466 424 467 - static void strcpy_test(struct kunit *test) 425 + static void fortify_test_strcpy(struct kunit *test) 468 426 { 469 427 struct fortify_padding pad = { }; 470 428 char src[sizeof(pad.buf) + 1] = { }; ··· 522 480 KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 523 481 } 524 482 525 - static void strncpy_test(struct kunit *test) 483 + static void fortify_test_strncpy(struct kunit *test) 526 484 { 527 485 struct fortify_padding pad = { }; 528 486 char src[] = "Copy me fully into a small buffer and I will overflow!"; ··· 581 539 KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 582 540 } 583 541 584 - static void strscpy_test(struct kunit *test) 542 + static void fortify_test_strscpy(struct kunit *test) 585 543 { 586 544 struct fortify_padding pad = { }; 587 545 char src[] = "Copy me fully into a small buffer and I will overflow!"; ··· 638 596 KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 639 597 } 640 598 641 - static void strcat_test(struct kunit *test) 599 + static void fortify_test_strcat(struct kunit *test) 642 600 { 643 601 struct fortify_padding pad = { }; 644 602 char src[sizeof(pad.buf) / 2] = { }; ··· 695 653 KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 696 654 } 697 655 698 - static void strncat_test(struct kunit *test) 656 + static void fortify_test_strncat(struct kunit *test) 699 657 { 700 658 struct fortify_padding pad = { }; 701 659 char src[sizeof(pad.buf)] = { }; ··· 768 726 KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 769 727 } 770 728 771 - static void strlcat_test(struct kunit *test) 729 + static void fortify_test_strlcat(struct kunit *test) 772 730 { 773 731 struct fortify_padding pad = { }; 774 732 char src[sizeof(pad.buf)] = { }; ··· 853 811 KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); 854 812 } 855 813 856 - static void memscan_test(struct kunit *test) 814 + /* Check for 0-sized arrays... */ 815 + struct fortify_zero_sized { 816 + unsigned long bytes_before; 817 + char buf[0]; 818 + unsigned long bytes_after; 819 + }; 820 + 821 + #define __fortify_test(memfunc) \ 822 + static void fortify_test_##memfunc(struct kunit *test) \ 823 + { \ 824 + struct fortify_zero_sized zero = { }; \ 825 + struct fortify_padding pad = { }; \ 826 + char srcA[sizeof(pad.buf) + 2]; \ 827 + char srcB[sizeof(pad.buf) + 2]; \ 828 + size_t len = sizeof(pad.buf) + unconst; \ 829 + \ 830 + memset(srcA, 'A', sizeof(srcA)); \ 831 + KUNIT_ASSERT_EQ(test, srcA[0], 'A'); \ 832 + memset(srcB, 'B', sizeof(srcB)); \ 833 + KUNIT_ASSERT_EQ(test, srcB[0], 'B'); \ 834 + \ 835 + memfunc(pad.buf, srcA, 0 + unconst); \ 836 + KUNIT_EXPECT_EQ(test, pad.buf[0], '\0'); \ 837 + KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 838 + KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 839 + memfunc(pad.buf + 1, srcB, 1 + unconst); \ 840 + KUNIT_EXPECT_EQ(test, pad.buf[0], '\0'); \ 841 + KUNIT_EXPECT_EQ(test, pad.buf[1], 'B'); \ 842 + KUNIT_EXPECT_EQ(test, pad.buf[2], '\0'); \ 843 + KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 844 + KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 845 + memfunc(pad.buf, srcA, 1 + unconst); \ 846 + KUNIT_EXPECT_EQ(test, pad.buf[0], 'A'); \ 847 + KUNIT_EXPECT_EQ(test, pad.buf[1], 'B'); \ 848 + KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 849 + KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 850 + memfunc(pad.buf, srcA, len - 1); \ 851 + KUNIT_EXPECT_EQ(test, pad.buf[1], 'A'); \ 852 + KUNIT_EXPECT_EQ(test, pad.buf[len - 1], '\0'); \ 853 + KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 854 + KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 855 + memfunc(pad.buf, srcA, len); \ 856 + KUNIT_EXPECT_EQ(test, pad.buf[1], 'A'); \ 857 + KUNIT_EXPECT_EQ(test, pad.buf[len - 1], 'A'); \ 858 + KUNIT_EXPECT_EQ(test, pad.bytes_after, 0); \ 859 + KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 860 + KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 861 + memfunc(pad.buf, srcA, len + 1); \ 862 + KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 863 + KUNIT_EXPECT_EQ(test, fortify_write_overflows, 1); \ 864 + memfunc(pad.buf + 1, srcB, len); \ 865 + KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 866 + KUNIT_EXPECT_EQ(test, fortify_write_overflows, 2); \ 867 + \ 868 + /* Reset error counter. */ \ 869 + fortify_write_overflows = 0; \ 870 + /* Copy nothing into nothing: no errors. */ \ 871 + memfunc(zero.buf, srcB, 0 + unconst); \ 872 + KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 873 + KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 874 + /* We currently explicitly ignore zero-sized dests. */ \ 875 + memfunc(zero.buf, srcB, 1 + unconst); \ 876 + KUNIT_EXPECT_EQ(test, fortify_read_overflows, 0); \ 877 + KUNIT_EXPECT_EQ(test, fortify_write_overflows, 0); \ 878 + } 879 + __fortify_test(memcpy) 880 + __fortify_test(memmove) 881 + 882 + static void fortify_test_memscan(struct kunit *test) 857 883 { 858 884 char haystack[] = "Where oh where is my memory range?"; 859 885 char *mem = haystack + strlen("Where oh where is "); ··· 940 830 KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 941 831 } 942 832 943 - static void memchr_test(struct kunit *test) 833 + static void fortify_test_memchr(struct kunit *test) 944 834 { 945 835 char haystack[] = "Where oh where is my memory range?"; 946 836 char *mem = haystack + strlen("Where oh where is "); ··· 959 849 KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 960 850 } 961 851 962 - static void memchr_inv_test(struct kunit *test) 852 + static void fortify_test_memchr_inv(struct kunit *test) 963 853 { 964 854 char haystack[] = "Where oh where is my memory range?"; 965 855 char *mem = haystack + 1; ··· 979 869 KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 980 870 } 981 871 982 - static void memcmp_test(struct kunit *test) 872 + static void fortify_test_memcmp(struct kunit *test) 983 873 { 984 874 char one[] = "My mind is going ..."; 985 875 char two[] = "My mind is going ... I can feel it."; ··· 1001 891 KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 1002 892 } 1003 893 1004 - static void kmemdup_test(struct kunit *test) 894 + static void fortify_test_kmemdup(struct kunit *test) 1005 895 { 1006 896 char src[] = "I got Doom running on it!"; 1007 897 char *copy; ··· 1027 917 1028 918 /* Out of bounds by 1 byte. */ 1029 919 copy = kmemdup(src, len + 1, GFP_KERNEL); 1030 - KUNIT_EXPECT_NULL(test, copy); 920 + KUNIT_EXPECT_PTR_EQ(test, copy, ZERO_SIZE_PTR); 1031 921 KUNIT_EXPECT_EQ(test, fortify_read_overflows, 1); 1032 922 kfree(copy); 1033 923 1034 924 /* Way out of bounds. */ 1035 925 copy = kmemdup(src, len * 2, GFP_KERNEL); 1036 - KUNIT_EXPECT_NULL(test, copy); 926 + KUNIT_EXPECT_PTR_EQ(test, copy, ZERO_SIZE_PTR); 1037 927 KUNIT_EXPECT_EQ(test, fortify_read_overflows, 2); 1038 928 kfree(copy); 1039 929 1040 930 /* Starting offset causing out of bounds. */ 1041 931 copy = kmemdup(src + 1, len, GFP_KERNEL); 1042 - KUNIT_EXPECT_NULL(test, copy); 932 + KUNIT_EXPECT_PTR_EQ(test, copy, ZERO_SIZE_PTR); 1043 933 KUNIT_EXPECT_EQ(test, fortify_read_overflows, 3); 1044 934 kfree(copy); 1045 935 } ··· 1061 951 } 1062 952 1063 953 static struct kunit_case fortify_test_cases[] = { 1064 - KUNIT_CASE(known_sizes_test), 1065 - KUNIT_CASE(control_flow_split_test), 1066 - KUNIT_CASE(alloc_size_kmalloc_const_test), 1067 - KUNIT_CASE(alloc_size_kmalloc_dynamic_test), 1068 - KUNIT_CASE(alloc_size_vmalloc_const_test), 1069 - KUNIT_CASE(alloc_size_vmalloc_dynamic_test), 1070 - KUNIT_CASE(alloc_size_kvmalloc_const_test), 1071 - KUNIT_CASE(alloc_size_kvmalloc_dynamic_test), 1072 - KUNIT_CASE(alloc_size_devm_kmalloc_const_test), 1073 - KUNIT_CASE(alloc_size_devm_kmalloc_dynamic_test), 1074 - KUNIT_CASE(strlen_test), 1075 - KUNIT_CASE(strnlen_test), 1076 - KUNIT_CASE(strcpy_test), 1077 - KUNIT_CASE(strncpy_test), 1078 - KUNIT_CASE(strscpy_test), 1079 - KUNIT_CASE(strcat_test), 1080 - KUNIT_CASE(strncat_test), 1081 - KUNIT_CASE(strlcat_test), 954 + KUNIT_CASE(fortify_test_known_sizes), 955 + KUNIT_CASE(fortify_test_control_flow_split), 956 + KUNIT_CASE(fortify_test_alloc_size_kmalloc_const), 957 + KUNIT_CASE(fortify_test_alloc_size_kmalloc_dynamic), 958 + KUNIT_CASE(fortify_test_alloc_size_vmalloc_const), 959 + KUNIT_CASE(fortify_test_alloc_size_vmalloc_dynamic), 960 + KUNIT_CASE(fortify_test_alloc_size_kvmalloc_const), 961 + KUNIT_CASE(fortify_test_alloc_size_kvmalloc_dynamic), 962 + KUNIT_CASE(fortify_test_alloc_size_devm_kmalloc_const), 963 + KUNIT_CASE(fortify_test_alloc_size_devm_kmalloc_dynamic), 964 + KUNIT_CASE(fortify_test_realloc_size), 965 + KUNIT_CASE(fortify_test_strlen), 966 + KUNIT_CASE(fortify_test_strnlen), 967 + KUNIT_CASE(fortify_test_strcpy), 968 + KUNIT_CASE(fortify_test_strncpy), 969 + KUNIT_CASE(fortify_test_strscpy), 970 + KUNIT_CASE(fortify_test_strcat), 971 + KUNIT_CASE(fortify_test_strncat), 972 + KUNIT_CASE(fortify_test_strlcat), 1082 973 /* skip memset: performs bounds checking on whole structs */ 1083 - /* skip memcpy: still using warn-and-overwrite instead of hard-fail */ 1084 - KUNIT_CASE(memscan_test), 1085 - KUNIT_CASE(memchr_test), 1086 - KUNIT_CASE(memchr_inv_test), 1087 - KUNIT_CASE(memcmp_test), 1088 - KUNIT_CASE(kmemdup_test), 974 + KUNIT_CASE(fortify_test_memcpy), 975 + KUNIT_CASE(fortify_test_memmove), 976 + KUNIT_CASE(fortify_test_memscan), 977 + KUNIT_CASE(fortify_test_memchr), 978 + KUNIT_CASE(fortify_test_memchr_inv), 979 + KUNIT_CASE(fortify_test_memcmp), 980 + KUNIT_CASE(fortify_test_kmemdup), 1089 981 {} 1090 982 }; 1091 983
-53
lib/memcpy_kunit.c
··· 493 493 } 494 494 } 495 495 496 - static void strtomem_test(struct kunit *test) 497 - { 498 - static const char input[sizeof(unsigned long)] = "hi"; 499 - static const char truncate[] = "this is too long"; 500 - struct { 501 - unsigned long canary1; 502 - unsigned char output[sizeof(unsigned long)] __nonstring; 503 - unsigned long canary2; 504 - } wrap; 505 - 506 - memset(&wrap, 0xFF, sizeof(wrap)); 507 - KUNIT_EXPECT_EQ_MSG(test, wrap.canary1, ULONG_MAX, 508 - "bad initial canary value"); 509 - KUNIT_EXPECT_EQ_MSG(test, wrap.canary2, ULONG_MAX, 510 - "bad initial canary value"); 511 - 512 - /* Check unpadded copy leaves surroundings untouched. */ 513 - strtomem(wrap.output, input); 514 - KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX); 515 - KUNIT_EXPECT_EQ(test, wrap.output[0], input[0]); 516 - KUNIT_EXPECT_EQ(test, wrap.output[1], input[1]); 517 - for (size_t i = 2; i < sizeof(wrap.output); i++) 518 - KUNIT_EXPECT_EQ(test, wrap.output[i], 0xFF); 519 - KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX); 520 - 521 - /* Check truncated copy leaves surroundings untouched. */ 522 - memset(&wrap, 0xFF, sizeof(wrap)); 523 - strtomem(wrap.output, truncate); 524 - KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX); 525 - for (size_t i = 0; i < sizeof(wrap.output); i++) 526 - KUNIT_EXPECT_EQ(test, wrap.output[i], truncate[i]); 527 - KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX); 528 - 529 - /* Check padded copy leaves only string padded. */ 530 - memset(&wrap, 0xFF, sizeof(wrap)); 531 - strtomem_pad(wrap.output, input, 0xAA); 532 - KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX); 533 - KUNIT_EXPECT_EQ(test, wrap.output[0], input[0]); 534 - KUNIT_EXPECT_EQ(test, wrap.output[1], input[1]); 535 - for (size_t i = 2; i < sizeof(wrap.output); i++) 536 - KUNIT_EXPECT_EQ(test, wrap.output[i], 0xAA); 537 - KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX); 538 - 539 - /* Check truncated padded copy has no padding. */ 540 - memset(&wrap, 0xFF, sizeof(wrap)); 541 - strtomem(wrap.output, truncate); 542 - KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX); 543 - for (size_t i = 0; i < sizeof(wrap.output); i++) 544 - KUNIT_EXPECT_EQ(test, wrap.output[i], truncate[i]); 545 - KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX); 546 - } 547 - 548 496 static struct kunit_case memcpy_test_cases[] = { 549 497 KUNIT_CASE(memset_test), 550 498 KUNIT_CASE(memcpy_test), ··· 500 552 KUNIT_CASE_SLOW(memmove_test), 501 553 KUNIT_CASE_SLOW(memmove_large_test), 502 554 KUNIT_CASE_SLOW(memmove_overlap_test), 503 - KUNIT_CASE(strtomem_test), 504 555 {} 505 556 }; 506 557
-104
lib/strcat_kunit.c
··· 1 - // SPDX-License-Identifier: GPL-2.0 2 - /* 3 - * Kernel module for testing 'strcat' family of functions. 4 - */ 5 - 6 - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 - 8 - #include <kunit/test.h> 9 - #include <linux/string.h> 10 - 11 - static volatile int unconst; 12 - 13 - static void strcat_test(struct kunit *test) 14 - { 15 - char dest[8]; 16 - 17 - /* Destination is terminated. */ 18 - memset(dest, 0, sizeof(dest)); 19 - KUNIT_EXPECT_EQ(test, strlen(dest), 0); 20 - /* Empty copy does nothing. */ 21 - KUNIT_EXPECT_TRUE(test, strcat(dest, "") == dest); 22 - KUNIT_EXPECT_STREQ(test, dest, ""); 23 - /* 4 characters copied in, stops at %NUL. */ 24 - KUNIT_EXPECT_TRUE(test, strcat(dest, "four\000123") == dest); 25 - KUNIT_EXPECT_STREQ(test, dest, "four"); 26 - KUNIT_EXPECT_EQ(test, dest[5], '\0'); 27 - /* 2 more characters copied in okay. */ 28 - KUNIT_EXPECT_TRUE(test, strcat(dest, "AB") == dest); 29 - KUNIT_EXPECT_STREQ(test, dest, "fourAB"); 30 - } 31 - 32 - static void strncat_test(struct kunit *test) 33 - { 34 - char dest[8]; 35 - 36 - /* Destination is terminated. */ 37 - memset(dest, 0, sizeof(dest)); 38 - KUNIT_EXPECT_EQ(test, strlen(dest), 0); 39 - /* Empty copy of size 0 does nothing. */ 40 - KUNIT_EXPECT_TRUE(test, strncat(dest, "", 0 + unconst) == dest); 41 - KUNIT_EXPECT_STREQ(test, dest, ""); 42 - /* Empty copy of size 1 does nothing too. */ 43 - KUNIT_EXPECT_TRUE(test, strncat(dest, "", 1 + unconst) == dest); 44 - KUNIT_EXPECT_STREQ(test, dest, ""); 45 - /* Copy of max 0 characters should do nothing. */ 46 - KUNIT_EXPECT_TRUE(test, strncat(dest, "asdf", 0 + unconst) == dest); 47 - KUNIT_EXPECT_STREQ(test, dest, ""); 48 - 49 - /* 4 characters copied in, even if max is 8. */ 50 - KUNIT_EXPECT_TRUE(test, strncat(dest, "four\000123", 8 + unconst) == dest); 51 - KUNIT_EXPECT_STREQ(test, dest, "four"); 52 - KUNIT_EXPECT_EQ(test, dest[5], '\0'); 53 - KUNIT_EXPECT_EQ(test, dest[6], '\0'); 54 - /* 2 characters copied in okay, 2 ignored. */ 55 - KUNIT_EXPECT_TRUE(test, strncat(dest, "ABCD", 2 + unconst) == dest); 56 - KUNIT_EXPECT_STREQ(test, dest, "fourAB"); 57 - } 58 - 59 - static void strlcat_test(struct kunit *test) 60 - { 61 - char dest[8] = ""; 62 - int len = sizeof(dest) + unconst; 63 - 64 - /* Destination is terminated. */ 65 - KUNIT_EXPECT_EQ(test, strlen(dest), 0); 66 - /* Empty copy is size 0. */ 67 - KUNIT_EXPECT_EQ(test, strlcat(dest, "", len), 0); 68 - KUNIT_EXPECT_STREQ(test, dest, ""); 69 - /* Size 1 should keep buffer terminated, report size of source only. */ 70 - KUNIT_EXPECT_EQ(test, strlcat(dest, "four", 1 + unconst), 4); 71 - KUNIT_EXPECT_STREQ(test, dest, ""); 72 - 73 - /* 4 characters copied in. */ 74 - KUNIT_EXPECT_EQ(test, strlcat(dest, "four", len), 4); 75 - KUNIT_EXPECT_STREQ(test, dest, "four"); 76 - /* 2 characters copied in okay, gets to 6 total. */ 77 - KUNIT_EXPECT_EQ(test, strlcat(dest, "AB", len), 6); 78 - KUNIT_EXPECT_STREQ(test, dest, "fourAB"); 79 - /* 2 characters ignored if max size (7) reached. */ 80 - KUNIT_EXPECT_EQ(test, strlcat(dest, "CD", 7 + unconst), 8); 81 - KUNIT_EXPECT_STREQ(test, dest, "fourAB"); 82 - /* 1 of 2 characters skipped, now at true max size. */ 83 - KUNIT_EXPECT_EQ(test, strlcat(dest, "EFG", len), 9); 84 - KUNIT_EXPECT_STREQ(test, dest, "fourABE"); 85 - /* Everything else ignored, now at full size. */ 86 - KUNIT_EXPECT_EQ(test, strlcat(dest, "1234", len), 11); 87 - KUNIT_EXPECT_STREQ(test, dest, "fourABE"); 88 - } 89 - 90 - static struct kunit_case strcat_test_cases[] = { 91 - KUNIT_CASE(strcat_test), 92 - KUNIT_CASE(strncat_test), 93 - KUNIT_CASE(strlcat_test), 94 - {} 95 - }; 96 - 97 - static struct kunit_suite strcat_test_suite = { 98 - .name = "strcat", 99 - .test_cases = strcat_test_cases, 100 - }; 101 - 102 - kunit_test_suite(strcat_test_suite); 103 - 104 - MODULE_LICENSE("GPL");
+449 -12
lib/string_kunit.c
··· 11 11 #include <linux/slab.h> 12 12 #include <linux/string.h> 13 13 14 - static void test_memset16(struct kunit *test) 14 + #define STRCMP_LARGE_BUF_LEN 2048 15 + #define STRCMP_CHANGE_POINT 1337 16 + #define STRCMP_TEST_EXPECT_EQUAL(test, fn, ...) KUNIT_EXPECT_EQ(test, fn(__VA_ARGS__), 0) 17 + #define STRCMP_TEST_EXPECT_LOWER(test, fn, ...) KUNIT_EXPECT_LT(test, fn(__VA_ARGS__), 0) 18 + #define STRCMP_TEST_EXPECT_GREATER(test, fn, ...) KUNIT_EXPECT_GT(test, fn(__VA_ARGS__), 0) 19 + 20 + static void string_test_memset16(struct kunit *test) 15 21 { 16 22 unsigned i, j, k; 17 23 u16 v, *p; ··· 46 40 } 47 41 } 48 42 49 - static void test_memset32(struct kunit *test) 43 + static void string_test_memset32(struct kunit *test) 50 44 { 51 45 unsigned i, j, k; 52 46 u32 v, *p; ··· 75 69 } 76 70 } 77 71 78 - static void test_memset64(struct kunit *test) 72 + static void string_test_memset64(struct kunit *test) 79 73 { 80 74 unsigned i, j, k; 81 75 u64 v, *p; ··· 104 98 } 105 99 } 106 100 107 - static void test_strchr(struct kunit *test) 101 + static void string_test_strchr(struct kunit *test) 108 102 { 109 103 const char *test_string = "abcdefghijkl"; 110 104 const char *empty_string = ""; ··· 127 121 KUNIT_ASSERT_NULL(test, result); 128 122 } 129 123 130 - static void test_strnchr(struct kunit *test) 124 + static void string_test_strnchr(struct kunit *test) 131 125 { 132 126 const char *test_string = "abcdefghijkl"; 133 127 const char *empty_string = ""; ··· 160 154 KUNIT_ASSERT_NULL(test, result); 161 155 } 162 156 163 - static void test_strspn(struct kunit *test) 157 + static void string_test_strspn(struct kunit *test) 164 158 { 165 159 static const struct strspn_test { 166 160 const char str[16]; ··· 185 179 } 186 180 } 187 181 182 + static char strcmp_buffer1[STRCMP_LARGE_BUF_LEN]; 183 + static char strcmp_buffer2[STRCMP_LARGE_BUF_LEN]; 184 + 185 + static void strcmp_fill_buffers(char fill1, char fill2) 186 + { 187 + memset(strcmp_buffer1, fill1, STRCMP_LARGE_BUF_LEN); 188 + memset(strcmp_buffer2, fill2, STRCMP_LARGE_BUF_LEN); 189 + strcmp_buffer1[STRCMP_LARGE_BUF_LEN - 1] = 0; 190 + strcmp_buffer2[STRCMP_LARGE_BUF_LEN - 1] = 0; 191 + } 192 + 193 + static void string_test_strcmp(struct kunit *test) 194 + { 195 + /* Equal strings */ 196 + STRCMP_TEST_EXPECT_EQUAL(test, strcmp, "Hello, Kernel!", "Hello, Kernel!"); 197 + /* First string is lexicographically less than the second */ 198 + STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Hello, KUnit!", "Hello, Kernel!"); 199 + /* First string is lexicographically larger than the second */ 200 + STRCMP_TEST_EXPECT_GREATER(test, strcmp, "Hello, Kernel!", "Hello, KUnit!"); 201 + /* Empty string is always lexicographically less than any non-empty string */ 202 + STRCMP_TEST_EXPECT_LOWER(test, strcmp, "", "Non-empty string"); 203 + /* Two empty strings should be equal */ 204 + STRCMP_TEST_EXPECT_EQUAL(test, strcmp, "", ""); 205 + /* Compare two strings which have only one char difference */ 206 + STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Abacaba", "Abadaba"); 207 + /* Compare two strings which have the same prefix*/ 208 + STRCMP_TEST_EXPECT_LOWER(test, strcmp, "Just a string", "Just a string and something else"); 209 + } 210 + 211 + static void string_test_strcmp_long_strings(struct kunit *test) 212 + { 213 + strcmp_fill_buffers('B', 'B'); 214 + STRCMP_TEST_EXPECT_EQUAL(test, strcmp, strcmp_buffer1, strcmp_buffer2); 215 + 216 + strcmp_buffer1[STRCMP_CHANGE_POINT] = 'A'; 217 + STRCMP_TEST_EXPECT_LOWER(test, strcmp, strcmp_buffer1, strcmp_buffer2); 218 + 219 + strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C'; 220 + STRCMP_TEST_EXPECT_GREATER(test, strcmp, strcmp_buffer1, strcmp_buffer2); 221 + } 222 + 223 + static void string_test_strncmp(struct kunit *test) 224 + { 225 + /* Equal strings */ 226 + STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Hello, KUnit!", "Hello, KUnit!", 13); 227 + /* First string is lexicographically less than the second */ 228 + STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Hello, KUnit!", "Hello, Kernel!", 13); 229 + /* Result is always 'equal' when count = 0 */ 230 + STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Hello, Kernel!", "Hello, KUnit!", 0); 231 + /* Strings with common prefix are equal if count = length of prefix */ 232 + STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Abacaba", "Abadaba", 3); 233 + /* Strings with common prefix are not equal when count = length of prefix + 1 */ 234 + STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Abacaba", "Abadaba", 4); 235 + /* If one string is a prefix of another, the shorter string is lexicographically smaller */ 236 + STRCMP_TEST_EXPECT_LOWER(test, strncmp, "Just a string", "Just a string and something else", 237 + strlen("Just a string and something else")); 238 + /* 239 + * If one string is a prefix of another, and we check first length 240 + * of prefix chars, the result is 'equal' 241 + */ 242 + STRCMP_TEST_EXPECT_EQUAL(test, strncmp, "Just a string", "Just a string and something else", 243 + strlen("Just a string")); 244 + } 245 + 246 + static void string_test_strncmp_long_strings(struct kunit *test) 247 + { 248 + strcmp_fill_buffers('B', 'B'); 249 + STRCMP_TEST_EXPECT_EQUAL(test, strncmp, strcmp_buffer1, 250 + strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 251 + 252 + strcmp_buffer1[STRCMP_CHANGE_POINT] = 'A'; 253 + STRCMP_TEST_EXPECT_LOWER(test, strncmp, strcmp_buffer1, 254 + strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 255 + 256 + strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C'; 257 + STRCMP_TEST_EXPECT_GREATER(test, strncmp, strcmp_buffer1, 258 + strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 259 + /* the strings are equal up to STRCMP_CHANGE_POINT */ 260 + STRCMP_TEST_EXPECT_EQUAL(test, strncmp, strcmp_buffer1, 261 + strcmp_buffer2, STRCMP_CHANGE_POINT); 262 + STRCMP_TEST_EXPECT_GREATER(test, strncmp, strcmp_buffer1, 263 + strcmp_buffer2, STRCMP_CHANGE_POINT + 1); 264 + } 265 + 266 + static void string_test_strcasecmp(struct kunit *test) 267 + { 268 + /* Same strings in different case should be equal */ 269 + STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "Hello, Kernel!", "HeLLO, KErNeL!"); 270 + /* Empty strings should be equal */ 271 + STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "", ""); 272 + /* Despite ascii code for 'a' is larger than ascii code for 'B', 'a' < 'B' */ 273 + STRCMP_TEST_EXPECT_LOWER(test, strcasecmp, "a", "B"); 274 + STRCMP_TEST_EXPECT_GREATER(test, strcasecmp, "B", "a"); 275 + /* Special symbols and numbers should be processed correctly */ 276 + STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, "-+**.1230ghTTT~^", "-+**.1230Ghttt~^"); 277 + } 278 + 279 + static void string_test_strcasecmp_long_strings(struct kunit *test) 280 + { 281 + strcmp_fill_buffers('b', 'B'); 282 + STRCMP_TEST_EXPECT_EQUAL(test, strcasecmp, strcmp_buffer1, strcmp_buffer2); 283 + 284 + strcmp_buffer1[STRCMP_CHANGE_POINT] = 'a'; 285 + STRCMP_TEST_EXPECT_LOWER(test, strcasecmp, strcmp_buffer1, strcmp_buffer2); 286 + 287 + strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C'; 288 + STRCMP_TEST_EXPECT_GREATER(test, strcasecmp, strcmp_buffer1, strcmp_buffer2); 289 + } 290 + 291 + static void string_test_strncasecmp(struct kunit *test) 292 + { 293 + /* Same strings in different case should be equal */ 294 + STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "AbAcAbA", "Abacaba", strlen("Abacaba")); 295 + /* strncasecmp should check 'count' chars only */ 296 + STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "AbaCaBa", "abaCaDa", 5); 297 + STRCMP_TEST_EXPECT_LOWER(test, strncasecmp, "a", "B", 1); 298 + STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, "B", "a", 1); 299 + /* Result is always 'equal' when count = 0 */ 300 + STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, "Abacaba", "Not abacaba", 0); 301 + } 302 + 303 + static void string_test_strncasecmp_long_strings(struct kunit *test) 304 + { 305 + strcmp_fill_buffers('b', 'B'); 306 + STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, strcmp_buffer1, 307 + strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 308 + 309 + strcmp_buffer1[STRCMP_CHANGE_POINT] = 'a'; 310 + STRCMP_TEST_EXPECT_LOWER(test, strncasecmp, strcmp_buffer1, 311 + strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 312 + 313 + strcmp_buffer1[STRCMP_CHANGE_POINT] = 'C'; 314 + STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, strcmp_buffer1, 315 + strcmp_buffer2, STRCMP_LARGE_BUF_LEN); 316 + 317 + STRCMP_TEST_EXPECT_EQUAL(test, strncasecmp, strcmp_buffer1, 318 + strcmp_buffer2, STRCMP_CHANGE_POINT); 319 + STRCMP_TEST_EXPECT_GREATER(test, strncasecmp, strcmp_buffer1, 320 + strcmp_buffer2, STRCMP_CHANGE_POINT + 1); 321 + } 322 + 323 + /** 324 + * strscpy_check() - Run a specific test case. 325 + * @test: KUnit test context pointer 326 + * @src: Source string, argument to strscpy_pad() 327 + * @count: Size of destination buffer, argument to strscpy_pad() 328 + * @expected: Expected return value from call to strscpy_pad() 329 + * @chars: Number of characters from the src string expected to be 330 + * written to the dst buffer. 331 + * @terminator: 1 if there should be a terminating null byte 0 otherwise. 332 + * @pad: Number of pad characters expected (in the tail of dst buffer). 333 + * (@pad does not include the null terminator byte.) 334 + * 335 + * Calls strscpy_pad() and verifies the return value and state of the 336 + * destination buffer after the call returns. 337 + */ 338 + static void strscpy_check(struct kunit *test, char *src, int count, 339 + int expected, int chars, int terminator, int pad) 340 + { 341 + int nr_bytes_poison; 342 + int max_expected; 343 + int max_count; 344 + int written; 345 + char buf[6]; 346 + int index, i; 347 + const char POISON = 'z'; 348 + 349 + KUNIT_ASSERT_TRUE_MSG(test, src != NULL, 350 + "null source string not supported"); 351 + 352 + memset(buf, POISON, sizeof(buf)); 353 + /* Future proofing test suite, validate args */ 354 + max_count = sizeof(buf) - 2; /* Space for null and to verify overflow */ 355 + max_expected = count - 1; /* Space for the null */ 356 + 357 + KUNIT_ASSERT_LE_MSG(test, count, max_count, 358 + "count (%d) is too big (%d) ... aborting", count, max_count); 359 + KUNIT_EXPECT_LE_MSG(test, expected, max_expected, 360 + "expected (%d) is bigger than can possibly be returned (%d)", 361 + expected, max_expected); 362 + 363 + written = strscpy_pad(buf, src, count); 364 + KUNIT_ASSERT_EQ(test, written, expected); 365 + 366 + if (count && written == -E2BIG) { 367 + KUNIT_ASSERT_EQ_MSG(test, 0, strncmp(buf, src, count - 1), 368 + "buffer state invalid for -E2BIG"); 369 + KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0', 370 + "too big string is not null terminated correctly"); 371 + } 372 + 373 + for (i = 0; i < chars; i++) 374 + KUNIT_ASSERT_EQ_MSG(test, buf[i], src[i], 375 + "buf[i]==%c != src[i]==%c", buf[i], src[i]); 376 + 377 + if (terminator) 378 + KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0', 379 + "string is not null terminated correctly"); 380 + 381 + for (i = 0; i < pad; i++) { 382 + index = chars + terminator + i; 383 + KUNIT_ASSERT_EQ_MSG(test, buf[index], '\0', 384 + "padding missing at index: %d", i); 385 + } 386 + 387 + nr_bytes_poison = sizeof(buf) - chars - terminator - pad; 388 + for (i = 0; i < nr_bytes_poison; i++) { 389 + index = sizeof(buf) - 1 - i; /* Check from the end back */ 390 + KUNIT_ASSERT_EQ_MSG(test, buf[index], POISON, 391 + "poison value missing at index: %d", i); 392 + } 393 + } 394 + 395 + static void string_test_strscpy(struct kunit *test) 396 + { 397 + char dest[8]; 398 + 399 + /* 400 + * strscpy_check() uses a destination buffer of size 6 and needs at 401 + * least 2 characters spare (one for null and one to check for 402 + * overflow). This means we should only call tc() with 403 + * strings up to a maximum of 4 characters long and 'count' 404 + * should not exceed 4. To test with longer strings increase 405 + * the buffer size in tc(). 406 + */ 407 + 408 + /* strscpy_check(test, src, count, expected, chars, terminator, pad) */ 409 + strscpy_check(test, "a", 0, -E2BIG, 0, 0, 0); 410 + strscpy_check(test, "", 0, -E2BIG, 0, 0, 0); 411 + 412 + strscpy_check(test, "a", 1, -E2BIG, 0, 1, 0); 413 + strscpy_check(test, "", 1, 0, 0, 1, 0); 414 + 415 + strscpy_check(test, "ab", 2, -E2BIG, 1, 1, 0); 416 + strscpy_check(test, "a", 2, 1, 1, 1, 0); 417 + strscpy_check(test, "", 2, 0, 0, 1, 1); 418 + 419 + strscpy_check(test, "abc", 3, -E2BIG, 2, 1, 0); 420 + strscpy_check(test, "ab", 3, 2, 2, 1, 0); 421 + strscpy_check(test, "a", 3, 1, 1, 1, 1); 422 + strscpy_check(test, "", 3, 0, 0, 1, 2); 423 + 424 + strscpy_check(test, "abcd", 4, -E2BIG, 3, 1, 0); 425 + strscpy_check(test, "abc", 4, 3, 3, 1, 0); 426 + strscpy_check(test, "ab", 4, 2, 2, 1, 1); 427 + strscpy_check(test, "a", 4, 1, 1, 1, 2); 428 + strscpy_check(test, "", 4, 0, 0, 1, 3); 429 + 430 + /* Compile-time-known source strings. */ 431 + KUNIT_EXPECT_EQ(test, strscpy(dest, "", ARRAY_SIZE(dest)), 0); 432 + KUNIT_EXPECT_EQ(test, strscpy(dest, "", 3), 0); 433 + KUNIT_EXPECT_EQ(test, strscpy(dest, "", 1), 0); 434 + KUNIT_EXPECT_EQ(test, strscpy(dest, "", 0), -E2BIG); 435 + KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", ARRAY_SIZE(dest)), 5); 436 + KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 3), -E2BIG); 437 + KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 1), -E2BIG); 438 + KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 0), -E2BIG); 439 + KUNIT_EXPECT_EQ(test, strscpy(dest, "This is too long", ARRAY_SIZE(dest)), -E2BIG); 440 + } 441 + 442 + static volatile int unconst; 443 + 444 + static void string_test_strcat(struct kunit *test) 445 + { 446 + char dest[8]; 447 + 448 + /* Destination is terminated. */ 449 + memset(dest, 0, sizeof(dest)); 450 + KUNIT_EXPECT_EQ(test, strlen(dest), 0); 451 + /* Empty copy does nothing. */ 452 + KUNIT_EXPECT_TRUE(test, strcat(dest, "") == dest); 453 + KUNIT_EXPECT_STREQ(test, dest, ""); 454 + /* 4 characters copied in, stops at %NUL. */ 455 + KUNIT_EXPECT_TRUE(test, strcat(dest, "four\000123") == dest); 456 + KUNIT_EXPECT_STREQ(test, dest, "four"); 457 + KUNIT_EXPECT_EQ(test, dest[5], '\0'); 458 + /* 2 more characters copied in okay. */ 459 + KUNIT_EXPECT_TRUE(test, strcat(dest, "AB") == dest); 460 + KUNIT_EXPECT_STREQ(test, dest, "fourAB"); 461 + } 462 + 463 + static void string_test_strncat(struct kunit *test) 464 + { 465 + char dest[8]; 466 + 467 + /* Destination is terminated. */ 468 + memset(dest, 0, sizeof(dest)); 469 + KUNIT_EXPECT_EQ(test, strlen(dest), 0); 470 + /* Empty copy of size 0 does nothing. */ 471 + KUNIT_EXPECT_TRUE(test, strncat(dest, "", 0 + unconst) == dest); 472 + KUNIT_EXPECT_STREQ(test, dest, ""); 473 + /* Empty copy of size 1 does nothing too. */ 474 + KUNIT_EXPECT_TRUE(test, strncat(dest, "", 1 + unconst) == dest); 475 + KUNIT_EXPECT_STREQ(test, dest, ""); 476 + /* Copy of max 0 characters should do nothing. */ 477 + KUNIT_EXPECT_TRUE(test, strncat(dest, "asdf", 0 + unconst) == dest); 478 + KUNIT_EXPECT_STREQ(test, dest, ""); 479 + 480 + /* 4 characters copied in, even if max is 8. */ 481 + KUNIT_EXPECT_TRUE(test, strncat(dest, "four\000123", 8 + unconst) == dest); 482 + KUNIT_EXPECT_STREQ(test, dest, "four"); 483 + KUNIT_EXPECT_EQ(test, dest[5], '\0'); 484 + KUNIT_EXPECT_EQ(test, dest[6], '\0'); 485 + /* 2 characters copied in okay, 2 ignored. */ 486 + KUNIT_EXPECT_TRUE(test, strncat(dest, "ABCD", 2 + unconst) == dest); 487 + KUNIT_EXPECT_STREQ(test, dest, "fourAB"); 488 + } 489 + 490 + static void string_test_strlcat(struct kunit *test) 491 + { 492 + char dest[8] = ""; 493 + int len = sizeof(dest) + unconst; 494 + 495 + /* Destination is terminated. */ 496 + KUNIT_EXPECT_EQ(test, strlen(dest), 0); 497 + /* Empty copy is size 0. */ 498 + KUNIT_EXPECT_EQ(test, strlcat(dest, "", len), 0); 499 + KUNIT_EXPECT_STREQ(test, dest, ""); 500 + /* Size 1 should keep buffer terminated, report size of source only. */ 501 + KUNIT_EXPECT_EQ(test, strlcat(dest, "four", 1 + unconst), 4); 502 + KUNIT_EXPECT_STREQ(test, dest, ""); 503 + 504 + /* 4 characters copied in. */ 505 + KUNIT_EXPECT_EQ(test, strlcat(dest, "four", len), 4); 506 + KUNIT_EXPECT_STREQ(test, dest, "four"); 507 + /* 2 characters copied in okay, gets to 6 total. */ 508 + KUNIT_EXPECT_EQ(test, strlcat(dest, "AB", len), 6); 509 + KUNIT_EXPECT_STREQ(test, dest, "fourAB"); 510 + /* 2 characters ignored if max size (7) reached. */ 511 + KUNIT_EXPECT_EQ(test, strlcat(dest, "CD", 7 + unconst), 8); 512 + KUNIT_EXPECT_STREQ(test, dest, "fourAB"); 513 + /* 1 of 2 characters skipped, now at true max size. */ 514 + KUNIT_EXPECT_EQ(test, strlcat(dest, "EFG", len), 9); 515 + KUNIT_EXPECT_STREQ(test, dest, "fourABE"); 516 + /* Everything else ignored, now at full size. */ 517 + KUNIT_EXPECT_EQ(test, strlcat(dest, "1234", len), 11); 518 + KUNIT_EXPECT_STREQ(test, dest, "fourABE"); 519 + } 520 + 521 + static void string_test_strtomem(struct kunit *test) 522 + { 523 + static const char input[sizeof(unsigned long)] = "hi"; 524 + static const char truncate[] = "this is too long"; 525 + struct { 526 + unsigned long canary1; 527 + unsigned char output[sizeof(unsigned long)] __nonstring; 528 + unsigned long canary2; 529 + } wrap; 530 + 531 + memset(&wrap, 0xFF, sizeof(wrap)); 532 + KUNIT_EXPECT_EQ_MSG(test, wrap.canary1, ULONG_MAX, 533 + "bad initial canary value"); 534 + KUNIT_EXPECT_EQ_MSG(test, wrap.canary2, ULONG_MAX, 535 + "bad initial canary value"); 536 + 537 + /* Check unpadded copy leaves surroundings untouched. */ 538 + strtomem(wrap.output, input); 539 + KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX); 540 + KUNIT_EXPECT_EQ(test, wrap.output[0], input[0]); 541 + KUNIT_EXPECT_EQ(test, wrap.output[1], input[1]); 542 + for (size_t i = 2; i < sizeof(wrap.output); i++) 543 + KUNIT_EXPECT_EQ(test, wrap.output[i], 0xFF); 544 + KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX); 545 + 546 + /* Check truncated copy leaves surroundings untouched. */ 547 + memset(&wrap, 0xFF, sizeof(wrap)); 548 + strtomem(wrap.output, truncate); 549 + KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX); 550 + for (size_t i = 0; i < sizeof(wrap.output); i++) 551 + KUNIT_EXPECT_EQ(test, wrap.output[i], truncate[i]); 552 + KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX); 553 + 554 + /* Check padded copy leaves only string padded. */ 555 + memset(&wrap, 0xFF, sizeof(wrap)); 556 + strtomem_pad(wrap.output, input, 0xAA); 557 + KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX); 558 + KUNIT_EXPECT_EQ(test, wrap.output[0], input[0]); 559 + KUNIT_EXPECT_EQ(test, wrap.output[1], input[1]); 560 + for (size_t i = 2; i < sizeof(wrap.output); i++) 561 + KUNIT_EXPECT_EQ(test, wrap.output[i], 0xAA); 562 + KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX); 563 + 564 + /* Check truncated padded copy has no padding. */ 565 + memset(&wrap, 0xFF, sizeof(wrap)); 566 + strtomem(wrap.output, truncate); 567 + KUNIT_EXPECT_EQ(test, wrap.canary1, ULONG_MAX); 568 + for (size_t i = 0; i < sizeof(wrap.output); i++) 569 + KUNIT_EXPECT_EQ(test, wrap.output[i], truncate[i]); 570 + KUNIT_EXPECT_EQ(test, wrap.canary2, ULONG_MAX); 571 + } 572 + 573 + 574 + static void string_test_memtostr(struct kunit *test) 575 + { 576 + char nonstring[7] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g' }; 577 + char nonstring_small[3] = { 'a', 'b', 'c' }; 578 + char dest[sizeof(nonstring) + 1]; 579 + 580 + /* Copy in a non-NUL-terminated string into exactly right-sized dest. */ 581 + KUNIT_EXPECT_EQ(test, sizeof(dest), sizeof(nonstring) + 1); 582 + memset(dest, 'X', sizeof(dest)); 583 + memtostr(dest, nonstring); 584 + KUNIT_EXPECT_STREQ(test, dest, "abcdefg"); 585 + memset(dest, 'X', sizeof(dest)); 586 + memtostr(dest, nonstring_small); 587 + KUNIT_EXPECT_STREQ(test, dest, "abc"); 588 + KUNIT_EXPECT_EQ(test, dest[7], 'X'); 589 + 590 + memset(dest, 'X', sizeof(dest)); 591 + memtostr_pad(dest, nonstring); 592 + KUNIT_EXPECT_STREQ(test, dest, "abcdefg"); 593 + memset(dest, 'X', sizeof(dest)); 594 + memtostr_pad(dest, nonstring_small); 595 + KUNIT_EXPECT_STREQ(test, dest, "abc"); 596 + KUNIT_EXPECT_EQ(test, dest[7], '\0'); 597 + } 598 + 188 599 static struct kunit_case string_test_cases[] = { 189 - KUNIT_CASE(test_memset16), 190 - KUNIT_CASE(test_memset32), 191 - KUNIT_CASE(test_memset64), 192 - KUNIT_CASE(test_strchr), 193 - KUNIT_CASE(test_strnchr), 194 - KUNIT_CASE(test_strspn), 600 + KUNIT_CASE(string_test_memset16), 601 + KUNIT_CASE(string_test_memset32), 602 + KUNIT_CASE(string_test_memset64), 603 + KUNIT_CASE(string_test_strchr), 604 + KUNIT_CASE(string_test_strnchr), 605 + KUNIT_CASE(string_test_strspn), 606 + KUNIT_CASE(string_test_strcmp), 607 + KUNIT_CASE(string_test_strcmp_long_strings), 608 + KUNIT_CASE(string_test_strncmp), 609 + KUNIT_CASE(string_test_strncmp_long_strings), 610 + KUNIT_CASE(string_test_strcasecmp), 611 + KUNIT_CASE(string_test_strcasecmp_long_strings), 612 + KUNIT_CASE(string_test_strncasecmp), 613 + KUNIT_CASE(string_test_strncasecmp_long_strings), 614 + KUNIT_CASE(string_test_strscpy), 615 + KUNIT_CASE(string_test_strcat), 616 + KUNIT_CASE(string_test_strncat), 617 + KUNIT_CASE(string_test_strlcat), 618 + KUNIT_CASE(string_test_strtomem), 619 + KUNIT_CASE(string_test_memtostr), 195 620 {} 196 621 }; 197 622
-142
lib/strscpy_kunit.c
··· 1 - // SPDX-License-Identifier: GPL-2.0+ 2 - /* 3 - * Kernel module for testing 'strscpy' family of functions. 4 - */ 5 - 6 - #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 7 - 8 - #include <kunit/test.h> 9 - #include <linux/string.h> 10 - 11 - /* 12 - * tc() - Run a specific test case. 13 - * @src: Source string, argument to strscpy_pad() 14 - * @count: Size of destination buffer, argument to strscpy_pad() 15 - * @expected: Expected return value from call to strscpy_pad() 16 - * @terminator: 1 if there should be a terminating null byte 0 otherwise. 17 - * @chars: Number of characters from the src string expected to be 18 - * written to the dst buffer. 19 - * @pad: Number of pad characters expected (in the tail of dst buffer). 20 - * (@pad does not include the null terminator byte.) 21 - * 22 - * Calls strscpy_pad() and verifies the return value and state of the 23 - * destination buffer after the call returns. 24 - */ 25 - static void tc(struct kunit *test, char *src, int count, int expected, 26 - int chars, int terminator, int pad) 27 - { 28 - int nr_bytes_poison; 29 - int max_expected; 30 - int max_count; 31 - int written; 32 - char buf[6]; 33 - int index, i; 34 - const char POISON = 'z'; 35 - 36 - KUNIT_ASSERT_TRUE_MSG(test, src != NULL, 37 - "null source string not supported"); 38 - 39 - memset(buf, POISON, sizeof(buf)); 40 - /* Future proofing test suite, validate args */ 41 - max_count = sizeof(buf) - 2; /* Space for null and to verify overflow */ 42 - max_expected = count - 1; /* Space for the null */ 43 - 44 - KUNIT_ASSERT_LE_MSG(test, count, max_count, 45 - "count (%d) is too big (%d) ... aborting", count, max_count); 46 - KUNIT_EXPECT_LE_MSG(test, expected, max_expected, 47 - "expected (%d) is bigger than can possibly be returned (%d)", 48 - expected, max_expected); 49 - 50 - written = strscpy_pad(buf, src, count); 51 - KUNIT_ASSERT_EQ(test, written, expected); 52 - 53 - if (count && written == -E2BIG) { 54 - KUNIT_ASSERT_EQ_MSG(test, 0, strncmp(buf, src, count - 1), 55 - "buffer state invalid for -E2BIG"); 56 - KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0', 57 - "too big string is not null terminated correctly"); 58 - } 59 - 60 - for (i = 0; i < chars; i++) 61 - KUNIT_ASSERT_EQ_MSG(test, buf[i], src[i], 62 - "buf[i]==%c != src[i]==%c", buf[i], src[i]); 63 - 64 - if (terminator) 65 - KUNIT_ASSERT_EQ_MSG(test, buf[count - 1], '\0', 66 - "string is not null terminated correctly"); 67 - 68 - for (i = 0; i < pad; i++) { 69 - index = chars + terminator + i; 70 - KUNIT_ASSERT_EQ_MSG(test, buf[index], '\0', 71 - "padding missing at index: %d", i); 72 - } 73 - 74 - nr_bytes_poison = sizeof(buf) - chars - terminator - pad; 75 - for (i = 0; i < nr_bytes_poison; i++) { 76 - index = sizeof(buf) - 1 - i; /* Check from the end back */ 77 - KUNIT_ASSERT_EQ_MSG(test, buf[index], POISON, 78 - "poison value missing at index: %d", i); 79 - } 80 - } 81 - 82 - static void strscpy_test(struct kunit *test) 83 - { 84 - char dest[8]; 85 - 86 - /* 87 - * tc() uses a destination buffer of size 6 and needs at 88 - * least 2 characters spare (one for null and one to check for 89 - * overflow). This means we should only call tc() with 90 - * strings up to a maximum of 4 characters long and 'count' 91 - * should not exceed 4. To test with longer strings increase 92 - * the buffer size in tc(). 93 - */ 94 - 95 - /* tc(test, src, count, expected, chars, terminator, pad) */ 96 - tc(test, "a", 0, -E2BIG, 0, 0, 0); 97 - tc(test, "", 0, -E2BIG, 0, 0, 0); 98 - 99 - tc(test, "a", 1, -E2BIG, 0, 1, 0); 100 - tc(test, "", 1, 0, 0, 1, 0); 101 - 102 - tc(test, "ab", 2, -E2BIG, 1, 1, 0); 103 - tc(test, "a", 2, 1, 1, 1, 0); 104 - tc(test, "", 2, 0, 0, 1, 1); 105 - 106 - tc(test, "abc", 3, -E2BIG, 2, 1, 0); 107 - tc(test, "ab", 3, 2, 2, 1, 0); 108 - tc(test, "a", 3, 1, 1, 1, 1); 109 - tc(test, "", 3, 0, 0, 1, 2); 110 - 111 - tc(test, "abcd", 4, -E2BIG, 3, 1, 0); 112 - tc(test, "abc", 4, 3, 3, 1, 0); 113 - tc(test, "ab", 4, 2, 2, 1, 1); 114 - tc(test, "a", 4, 1, 1, 1, 2); 115 - tc(test, "", 4, 0, 0, 1, 3); 116 - 117 - /* Compile-time-known source strings. */ 118 - KUNIT_EXPECT_EQ(test, strscpy(dest, "", ARRAY_SIZE(dest)), 0); 119 - KUNIT_EXPECT_EQ(test, strscpy(dest, "", 3), 0); 120 - KUNIT_EXPECT_EQ(test, strscpy(dest, "", 1), 0); 121 - KUNIT_EXPECT_EQ(test, strscpy(dest, "", 0), -E2BIG); 122 - KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", ARRAY_SIZE(dest)), 5); 123 - KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 3), -E2BIG); 124 - KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 1), -E2BIG); 125 - KUNIT_EXPECT_EQ(test, strscpy(dest, "Fixed", 0), -E2BIG); 126 - KUNIT_EXPECT_EQ(test, strscpy(dest, "This is too long", ARRAY_SIZE(dest)), -E2BIG); 127 - } 128 - 129 - static struct kunit_case strscpy_test_cases[] = { 130 - KUNIT_CASE(strscpy_test), 131 - {} 132 - }; 133 - 134 - static struct kunit_suite strscpy_test_suite = { 135 - .name = "strscpy", 136 - .test_cases = strscpy_test_cases, 137 - }; 138 - 139 - kunit_test_suite(strscpy_test_suite); 140 - 141 - MODULE_AUTHOR("Tobin C. Harding <tobin@kernel.org>"); 142 - MODULE_LICENSE("GPL");
+28 -15
lib/ubsan.h
··· 43 43 struct type_descriptor { 44 44 u16 type_kind; 45 45 u16 type_info; 46 - char type_name[1]; 46 + char type_name[]; 47 47 }; 48 48 49 49 struct source_location { ··· 124 124 typedef u64 u_max; 125 125 #endif 126 126 127 - void __ubsan_handle_add_overflow(void *data, void *lhs, void *rhs); 128 - void __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs); 129 - void __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs); 130 - void __ubsan_handle_negate_overflow(void *_data, void *old_val); 131 - void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs); 132 - void __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr); 133 - void __ubsan_handle_type_mismatch_v1(void *_data, void *ptr); 134 - void __ubsan_handle_out_of_bounds(void *_data, void *index); 135 - void __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs); 136 - void __ubsan_handle_builtin_unreachable(void *_data); 137 - void __ubsan_handle_load_invalid_value(void *_data, void *val); 138 - void __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr, 139 - unsigned long align, 140 - unsigned long offset); 127 + /* 128 + * When generating Runtime Calls, Clang doesn't respect the -mregparm=3 129 + * option used on i386: https://github.com/llvm/llvm-project/issues/89670 130 + * Fix this for earlier Clang versions by forcing the calling convention 131 + * to use non-register arguments. 132 + */ 133 + #if defined(CONFIG_X86_32) && \ 134 + defined(CONFIG_CC_IS_CLANG) && CONFIG_CLANG_VERSION < 190000 135 + # define ubsan_linkage asmlinkage 136 + #else 137 + # define ubsan_linkage 138 + #endif 139 + 140 + void ubsan_linkage __ubsan_handle_add_overflow(void *data, void *lhs, void *rhs); 141 + void ubsan_linkage __ubsan_handle_sub_overflow(void *data, void *lhs, void *rhs); 142 + void ubsan_linkage __ubsan_handle_mul_overflow(void *data, void *lhs, void *rhs); 143 + void ubsan_linkage __ubsan_handle_negate_overflow(void *_data, void *old_val); 144 + void ubsan_linkage __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs); 145 + void ubsan_linkage __ubsan_handle_type_mismatch(struct type_mismatch_data *data, void *ptr); 146 + void ubsan_linkage __ubsan_handle_type_mismatch_v1(void *_data, void *ptr); 147 + void ubsan_linkage __ubsan_handle_out_of_bounds(void *_data, void *index); 148 + void ubsan_linkage __ubsan_handle_shift_out_of_bounds(void *_data, void *lhs, void *rhs); 149 + void ubsan_linkage __ubsan_handle_builtin_unreachable(void *_data); 150 + void ubsan_linkage __ubsan_handle_load_invalid_value(void *_data, void *val); 151 + void ubsan_linkage __ubsan_handle_alignment_assumption(void *_data, unsigned long ptr, 152 + unsigned long align, 153 + unsigned long offset); 141 154 142 155 #endif