History

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

Pull kernel hardening updates from Kees Cook: - Convert flexible array members, fix -Wstringop-overflow warnings, and fix KCFI function type mismatches that went ignored by maintainers (Gustavo A. R. Silva, Nathan Chancellor, Kees Cook) - Remove the remaining side-effect users of ksize() by converting dma-buf, btrfs, and coredump to using kmalloc_size_roundup(), add more __alloc_size attributes, and introduce full testing of all allocator functions. Finally remove the ksize() side-effect so that each allocation-aware checker can finally behave without exceptions - Introduce oops_limit (default 10,000) and warn_limit (default off) to provide greater granularity of control for panic_on_oops and panic_on_warn (Jann Horn, Kees Cook) - Introduce overflows_type() and castable_to_type() helpers for cleaner overflow checking - Improve code generation for strscpy() and update str*() kern-doc - Convert strscpy and sigphash tests to KUnit, and expand memcpy tests - Always use a non-NULL argument for prepare_kernel_cred() - Disable structleak plugin in FORTIFY KUnit test (Anders Roxell) - Adjust orphan linker section checking to respect CONFIG_WERROR (Xin Li) - Make sure siginfo is cleared for forced SIGKILL (haifeng.xu) - Fix um vs FORTIFY warnings for always-NULL arguments * tag 'hardening-v6.2-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: (31 commits) ksmbd: replace one-element arrays with flexible-array members hpet: Replace one-element array with flexible-array member um: virt-pci: Avoid GCC non-NULL warning signal: Initialize the info in ksignal lib: fortify_kunit: build without structleak plugin panic: Expose "warn_count" to sysfs panic: Introduce warn_limit panic: Consolidate open-coded panic_on_warn checks exit: Allow oops_limit to be disabled exit: Expose "oops_count" to sysfs exit: Put an upper limit on how often we can oops panic: Separate sysctl logic from CONFIG_SMP mm/pgtable: Fix multiple -Wstringop-overflow warnings mm: Make ksize() a reporting-only function kunit/fortify: Validate __alloc_size attribute results drm/sti: Fix return type of sti_{dvo,hda,hdmi}_connector_mode_valid() drm/fsl-dcu: Fix return type of fsl_dcu_drm_connector_mode_valid() driver core: Add __alloc_size hint to devm allocators overflow: Introduce overflows_type() and castable_to_type() coredump: Proactively round up to kmalloc bucket size ...

Linus Torvalds committed 3 years ago

Commit 48ea09c2 parents ad76bf1 d272e0161 files · +1533 −463Browse files

Unified · Split

61 files
  1. Documentation/ABI/testing/sysfs-kernel-oops_count +6 −0
  2. Documentation/ABI/testing/sysfs-kernel-warn_count +6 −0
  3. Documentation/admin-guide/sysctl/kernel.rst +19 −0
  4. Documentation/core-api/kernel-api.rst +3 −0
  5. MAINTAINERS +5 −1
  6. Makefile +1 −1
  7. arch/arm/boot/compressed/Makefile +1 −1
  8. arch/arm64/kernel/vdso/Makefile +1 −1
  9. arch/arm64/kernel/vdso32/Makefile +1 −1
  10. arch/um/drivers/virt-pci.c +6 −3
  11. arch/x86/boot/compressed/Makefile +1 −1
  12. arch/x86/mm/pgtable.c +13 −9
  13. drivers/base/firmware_loader/main.c +1 −1
  14. drivers/dma-buf/dma-resv.c +7 −2
  15. drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c +3 −2
  16. drivers/gpu/drm/i915/i915_user_extensions.c +1 −1
  17. drivers/gpu/drm/i915/i915_utils.h +0 −4
  18. drivers/gpu/drm/sti/sti_dvo.c +3 −2
  19. drivers/gpu/drm/sti/sti_hda.c +3 −2
  20. drivers/gpu/drm/sti/sti_hdmi.c +3 −2
  21. fs/btrfs/send.c +6 −5
  22. fs/cifs/cifs_spnego.c +1 −1
  23. fs/cifs/cifsacl.c +1 −1
  24. fs/coredump.c +5 −2
  25. fs/ksmbd/smb2pdu.c +2 −2
  26. fs/ksmbd/smb2pdu.h +1 −1
  27. fs/ksmbd/smb_common.c +1 −1
  28. fs/ksmbd/smb_common.h +6 −6
  29. fs/nfs/flexfilelayout/flexfilelayout.c +2 −2
  30. fs/nfs/nfs4idmap.c +1 −1
  31. fs/nfsd/nfs4callback.c +1 −1
  32. include/linux/compiler.h +1 −0
  33. include/linux/device.h +4 −3
  34. include/linux/fortify-string.h +136 −12
  35. include/linux/hpet.h +1 −1
  36. include/linux/overflow.h +47 −0
  37. include/linux/panic.h +1 −0
  38. include/linux/string.h +1 −1
  39. init/Kconfig +12 −3
  40. kernel/cred.c +7 −8
  41. kernel/exit.c +60 −0
  42. kernel/kcsan/report.c +1 −2
  43. kernel/panic.c +42 −3
  44. kernel/sched/core.c +1 −2
  45. kernel/signal.c +1 −0
  46. lib/Kconfig.debug +16 −12
  47. lib/Makefile +5 −2
  48. lib/fortify_kunit.c +255 −0
  49. lib/memcpy_kunit.c +205 −0
  50. lib/overflow_kunit.c +381 −0
  51. lib/siphash_kunit.c +70 −95
  52. lib/string.c +0 −82
  53. lib/strscpy_kunit.c +142 −0
  54. lib/test_strscpy.c +0 −150
  55. lib/ubsan.c +1 −2
  56. mm/kasan/kasan_test.c +13 −6
  57. mm/kasan/report.c +2 −2
  58. mm/kfence/report.c +1 −2
  59. mm/slab_common.c +10 −16
  60. net/dns_resolver/dns_key.c +1 −1
  61. scripts/kernel-doc +5 −1
Documentation/ABI/testing/sysfs-kernel-oops_count+6−0
@@ -0,0 +1,6 @@
1What: /sys/kernel/oops_count
2Date: November 2022
3KernelVersion: 6.2.0
4Contact: Linux Kernel Hardening List <linux-hardening@vger.kernel.org>
5Description:
6 Shows how many times the system has Oopsed since last boot.
Documentation/ABI/testing/sysfs-kernel-warn_count+6−0
@@ -0,0 +1,6 @@
1What: /sys/kernel/oops_count
2Date: November 2022
3KernelVersion: 6.2.0
4Contact: Linux Kernel Hardening List <linux-hardening@vger.kernel.org>
5Description:
6 Shows how many times the system has Warned since last boot.
Documentation/admin-guide/sysctl/kernel.rst+19−0
@@ -670,6 +670,15 @@ This is the default behavior. · 669 unmodified lines
670an oops event is detected.670an oops event is detected.
671 671
672 672
673oops_limit
674==========
675
676Number of kernel oopses after which the kernel should panic when
677``panic_on_oops`` is not set. Setting this to 0 disables checking
678the count. Setting this to 1 has the same effect as setting
679``panic_on_oops=1``. The default value is 10000.
680
681
673osrelease, ostype & version682osrelease, ostype & version
674===========================683===========================
675 684
@@ -1526,6 +1535,16 @@ entry will default to 2 instead of 0. · 850 unmodified lines
15262 Unprivileged calls to ``bpf()`` are disabled15352 Unprivileged calls to ``bpf()`` are disabled
1527= =============================================================1536= =============================================================
1528 1537
1538
1539warn_limit
1540==========
1541
1542Number of kernel warnings after which the kernel should panic when
1543``panic_on_warn`` is not set. Setting this to 0 disables checking
1544the warning count. Setting this to 1 has the same effect as setting
1545``panic_on_warn=1``. The default value is 0.
1546
1547
1529watchdog1548watchdog
1530========1549========
1531 1550
Documentation/core-api/kernel-api.rst+3−0
@@ -36,6 +36,9 @@ String Conversions · 35 unmodified lines
36String Manipulation36String Manipulation
37-------------------37-------------------
38 38
39.. kernel-doc:: include/linux/fortify-string.h
40 :internal:
41
39.. kernel-doc:: lib/string.c42.. kernel-doc:: lib/string.c
40 :export:43 :export:
41 44
MAINTAINERS+5−1
@@ -8105,6 +8105,8 @@ S: Supported · 8104 unmodified lines
8105T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening8105T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
8106F: include/linux/fortify-string.h8106F: include/linux/fortify-string.h
8107F: lib/fortify_kunit.c8107F: lib/fortify_kunit.c
8108F: lib/memcpy_kunit.c
8109F: lib/strscpy_kunit.c
8108F: lib/test_fortify/*8110F: lib/test_fortify/*
8109F: scripts/test_fortify.sh8111F: scripts/test_fortify.sh
8110K: \b__NO_FORTIFY\b8112K: \b__NO_FORTIFY\b
@@ -11208,6 +11210,8 @@ M: Kees Cook <keescook@chromium.org> · 3097 unmodified lines
11208L: linux-hardening@vger.kernel.org11210L: linux-hardening@vger.kernel.org
11209S: Supported11211S: Supported
11210T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening11212T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
11213F: Documentation/ABI/testing/sysfs-kernel-oops_count
11214F: Documentation/ABI/testing/sysfs-kernel-warn_count
11211F: include/linux/overflow.h11215F: include/linux/overflow.h
11212F: include/linux/randomize_kstack.h11216F: include/linux/randomize_kstack.h
11213F: mm/usercopy.c11217F: mm/usercopy.c
@@ -19050,7 +19054,7 @@ M: Jason A. Donenfeld <Jason@zx2c4.com> · 7836 unmodified lines
19050S: Maintained19054S: Maintained
19051F: include/linux/siphash.h19055F: include/linux/siphash.h
19052F: lib/siphash.c19056F: lib/siphash.c
19053F: lib/test_siphash.c19057F: lib/siphash_kunit.c
19054 19058
19055SIS 190 ETHERNET DRIVER19059SIS 190 ETHERNET DRIVER
19056M: Francois Romieu <romieu@fr.zoreil.com>19060M: Francois Romieu <romieu@fr.zoreil.com>
Makefile+1−1
@@ -1120,7 +1120,7 @@ endif · 1119 unmodified lines
1120# We never want expected sections to be placed heuristically by the1120# We never want expected sections to be placed heuristically by the
1121# linker. All sections should be explicitly named in the linker script.1121# linker. All sections should be explicitly named in the linker script.
1122ifdef CONFIG_LD_ORPHAN_WARN1122ifdef CONFIG_LD_ORPHAN_WARN
1123LDFLAGS_vmlinux += --orphan-handling=warn1123LDFLAGS_vmlinux += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
1124endif1124endif
1125 1125
1126# Align the bit size of userspace programs with the kernel1126# Align the bit size of userspace programs with the kernel
arch/arm/boot/compressed/Makefile+1−1
@@ -124,7 +124,7 @@ LDFLAGS_vmlinux += --no-undefined · 123 unmodified lines
124LDFLAGS_vmlinux += -X124LDFLAGS_vmlinux += -X
125# Report orphan sections125# Report orphan sections
126ifdef CONFIG_LD_ORPHAN_WARN126ifdef CONFIG_LD_ORPHAN_WARN
127LDFLAGS_vmlinux += --orphan-handling=warn127LDFLAGS_vmlinux += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
128endif128endif
129# Next argument is a linker script129# Next argument is a linker script
130LDFLAGS_vmlinux += -T130LDFLAGS_vmlinux += -T
arch/arm64/kernel/vdso/Makefile+1−1
@@ -27,7 +27,7 @@ ldflags-y := -shared -soname=linux-vdso.so.1 --hash-style=sysv \ · 26 unmodified lines
27 -Bsymbolic --build-id=sha1 -n $(btildflags-y)27 -Bsymbolic --build-id=sha1 -n $(btildflags-y)
28 28
29ifdef CONFIG_LD_ORPHAN_WARN29ifdef CONFIG_LD_ORPHAN_WARN
30 ldflags-y += --orphan-handling=warn30 ldflags-y += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
31endif31endif
32 32
33ldflags-y += -T33ldflags-y += -T
arch/arm64/kernel/vdso32/Makefile+1−1
@@ -104,7 +104,7 @@ VDSO_AFLAGS += -D__ASSEMBLY__ · 103 unmodified lines
104VDSO_LDFLAGS += -Bsymbolic --no-undefined -soname=linux-vdso.so.1104VDSO_LDFLAGS += -Bsymbolic --no-undefined -soname=linux-vdso.so.1
105VDSO_LDFLAGS += -z max-page-size=4096 -z common-page-size=4096105VDSO_LDFLAGS += -z max-page-size=4096 -z common-page-size=4096
106VDSO_LDFLAGS += -shared --hash-style=sysv --build-id=sha1106VDSO_LDFLAGS += -shared --hash-style=sysv --build-id=sha1
107VDSO_LDFLAGS += --orphan-handling=warn107VDSO_LDFLAGS += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
108 108
109 109
110# Borrow vdsomunge.c from the arm vDSO110# Borrow vdsomunge.c from the arm vDSO
arch/um/drivers/virt-pci.c+6−3
@@ -97,7 +97,8 @@ static int um_pci_send_cmd(struct um_pci_device *dev, · 96 unmodified lines
97 }97 }
98 98
99 buf = get_cpu_var(um_pci_msg_bufs);99 buf = get_cpu_var(um_pci_msg_bufs);
100 memcpy(buf, cmd, cmd_size);100 if (buf)
101 memcpy(buf, cmd, cmd_size);
101 102
102 if (posted) {103 if (posted) {
103 u8 *ncmd = kmalloc(cmd_size + extra_size, GFP_ATOMIC);104 u8 *ncmd = kmalloc(cmd_size + extra_size, GFP_ATOMIC);
@@ -182,6 +183,7 @@ static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset, · 78 unmodified lines
182 struct um_pci_message_buffer *buf;183 struct um_pci_message_buffer *buf;
183 u8 *data;184 u8 *data;
184 unsigned long ret = ULONG_MAX;185 unsigned long ret = ULONG_MAX;
186 size_t bytes = sizeof(buf->data);
185 187
186 if (!dev)188 if (!dev)
187 return ULONG_MAX;189 return ULONG_MAX;
@@ -189,7 +191,8 @@ static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset, · 1 unmodified line
189 buf = get_cpu_var(um_pci_msg_bufs);191 buf = get_cpu_var(um_pci_msg_bufs);
190 data = buf->data;192 data = buf->data;
191 193
192 memset(buf->data, 0xff, sizeof(buf->data));194 if (buf)
195 memset(data, 0xff, bytes);
193 196
194 switch (size) {197 switch (size) {
195 case 1:198 case 1:
@@ -204,7 +207,7 @@ static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset, · 8 unmodified lines
204 goto out;207 goto out;
205 }208 }
206 209
207 if (um_pci_send_cmd(dev, &hdr, sizeof(hdr), NULL, 0, data, 8))210 if (um_pci_send_cmd(dev, &hdr, sizeof(hdr), NULL, 0, data, bytes))
208 goto out;211 goto out;
209 212
210 switch (size) {213 switch (size) {
arch/x86/boot/compressed/Makefile+1−1
@@ -68,7 +68,7 @@ KBUILD_LDFLAGS += $(call ld-option,--no-ld-generated-unwind-info) · 67 unmodified lines
68# address by the bootloader.68# address by the bootloader.
69LDFLAGS_vmlinux := -pie $(call ld-option, --no-dynamic-linker)69LDFLAGS_vmlinux := -pie $(call ld-option, --no-dynamic-linker)
70ifdef CONFIG_LD_ORPHAN_WARN70ifdef CONFIG_LD_ORPHAN_WARN
71LDFLAGS_vmlinux += --orphan-handling=warn71LDFLAGS_vmlinux += --orphan-handling=$(CONFIG_LD_ORPHAN_WARN_LEVEL)
72endif72endif
73LDFLAGS_vmlinux += -z noexecstack73LDFLAGS_vmlinux += -z noexecstack
74ifeq ($(CONFIG_LD_IS_BFD),y)74ifeq ($(CONFIG_LD_IS_BFD),y)
arch/x86/mm/pgtable.c+13−9
@@ -299,9 +299,6 @@ static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmds[]) · 298 unmodified lines
299 pud_t *pud;299 pud_t *pud;
300 int i;300 int i;
301 301
302 if (PREALLOCATED_PMDS == 0) /* Work around gcc-3.4.x bug */
303 return;
304
305 p4d = p4d_offset(pgd, 0);302 p4d = p4d_offset(pgd, 0);
306 pud = pud_offset(p4d, 0);303 pud = pud_offset(p4d, 0);
307 304
@@ -434,10 +431,12 @@ pgd_t *pgd_alloc(struct mm_struct *mm) · 126 unmodified lines
434 431
435 mm->pgd = pgd;432 mm->pgd = pgd;
436 433
437 if (preallocate_pmds(mm, pmds, PREALLOCATED_PMDS) != 0)434 if (sizeof(pmds) != 0 &&
435 preallocate_pmds(mm, pmds, PREALLOCATED_PMDS) != 0)
438 goto out_free_pgd;436 goto out_free_pgd;
439 437
440 if (preallocate_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS) != 0)438 if (sizeof(u_pmds) != 0 &&
439 preallocate_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS) != 0)
441 goto out_free_pmds;440 goto out_free_pmds;
442 441
443 if (paravirt_pgd_alloc(mm) != 0)442 if (paravirt_pgd_alloc(mm) != 0)
@@ -451,17 +450,22 @@ pgd_t *pgd_alloc(struct mm_struct *mm) · 7 unmodified lines
451 spin_lock(&pgd_lock);450 spin_lock(&pgd_lock);
452 451
453 pgd_ctor(mm, pgd);452 pgd_ctor(mm, pgd);
454 pgd_prepopulate_pmd(mm, pgd, pmds);453 if (sizeof(pmds) != 0)
455 pgd_prepopulate_user_pmd(mm, pgd, u_pmds);454 pgd_prepopulate_pmd(mm, pgd, pmds);
455
456 if (sizeof(u_pmds) != 0)
457 pgd_prepopulate_user_pmd(mm, pgd, u_pmds);
456 458
457 spin_unlock(&pgd_lock);459 spin_unlock(&pgd_lock);
458 460
459 return pgd;461 return pgd;
460 462
461out_free_user_pmds:463out_free_user_pmds:
462 free_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS);464 if (sizeof(u_pmds) != 0)
465 free_pmds(mm, u_pmds, PREALLOCATED_USER_PMDS);
463out_free_pmds:466out_free_pmds:
464 free_pmds(mm, pmds, PREALLOCATED_PMDS);467 if (sizeof(pmds) != 0)
468 free_pmds(mm, pmds, PREALLOCATED_PMDS);
465out_free_pgd:469out_free_pgd:
466 _pgd_free(pgd);470 _pgd_free(pgd);
467out:471out:
drivers/base/firmware_loader/main.c+1−1
@@ -821,7 +821,7 @@ _request_firmware(const struct firmware **firmware_p, const char *name, · 820 unmodified lines
821 * called by a driver when serving an unrelated request from userland, we use821 * called by a driver when serving an unrelated request from userland, we use
822 * the kernel credentials to read the file.822 * the kernel credentials to read the file.
823 */823 */
824 kern_cred = prepare_kernel_cred(NULL);824 kern_cred = prepare_kernel_cred(&init_task);
825 if (!kern_cred) {825 if (!kern_cred) {
826 ret = -ENOMEM;826 ret = -ENOMEM;
827 goto out;827 goto out;
drivers/dma-buf/dma-resv.c+7−2
@@ -98,12 +98,17 @@ static void dma_resv_list_set(struct dma_resv_list *list, · 97 unmodified lines
98static struct dma_resv_list *dma_resv_list_alloc(unsigned int max_fences)98static struct dma_resv_list *dma_resv_list_alloc(unsigned int max_fences)
99{99{
100 struct dma_resv_list *list;100 struct dma_resv_list *list;
101 size_t size;
101 102
102 list = kmalloc(struct_size(list, table, max_fences), GFP_KERNEL);103 /* Round up to the next kmalloc bucket size. */
104 size = kmalloc_size_roundup(struct_size(list, table, max_fences));
105
106 list = kmalloc(size, GFP_KERNEL);
103 if (!list)107 if (!list)
104 return NULL;108 return NULL;
105 109
106 list->max_fences = (ksize(list) - offsetof(typeof(*list), table)) /110 /* Given the resulting bucket size, recalculated max_fences. */
111 list->max_fences = (size - offsetof(typeof(*list), table)) /
107 sizeof(*list->table);112 sizeof(*list->table);
108 113
109 return list;114 return list;
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c+3−2
@@ -60,8 +60,9 @@ static int fsl_dcu_drm_connector_get_modes(struct drm_connector *connector) · 59 unmodified lines
60 return drm_panel_get_modes(fsl_connector->panel, connector);60 return drm_panel_get_modes(fsl_connector->panel, connector);
61}61}
62 62
63static int fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector,63static enum drm_mode_status
64 struct drm_display_mode *mode)64fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector,
65 struct drm_display_mode *mode)
65{66{
66 if (mode->hdisplay & 0xf)67 if (mode->hdisplay & 0xf)
67 return MODE_ERROR;68 return MODE_ERROR;
drivers/gpu/drm/i915/i915_user_extensions.c+1−1
@@ -51,7 +51,7 @@ int i915_user_extensions(struct i915_user_extension __user *ext, · 50 unmodified lines
51 return err;51 return err;
52 52
53 if (get_user(next, &ext->next_extension) ||53 if (get_user(next, &ext->next_extension) ||
54 overflows_type(next, ext))54 overflows_type(next, uintptr_t))
55 return -EFAULT;55 return -EFAULT;
56 56
57 ext = u64_to_user_ptr(next);57 ext = u64_to_user_ptr(next);
drivers/gpu/drm/i915/i915_utils.h+0−4
@@ -111,10 +111,6 @@ bool i915_error_injected(void); · 110 unmodified lines
111#define range_overflows_end_t(type, start, size, max) \111#define range_overflows_end_t(type, start, size, max) \
112 range_overflows_end((type)(start), (type)(size), (type)(max))112 range_overflows_end((type)(start), (type)(size), (type)(max))
113 113
114/* Note we don't consider signbits :| */
115#define overflows_type(x, T) \
116 (sizeof(x) > sizeof(T) && (x) >> BITS_PER_TYPE(T))
117
118#define ptr_mask_bits(ptr, n) ({ \114#define ptr_mask_bits(ptr, n) ({ \
119 unsigned long __v = (unsigned long)(ptr); \115 unsigned long __v = (unsigned long)(ptr); \
120 (typeof(ptr))(__v & -BIT(n)); \116 (typeof(ptr))(__v & -BIT(n)); \
drivers/gpu/drm/sti/sti_dvo.c+3−2
@@ -346,8 +346,9 @@ static int sti_dvo_connector_get_modes(struct drm_connector *connector) · 345 unmodified lines
346 346
347#define CLK_TOLERANCE_HZ 50347#define CLK_TOLERANCE_HZ 50
348 348
349static int sti_dvo_connector_mode_valid(struct drm_connector *connector,349static enum drm_mode_status
350 struct drm_display_mode *mode)350sti_dvo_connector_mode_valid(struct drm_connector *connector,
351 struct drm_display_mode *mode)
351{352{
352 int target = mode->clock * 1000;353 int target = mode->clock * 1000;
353 int target_min = target - CLK_TOLERANCE_HZ;354 int target_min = target - CLK_TOLERANCE_HZ;
drivers/gpu/drm/sti/sti_hda.c+3−2
@@ -601,8 +601,9 @@ static int sti_hda_connector_get_modes(struct drm_connector *connector) · 600 unmodified lines
601 601
602#define CLK_TOLERANCE_HZ 50602#define CLK_TOLERANCE_HZ 50
603 603
604static int sti_hda_connector_mode_valid(struct drm_connector *connector,604static enum drm_mode_status
605 struct drm_display_mode *mode)605sti_hda_connector_mode_valid(struct drm_connector *connector,
606 struct drm_display_mode *mode)
606{607{
607 int target = mode->clock * 1000;608 int target = mode->clock * 1000;
608 int target_min = target - CLK_TOLERANCE_HZ;609 int target_min = target - CLK_TOLERANCE_HZ;
drivers/gpu/drm/sti/sti_hdmi.c+3−2
@@ -1004,8 +1004,9 @@ fail: · 1003 unmodified lines
1004 1004
1005#define CLK_TOLERANCE_HZ 501005#define CLK_TOLERANCE_HZ 50
1006 1006
1007static int sti_hdmi_connector_mode_valid(struct drm_connector *connector,1007static enum drm_mode_status
1008 struct drm_display_mode *mode)1008sti_hdmi_connector_mode_valid(struct drm_connector *connector,
1009 struct drm_display_mode *mode)
1009{1010{
1010 int target = mode->clock * 1000;1011 int target = mode->clock * 1000;
1011 int target_min = target - CLK_TOLERANCE_HZ;1012 int target_min = target - CLK_TOLERANCE_HZ;
fs/btrfs/send.c+6−5
@@ -485,6 +485,11 @@ static int fs_path_ensure_buf(struct fs_path *p, int len) · 484 unmodified lines
485 path_len = p->end - p->start;485 path_len = p->end - p->start;
486 old_buf_len = p->buf_len;486 old_buf_len = p->buf_len;
487 487
488 /*
489 * Allocate to the next largest kmalloc bucket size, to let
490 * the fast path happen most of the time.
491 */
492 len = kmalloc_size_roundup(len);
488 /*493 /*
489 * First time the inline_buf does not suffice494 * First time the inline_buf does not suffice
490 */495 */
@@ -498,11 +503,7 @@ static int fs_path_ensure_buf(struct fs_path *p, int len) · 7 unmodified lines
498 if (!tmp_buf)503 if (!tmp_buf)
499 return -ENOMEM;504 return -ENOMEM;
500 p->buf = tmp_buf;505 p->buf = tmp_buf;
501 /*506 p->buf_len = len;
502 * The real size of the buffer is bigger, this will let the fast path
503 * happen most of the time
504 */
505 p->buf_len = ksize(p->buf);
506 507
507 if (p->reversed) {508 if (p->reversed) {
508 tmp_buf = p->buf + old_buf_len - path_len - 1;509 tmp_buf = p->buf + old_buf_len - path_len - 1;
fs/cifs/cifs_spnego.c+1−1
@@ -189,7 +189,7 @@ init_cifs_spnego(void) · 188 unmodified lines
189 * spnego upcalls.189 * spnego upcalls.
190 */190 */
191 191
192 cred = prepare_kernel_cred(NULL);192 cred = prepare_kernel_cred(&init_task);
193 if (!cred)193 if (!cred)
194 return -ENOMEM;194 return -ENOMEM;
195 195
fs/cifs/cifsacl.c+1−1
@@ -470,7 +470,7 @@ init_cifs_idmap(void) · 469 unmodified lines
470 * this is used to prevent malicious redirections from being installed470 * this is used to prevent malicious redirections from being installed
471 * with add_key().471 * with add_key().
472 */472 */
473 cred = prepare_kernel_cred(NULL);473 cred = prepare_kernel_cred(&init_task);
474 if (!cred)474 if (!cred)
475 return -ENOMEM;475 return -ENOMEM;
476 476
fs/coredump.c+5−2
@@ -68,7 +68,10 @@ struct core_name { · 67 unmodified lines
68 68
69static int expand_corename(struct core_name *cn, int size)69static int expand_corename(struct core_name *cn, int size)
70{70{
71 char *corename = krealloc(cn->corename, size, GFP_KERNEL);71 char *corename;
72
73 size = kmalloc_size_roundup(size);
74 corename = krealloc(cn->corename, size, GFP_KERNEL);
72 75
73 if (!corename)76 if (!corename)
74 return -ENOMEM;77 return -ENOMEM;
@@ -76,7 +79,7 @@ static int expand_corename(struct core_name *cn, int size) · 1 unmodified line
76 if (size > core_name_size) /* racy but harmless */79 if (size > core_name_size) /* racy but harmless */
77 core_name_size = size;80 core_name_size = size;
78 81
79 cn->size = ksize(corename);82 cn->size = size;
80 cn->corename = corename;83 cn->corename = corename;
81 return 0;84 return 0;
82}85}
fs/ksmbd/smb2pdu.c+2−2
@@ -3438,7 +3438,7 @@ static int smb2_populate_readdir_entry(struct ksmbd_conn *conn, int info_level, · 3437 unmodified lines
3438 goto free_conv_name;3438 goto free_conv_name;
3439 }3439 }
3440 3440
3441 struct_sz = readdir_info_level_struct_sz(info_level) - 1 + conv_len;3441 struct_sz = readdir_info_level_struct_sz(info_level) + conv_len;
3442 next_entry_offset = ALIGN(struct_sz, KSMBD_DIR_INFO_ALIGNMENT);3442 next_entry_offset = ALIGN(struct_sz, KSMBD_DIR_INFO_ALIGNMENT);
3443 d_info->last_entry_off_align = next_entry_offset - struct_sz;3443 d_info->last_entry_off_align = next_entry_offset - struct_sz;
3444 3444
@@ -3690,7 +3690,7 @@ static int reserve_populate_dentry(struct ksmbd_dir_info *d_info, · 245 unmodified lines
3690 return -EOPNOTSUPP;3690 return -EOPNOTSUPP;
3691 3691
3692 conv_len = (d_info->name_len + 1) * 2;3692 conv_len = (d_info->name_len + 1) * 2;
3693 next_entry_offset = ALIGN(struct_sz - 1 + conv_len,3693 next_entry_offset = ALIGN(struct_sz + conv_len,
3694 KSMBD_DIR_INFO_ALIGNMENT);3694 KSMBD_DIR_INFO_ALIGNMENT);
3695 3695
3696 if (next_entry_offset > d_info->out_buf_len) {3696 if (next_entry_offset > d_info->out_buf_len) {
fs/ksmbd/smb2pdu.h+1−1
@@ -443,7 +443,7 @@ struct smb2_posix_info { · 442 unmodified lines
443 /* SidBuffer contain two sids (UNIX user sid(16), UNIX group sid(16)) */443 /* SidBuffer contain two sids (UNIX user sid(16), UNIX group sid(16)) */
444 u8 SidBuffer[32];444 u8 SidBuffer[32];
445 __le32 name_len;445 __le32 name_len;
446 u8 name[1];446 u8 name[];
447 /*447 /*
448 * var sized owner SID448 * var sized owner SID
449 * var sized group SID449 * var sized group SID
fs/ksmbd/smb_common.c+1−1
@@ -623,7 +623,7 @@ int ksmbd_override_fsids(struct ksmbd_work *work) · 622 unmodified lines
623 if (share->force_gid != KSMBD_SHARE_INVALID_GID)623 if (share->force_gid != KSMBD_SHARE_INVALID_GID)
624 gid = share->force_gid;624 gid = share->force_gid;
625 625
626 cred = prepare_kernel_cred(NULL);626 cred = prepare_kernel_cred(&init_task);
627 if (!cred)627 if (!cred)
628 return -ENOMEM;628 return -ENOMEM;
629 629
fs/ksmbd/smb_common.h+6−6
@@ -277,14 +277,14 @@ struct file_directory_info { · 276 unmodified lines
277 __le64 AllocationSize;277 __le64 AllocationSize;
278 __le32 ExtFileAttributes;278 __le32 ExtFileAttributes;
279 __le32 FileNameLength;279 __le32 FileNameLength;
280 char FileName[1];280 char FileName[];
281} __packed; /* level 0x101 FF resp data */281} __packed; /* level 0x101 FF resp data */
282 282
283struct file_names_info {283struct file_names_info {
284 __le32 NextEntryOffset;284 __le32 NextEntryOffset;
285 __u32 FileIndex;285 __u32 FileIndex;
286 __le32 FileNameLength;286 __le32 FileNameLength;
287 char FileName[1];287 char FileName[];
288} __packed; /* level 0xc FF resp data */288} __packed; /* level 0xc FF resp data */
289 289
290struct file_full_directory_info {290struct file_full_directory_info {
@@ -299,7 +299,7 @@ struct file_full_directory_info { · 8 unmodified lines
299 __le32 ExtFileAttributes;299 __le32 ExtFileAttributes;
300 __le32 FileNameLength;300 __le32 FileNameLength;
301 __le32 EaSize;301 __le32 EaSize;
302 char FileName[1];302 char FileName[];
303} __packed; /* level 0x102 FF resp */303} __packed; /* level 0x102 FF resp */
304 304
305struct file_both_directory_info {305struct file_both_directory_info {
@@ -317,7 +317,7 @@ struct file_both_directory_info { · 11 unmodified lines
317 __u8 ShortNameLength;317 __u8 ShortNameLength;
318 __u8 Reserved;318 __u8 Reserved;
319 __u8 ShortName[24];319 __u8 ShortName[24];
320 char FileName[1];320 char FileName[];
321} __packed; /* level 0x104 FFrsp data */321} __packed; /* level 0x104 FFrsp data */
322 322
323struct file_id_both_directory_info {323struct file_id_both_directory_info {
@@ -337,7 +337,7 @@ struct file_id_both_directory_info { · 13 unmodified lines
337 __u8 ShortName[24];337 __u8 ShortName[24];
338 __le16 Reserved2;338 __le16 Reserved2;
339 __le64 UniqueId;339 __le64 UniqueId;
340 char FileName[1];340 char FileName[];
341} __packed;341} __packed;
342 342
343struct file_id_full_dir_info {343struct file_id_full_dir_info {
@@ -354,7 +354,7 @@ struct file_id_full_dir_info { · 10 unmodified lines
354 __le32 EaSize; /* EA size */354 __le32 EaSize; /* EA size */
355 __le32 Reserved;355 __le32 Reserved;
356 __le64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/356 __le64 UniqueId; /* inode num - le since Samba puts ino in low 32 bit*/
357 char FileName[1];357 char FileName[];
358} __packed; /* level 0x105 FF rsp data */358} __packed; /* level 0x105 FF rsp data */
359 359
360struct smb_version_values {360struct smb_version_values {
fs/nfs/flexfilelayout/flexfilelayout.c+2−2
@@ -493,10 +493,10 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh, · 492 unmodified lines
493 gid = make_kgid(&init_user_ns, id);493 gid = make_kgid(&init_user_ns, id);
494 494
495 if (gfp_flags & __GFP_FS)495 if (gfp_flags & __GFP_FS)
496 kcred = prepare_kernel_cred(NULL);496 kcred = prepare_kernel_cred(&init_task);
497 else {497 else {
498 unsigned int nofs_flags = memalloc_nofs_save();498 unsigned int nofs_flags = memalloc_nofs_save();
499 kcred = prepare_kernel_cred(NULL);499 kcred = prepare_kernel_cred(&init_task);
500 memalloc_nofs_restore(nofs_flags);500 memalloc_nofs_restore(nofs_flags);
501 }501 }
502 rc = -ENOMEM;502 rc = -ENOMEM;
fs/nfs/nfs4idmap.c+1−1
@@ -203,7 +203,7 @@ int nfs_idmap_init(void) · 202 unmodified lines
203 printk(KERN_NOTICE "NFS: Registering the %s key type\n",203 printk(KERN_NOTICE "NFS: Registering the %s key type\n",
204 key_type_id_resolver.name);204 key_type_id_resolver.name);
205 205
206 cred = prepare_kernel_cred(NULL);206 cred = prepare_kernel_cred(&init_task);
207 if (!cred)207 if (!cred)
208 return -ENOMEM;208 return -ENOMEM;
209 209
fs/nfsd/nfs4callback.c+1−1
@@ -942,7 +942,7 @@ static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct r · 941 unmodified lines
942 } else {942 } else {
943 struct cred *kcred;943 struct cred *kcred;
944 944
945 kcred = prepare_kernel_cred(NULL);945 kcred = prepare_kernel_cred(&init_task);
946 if (!kcred)946 if (!kcred)
947 return NULL;947 return NULL;
948 948
include/linux/compiler.h+1−0
@@ -236,6 +236,7 @@ static inline void *offset_to_ptr(const int *off) · 235 unmodified lines
236 * bool and also pointer types.236 * bool and also pointer types.
237 */237 */
238#define is_signed_type(type) (((type)(-1)) < (__force type)1)238#define is_signed_type(type) (((type)(-1)) < (__force type)1)
239#define is_unsigned_type(type) (!is_signed_type(type))
239 240
240/*241/*
241 * This is needed in functions which generate the stack canary, see242 * This is needed in functions which generate the stack canary, see
include/linux/device.h+4−3
@@ -197,9 +197,9 @@ void devres_remove_group(struct device *dev, void *id); · 196 unmodified lines
197int devres_release_group(struct device *dev, void *id);197int devres_release_group(struct device *dev, void *id);
198 198
199/* managed devm_k.alloc/kfree for device drivers */199/* managed devm_k.alloc/kfree for device drivers */
200void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp) __malloc;200void *devm_kmalloc(struct device *dev, size_t size, gfp_t gfp) __alloc_size(2);
201void *devm_krealloc(struct device *dev, void *ptr, size_t size,201void *devm_krealloc(struct device *dev, void *ptr, size_t size,
202 gfp_t gfp) __must_check;202 gfp_t gfp) __must_check __realloc_size(3);
203__printf(3, 0) char *devm_kvasprintf(struct device *dev, gfp_t gfp,203__printf(3, 0) char *devm_kvasprintf(struct device *dev, gfp_t gfp,
204 const char *fmt, va_list ap) __malloc;204 const char *fmt, va_list ap) __malloc;
205__printf(3, 4) char *devm_kasprintf(struct device *dev, gfp_t gfp,205__printf(3, 4) char *devm_kasprintf(struct device *dev, gfp_t gfp,
@@ -226,7 +226,8 @@ static inline void *devm_kcalloc(struct device *dev, · 20 unmodified lines
226void devm_kfree(struct device *dev, const void *p);226void devm_kfree(struct device *dev, const void *p);
227char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) __malloc;227char *devm_kstrdup(struct device *dev, const char *s, gfp_t gfp) __malloc;
228const char *devm_kstrdup_const(struct device *dev, const char *s, gfp_t gfp);228const char *devm_kstrdup_const(struct device *dev, const char *s, gfp_t gfp);
229void *devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp);229void *devm_kmemdup(struct device *dev, const void *src, size_t len, gfp_t gfp)
230 __realloc_size(3);
230 231
231unsigned long devm_get_free_pages(struct device *dev,232unsigned long devm_get_free_pages(struct device *dev,
232 gfp_t gfp_mask, unsigned int order);233 gfp_t gfp_mask, unsigned int order);
include/linux/fortify-string.h+136−12
@@ -18,7 +18,7 @@ void __write_overflow_field(size_t avail, size_t wanted) __compiletime_warning(" · 17 unmodified lines
18 18
19#define __compiletime_strlen(p) \19#define __compiletime_strlen(p) \
20({ \20({ \
21 unsigned char *__p = (unsigned char *)(p); \21 char *__p = (char *)(p); \
22 size_t __ret = SIZE_MAX; \22 size_t __ret = SIZE_MAX; \
23 size_t __p_size = __member_size(p); \23 size_t __p_size = __member_size(p); \
24 if (__p_size != SIZE_MAX && \24 if (__p_size != SIZE_MAX && \
@@ -119,13 +119,13 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) · 94 unmodified lines
119 * Instead, please choose an alternative, so that the expectation119 * Instead, please choose an alternative, so that the expectation
120 * of @p's contents is unambiguous:120 * of @p's contents is unambiguous:
121 *121 *
122 * +--------------------+-----------------+------------+122 * +--------------------+--------------------+------------+
123 * | @p needs to be: | padded to @size | not padded |123 * | **p** needs to be: | padded to **size** | not padded |
124 * +====================+=================+============+124 * +====================+====================+============+
125 * | NUL-terminated | strscpy_pad() | strscpy() |125 * | NUL-terminated | strscpy_pad() | strscpy() |
126 * +--------------------+-----------------+------------+126 * +--------------------+--------------------+------------+
127 * | not NUL-terminated | strtomem_pad() | strtomem() |127 * | not NUL-terminated | strtomem_pad() | strtomem() |
128 * +--------------------+-----------------+------------+128 * +--------------------+--------------------+------------+
129 *129 *
130 * Note strscpy*()'s differing return values for detecting truncation,130 * Note strscpy*()'s differing return values for detecting truncation,
131 * and strtomem*()'s expectation that the destination is marked with131 * and strtomem*()'s expectation that the destination is marked with
@@ -144,6 +144,21 @@ char *strncpy(char * const POS p, const char *q, __kernel_size_t size) · 12 unmodified lines
144 return __underlying_strncpy(p, q, size);144 return __underlying_strncpy(p, q, size);
145}145}
146 146
147/**
148 * strcat - Append a string to an existing string
149 *
150 * @p: pointer to NUL-terminated string to append to
151 * @q: pointer to NUL-terminated source string to append from
152 *
153 * Do not use this function. While FORTIFY_SOURCE tries to avoid
154 * read and write overflows, this is only possible when the
155 * destination buffer size is known to the compiler. Prefer
156 * building the string with formatting, via scnprintf() or similar.
157 * At the very least, use strncat().
158 *
159 * Returns @p.
160 *
161 */
147__FORTIFY_INLINE __diagnose_as(__builtin_strcat, 1, 2)162__FORTIFY_INLINE __diagnose_as(__builtin_strcat, 1, 2)
148char *strcat(char * const POS p, const char *q)163char *strcat(char * const POS p, const char *q)
149{164{
@@ -157,6 +172,16 @@ char *strcat(char * const POS p, const char *q) · 7 unmodified lines
157}172}
158 173
159extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen);174extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen);
175/**
176 * strnlen - Return bounded count of characters in a NUL-terminated string
177 *
178 * @p: pointer to NUL-terminated string to count.
179 * @maxlen: maximum number of characters to count.
180 *
181 * Returns number of characters in @p (NOT including the final NUL), or
182 * @maxlen, if no NUL has been found up to there.
183 *
184 */
160__FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size_t maxlen)185__FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size_t maxlen)
161{186{
162 size_t p_size = __member_size(p);187 size_t p_size = __member_size(p);
@@ -182,6 +207,19 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size · 19 unmodified lines
182 * possible for strlen() to be used on compile-time strings for use in207 * possible for strlen() to be used on compile-time strings for use in
183 * static initializers (i.e. as a constant expression).208 * static initializers (i.e. as a constant expression).
184 */209 */
210/**
211 * strlen - Return count of characters in a NUL-terminated string
212 *
213 * @p: pointer to NUL-terminated string to count.
214 *
215 * Do not use this function unless the string length is known at
216 * compile-time. When @p is unterminated, this function may crash
217 * or return unexpected counts that could lead to memory content
218 * exposures. Prefer strnlen().
219 *
220 * Returns number of characters in @p (NOT including the final NUL).
221 *
222 */
185#define strlen(p) \223#define strlen(p) \
186 __builtin_choose_expr(__is_constexpr(__builtin_strlen(p)), \224 __builtin_choose_expr(__is_constexpr(__builtin_strlen(p)), \
187 __builtin_strlen(p), __fortify_strlen(p))225 __builtin_strlen(p), __fortify_strlen(p))
@@ -200,8 +238,26 @@ __kernel_size_t __fortify_strlen(const char * const POS p) · 12 unmodified lines
200 return ret;238 return ret;
201}239}
202 240
203/* defined after fortified strlen to reuse it */241/* Defined after fortified strlen() to reuse it. */
204extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy);242extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy);
243/**
244 * strlcpy - Copy a string into another string buffer
245 *
246 * @p: pointer to destination of copy
247 * @q: pointer to NUL-terminated source string to copy
248 * @size: maximum number of bytes to write at @p
249 *
250 * If strlen(@q) >= @size, the copy of @q will be truncated at
251 * @size - 1 bytes. @p will always be NUL-terminated.
252 *
253 * Do not use this function. While FORTIFY_SOURCE tries to avoid
254 * over-reads when calculating strlen(@q), it is still possible.
255 * Prefer strscpy(), though note its different return values for
256 * detecting truncation.
257 *
258 * Returns total number of bytes written to @p, including terminating NUL.
259 *
260 */
205__FORTIFY_INLINE size_t strlcpy(char * const POS p, const char * const POS q, size_t size)261__FORTIFY_INLINE size_t strlcpy(char * const POS p, const char * const POS q, size_t size)
206{262{
207 size_t p_size = __member_size(p);263 size_t p_size = __member_size(p);
@@ -227,8 +283,32 @@ __FORTIFY_INLINE size_t strlcpy(char * const POS p, const char * const POS q, si · 19 unmodified lines
227 return q_len;283 return q_len;
228}284}
229 285
230/* defined after fortified strnlen to reuse it */286/* Defined after fortified strnlen() to reuse it. */
231extern ssize_t __real_strscpy(char *, const char *, size_t) __RENAME(strscpy);287extern ssize_t __real_strscpy(char *, const char *, size_t) __RENAME(strscpy);
288/**
289 * strscpy - Copy a C-string into a sized buffer
290 *
291 * @p: Where to copy the string to
292 * @q: Where to copy the string from
293 * @size: Size of destination buffer
294 *
295 * Copy the source string @p, or as much of it as fits, into the destination
296 * @q buffer. The behavior is undefined if the string buffers overlap. The
297 * destination @p buffer is always NUL terminated, unless it's zero-sized.
298 *
299 * Preferred to strlcpy() since the API doesn't require reading memory
300 * from the source @q string beyond the specified @size bytes, and since
301 * the return value is easier to error-check than strlcpy()'s.
302 * In addition, the implementation is robust to the string changing out
303 * from underneath it, unlike the current strlcpy() implementation.
304 *
305 * Preferred to strncpy() since it always returns a valid string, and
306 * doesn't unnecessarily force the tail of the destination buffer to be
307 * zero padded. If padding is desired please use strscpy_pad().
308 *
309 * Returns the number of characters copied in @p (not including the
310 * trailing %NUL) or -E2BIG if @size is 0 or the copy of @q was truncated.
311 */
232__FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, size_t size)312__FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, size_t size)
233{313{
234 size_t len;314 size_t len;
@@ -247,6 +327,16 @@ __FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, s · 12 unmodified lines
247 if (__compiletime_lessthan(p_size, size))327 if (__compiletime_lessthan(p_size, size))
248 __write_overflow();328 __write_overflow();
249 329
330 /* Short-circuit for compile-time known-safe lengths. */
331 if (__compiletime_lessthan(p_size, SIZE_MAX)) {
332 len = __compiletime_strlen(q);
333
334 if (len < SIZE_MAX && __compiletime_lessthan(len, size)) {
335 __underlying_memcpy(p, q, len + 1);
336 return len;
337 }
338 }
339
250 /*340 /*
251 * This call protects from read overflow, because len will default to q341 * This call protects from read overflow, because len will default to q
252 * length if it smaller than size.342 * length if it smaller than size.
@@ -274,7 +364,26 @@ __FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, s · 21 unmodified lines
274 return __real_strscpy(p, q, len);364 return __real_strscpy(p, q, len);
275}365}
276 366
277/* defined after fortified strlen and strnlen to reuse them */367/**
368 * strncat - Append a string to an existing string
369 *
370 * @p: pointer to NUL-terminated string to append to
371 * @q: pointer to source string to append from
372 * @count: Maximum bytes to read from @q
373 *
374 * Appends at most @count bytes from @q (stopping at the first
375 * NUL byte) after the NUL-terminated string at @p. @p will be
376 * NUL-terminated.
377 *
378 * Do not use this function. While FORTIFY_SOURCE tries to avoid
379 * read and write overflows, this is only possible when the sizes
380 * of @p and @q are known to the compiler. Prefer building the
381 * string with formatting, via scnprintf() or similar.
382 *
383 * Returns @p.
384 *
385 */
386/* Defined after fortified strlen() and strnlen() to reuse them. */
278__FORTIFY_INLINE __diagnose_as(__builtin_strncat, 1, 2, 3)387__FORTIFY_INLINE __diagnose_as(__builtin_strncat, 1, 2, 3)
279char *strncat(char * const POS p, const char * const POS q, __kernel_size_t count)388char *strncat(char * const POS p, const char * const POS q, __kernel_size_t count)
280{389{
@@ -573,7 +682,8 @@ __FORTIFY_INLINE void *memchr_inv(const void * const POS0 p, int c, size_t size) · 292 unmodified lines
573 return __real_memchr_inv(p, c, size);682 return __real_memchr_inv(p, c, size);
574}683}
575 684
576extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENAME(kmemdup);685extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENAME(kmemdup)
686 __realloc_size(2);
577__FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp_t gfp)687__FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp_t gfp)
578{688{
579 size_t p_size = __struct_size(p);689 size_t p_size = __struct_size(p);
@@ -585,6 +695,20 @@ __FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp_t gfp · 5 unmodified lines
585 return __real_kmemdup(p, size, gfp);695 return __real_kmemdup(p, size, gfp);
586}696}
587 697
698/**
699 * strcpy - Copy a string into another string buffer
700 *
701 * @p: pointer to destination of copy
702 * @q: pointer to NUL-terminated source string to copy
703 *
704 * Do not use this function. While FORTIFY_SOURCE tries to avoid
705 * overflows, this is only possible when the sizes of @q and @p are
706 * known to the compiler. Prefer strscpy(), though note its different
707 * return values for detecting truncation.
708 *
709 * Returns @p.
710 *
711 */
588/* Defined after fortified strlen to reuse it. */712/* Defined after fortified strlen to reuse it. */
589__FORTIFY_INLINE __diagnose_as(__builtin_strcpy, 1, 2)713__FORTIFY_INLINE __diagnose_as(__builtin_strcpy, 1, 2)
590char *strcpy(char * const POS p, const char * const POS q)714char *strcpy(char * const POS p, const char * const POS q)
include/linux/hpet.h+1−1
@@ -30,7 +30,7 @@ struct hpet { · 29 unmodified lines
30 unsigned long _hpet_compare;30 unsigned long _hpet_compare;
31 } _u1;31 } _u1;
32 u64 hpet_fsb[2]; /* FSB route */32 u64 hpet_fsb[2]; /* FSB route */
33 } hpet_timers[1];33 } hpet_timers[];
34};34};
35 35
36#define hpet_mc _u0._hpet_mc36#define hpet_mc _u0._hpet_mc
include/linux/overflow.h+47−0
@@ -128,6 +128,53 @@ static inline bool __must_check __must_check_overflow(bool overflow) · 127 unmodified lines
128 (*_d >> _to_shift) != _a); \128 (*_d >> _to_shift) != _a); \
129}))129}))
130 130
131#define __overflows_type_constexpr(x, T) ( \
132 is_unsigned_type(typeof(x)) ? \
133 (x) > type_max(typeof(T)) : \
134 is_unsigned_type(typeof(T)) ? \
135 (x) < 0 || (x) > type_max(typeof(T)) : \
136 (x) < type_min(typeof(T)) || (x) > type_max(typeof(T)))
137
138#define __overflows_type(x, T) ({ \
139 typeof(T) v = 0; \
140 check_add_overflow((x), v, &v); \
141})
142
143/**
144 * overflows_type - helper for checking the overflows between value, variables,
145 * or data type
146 *
147 * @n: source constant value or variable to be checked
148 * @T: destination variable or data type proposed to store @x
149 *
150 * Compares the @x expression for whether or not it can safely fit in
151 * the storage of the type in @T. @x and @T can have different types.
152 * If @x is a constant expression, this will also resolve to a constant
153 * expression.
154 *
155 * Returns: true if overflow can occur, false otherwise.
156 */
157#define overflows_type(n, T) \
158 __builtin_choose_expr(__is_constexpr(n), \
159 __overflows_type_constexpr(n, T), \
160 __overflows_type(n, T))
161
162/**
163 * castable_to_type - like __same_type(), but also allows for casted literals
164 *
165 * @n: variable or constant value
166 * @T: variable or data type
167 *
168 * Unlike the __same_type() macro, this allows a constant value as the
169 * first argument. If this value would not overflow into an assignment
170 * of the second argument's type, it returns true. Otherwise, this falls
171 * back to __same_type().
172 */
173#define castable_to_type(n, T) \
174 __builtin_choose_expr(__is_constexpr(n), \
175 !__overflows_type_constexpr(n, T), \
176 __same_type(n, T))
177
131/**178/**
132 * size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX179 * size_mul() - Calculate size_t multiplication with saturation at SIZE_MAX
133 * @factor1: first factor180 * @factor1: first factor
include/linux/panic.h+1−0
@@ -11,6 +11,7 @@ extern long (*panic_blink)(int state); · 10 unmodified lines
11__printf(1, 2)11__printf(1, 2)
12void panic(const char *fmt, ...) __noreturn __cold;12void panic(const char *fmt, ...) __noreturn __cold;
13void nmi_panic(struct pt_regs *regs, const char *msg);13void nmi_panic(struct pt_regs *regs, const char *msg);
14void check_panic_on_warn(const char *origin);
14extern void oops_enter(void);15extern void oops_enter(void);
15extern void oops_exit(void);16extern void oops_exit(void);
16extern bool oops_may_print(void);17extern bool oops_may_print(void);
include/linux/string.h+1−1
@@ -176,7 +176,7 @@ extern void kfree_const(const void *x); · 175 unmodified lines
176extern char *kstrdup(const char *s, gfp_t gfp) __malloc;176extern char *kstrdup(const char *s, gfp_t gfp) __malloc;
177extern const char *kstrdup_const(const char *s, gfp_t gfp);177extern const char *kstrdup_const(const char *s, gfp_t gfp);
178extern char *kstrndup(const char *s, size_t len, gfp_t gfp);178extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
179extern void *kmemdup(const void *src, size_t len, gfp_t gfp);179extern void *kmemdup(const void *src, size_t len, gfp_t gfp) __realloc_size(2);
180extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);180extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);
181 181
182extern char **argv_split(gfp_t gfp, const char *str, int *argcp);182extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
init/Kconfig+12−3
@@ -159,10 +159,12 @@ config WERROR · 158 unmodified lines
159 help159 help
160 A kernel build should not cause any compiler warnings, and this160 A kernel build should not cause any compiler warnings, and this
161 enables the '-Werror' (for C) and '-Dwarnings' (for Rust) flags161 enables the '-Werror' (for C) and '-Dwarnings' (for Rust) flags
162 to enforce that rule by default.162 to enforce that rule by default. Certain warnings from other tools
163 such as the linker may be upgraded to errors with this option as
164 well.
163 165
164 However, if you have a new (or very old) compiler with odd and166 However, if you have a new (or very old) compiler or linker with odd
165 unusual warnings, or you have some architecture with problems,167 and unusual warnings, or you have some architecture with problems,
166 you may need to disable this config option in order to168 you may need to disable this config option in order to
167 successfully build the kernel.169 successfully build the kernel.
168 170
@@ -1454,6 +1456,13 @@ config LD_ORPHAN_WARN · 1285 unmodified lines
1454 def_bool y1456 def_bool y
1455 depends on ARCH_WANT_LD_ORPHAN_WARN1457 depends on ARCH_WANT_LD_ORPHAN_WARN
1456 depends on $(ld-option,--orphan-handling=warn)1458 depends on $(ld-option,--orphan-handling=warn)
1459 depends on $(ld-option,--orphan-handling=error)
1460
1461config LD_ORPHAN_WARN_LEVEL
1462 string
1463 depends on LD_ORPHAN_WARN
1464 default "error" if WERROR
1465 default "warn"
1457 1466
1458config SYSCTL1467config SYSCTL
1459 bool1468 bool
kernel/cred.c+7−8
@@ -701,9 +701,9 @@ void __init cred_init(void) · 700 unmodified lines
701 * override a task's own credentials so that work can be done on behalf of that701 * override a task's own credentials so that work can be done on behalf of that
702 * task that requires a different subjective context.702 * task that requires a different subjective context.
703 *703 *
704 * @daemon is used to provide a base for the security record, but can be NULL.704 * @daemon is used to provide a base cred, with the security data derived from
705 * If @daemon is supplied, then the security data will be derived from that;705 * that; if this is "&init_task", they'll be set to 0, no groups, full
706 * otherwise they'll be set to 0 and no groups, full capabilities and no keys.706 * capabilities, and no keys.
707 *707 *
708 * The caller may change these controls afterwards if desired.708 * The caller may change these controls afterwards if desired.
709 *709 *
@@ -714,17 +714,16 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon) · 4 unmodified lines
714 const struct cred *old;714 const struct cred *old;
715 struct cred *new;715 struct cred *new;
716 716
717 if (WARN_ON_ONCE(!daemon))
718 return NULL;
719
717 new = kmem_cache_alloc(cred_jar, GFP_KERNEL);720 new = kmem_cache_alloc(cred_jar, GFP_KERNEL);
718 if (!new)721 if (!new)
719 return NULL;722 return NULL;
720 723
721 kdebug("prepare_kernel_cred() alloc %p", new);724 kdebug("prepare_kernel_cred() alloc %p", new);
722 725
723 if (daemon)726 old = get_task_cred(daemon);
724 old = get_task_cred(daemon);
725 else
726 old = get_cred(&init_cred);
727
728 validate_creds(old);727 validate_creds(old);
729 728
730 *new = *old;729 *new = *old;
kernel/exit.c+60−0
@@ -67,11 +67,58 @@ · 66 unmodified lines
67#include <linux/io_uring.h>67#include <linux/io_uring.h>
68#include <linux/kprobes.h>68#include <linux/kprobes.h>
69#include <linux/rethook.h>69#include <linux/rethook.h>
70#include <linux/sysfs.h>
70 71
71#include <linux/uaccess.h>72#include <linux/uaccess.h>
72#include <asm/unistd.h>73#include <asm/unistd.h>
73#include <asm/mmu_context.h>74#include <asm/mmu_context.h>
74 75
76/*
77 * The default value should be high enough to not crash a system that randomly
78 * crashes its kernel from time to time, but low enough to at least not permit
79 * overflowing 32-bit refcounts or the ldsem writer count.
80 */
81static unsigned int oops_limit = 10000;
82
83#ifdef CONFIG_SYSCTL
84static struct ctl_table kern_exit_table[] = {
85 {
86 .procname = "oops_limit",
87 .data = &oops_limit,
88 .maxlen = sizeof(oops_limit),
89 .mode = 0644,
90 .proc_handler = proc_douintvec,
91 },
92 { }
93};
94
95static __init int kernel_exit_sysctls_init(void)
96{
97 register_sysctl_init("kernel", kern_exit_table);
98 return 0;
99}
100late_initcall(kernel_exit_sysctls_init);
101#endif
102
103static atomic_t oops_count = ATOMIC_INIT(0);
104
105#ifdef CONFIG_SYSFS
106static ssize_t oops_count_show(struct kobject *kobj, struct kobj_attribute *attr,
107 char *page)
108{
109 return sysfs_emit(page, "%d\n", atomic_read(&oops_count));
110}
111
112static struct kobj_attribute oops_count_attr = __ATTR_RO(oops_count);
113
114static __init int kernel_exit_sysfs_init(void)
115{
116 sysfs_add_file_to_group(kernel_kobj, &oops_count_attr.attr, NULL);
117 return 0;
118}
119late_initcall(kernel_exit_sysfs_init);
120#endif
121
75static void __unhash_process(struct task_struct *p, bool group_dead)122static void __unhash_process(struct task_struct *p, bool group_dead)
76{123{
77 nr_threads--;124 nr_threads--;
@@ -897,6 +944,19 @@ void __noreturn make_task_dead(int signr) · 819 unmodified lines
897 preempt_count_set(PREEMPT_ENABLED);944 preempt_count_set(PREEMPT_ENABLED);
898 }945 }
899 946
947 /*
948 * Every time the system oopses, if the oops happens while a reference
949 * to an object was held, the reference leaks.
950 * If the oops doesn't also leak memory, repeated oopsing can cause
951 * reference counters to wrap around (if they're not using refcount_t).
952 * This means that repeated oopsing can make unexploitable-looking bugs
953 * exploitable through repeated oopsing.
954 * To make sure this can't happen, place an upper bound on how often the
955 * kernel may oops without panic().
956 */
957 if (atomic_inc_return(&oops_count) >= READ_ONCE(oops_limit) && oops_limit)
958 panic("Oopsed too often (kernel.oops_limit is %d)", oops_limit);
959
900 /*960 /*
901 * We're taking recursive faults here in make_task_dead. Safest is to just961 * We're taking recursive faults here in make_task_dead. Safest is to just
902 * leave this task alone and wait for reboot.962 * leave this task alone and wait for reboot.
kernel/kcsan/report.c+1−2
@@ -492,8 +492,7 @@ static void print_report(enum kcsan_value_change value_change, · 491 unmodified lines
492 dump_stack_print_info(KERN_DEFAULT);492 dump_stack_print_info(KERN_DEFAULT);
493 pr_err("==================================================================\n");493 pr_err("==================================================================\n");
494 494
495 if (panic_on_warn)495 check_panic_on_warn("KCSAN");
496 panic("panic_on_warn set ...\n");
497}496}
498 497
499static void release_report(unsigned long *flags, struct other_info *other_info)498static void release_report(unsigned long *flags, struct other_info *other_info)
kernel/panic.c+42−3
@@ -33,6 +33,7 @@ · 32 unmodified lines
33#include <linux/bug.h>33#include <linux/bug.h>
34#include <linux/ratelimit.h>34#include <linux/ratelimit.h>
35#include <linux/debugfs.h>35#include <linux/debugfs.h>
36#include <linux/sysfs.h>
36#include <trace/events/error_report.h>37#include <trace/events/error_report.h>
37#include <asm/sections.h>38#include <asm/sections.h>
38 39
@@ -59,6 +60,7 @@ bool crash_kexec_post_notifiers; · 20 unmodified lines
59int panic_on_warn __read_mostly;60int panic_on_warn __read_mostly;
60unsigned long panic_on_taint;61unsigned long panic_on_taint;
61bool panic_on_taint_nousertaint = false;62bool panic_on_taint_nousertaint = false;
63static unsigned int warn_limit __read_mostly;
62 64
63int panic_timeout = CONFIG_PANIC_TIMEOUT;65int panic_timeout = CONFIG_PANIC_TIMEOUT;
64EXPORT_SYMBOL_GPL(panic_timeout);66EXPORT_SYMBOL_GPL(panic_timeout);
@@ -76,8 +78,9 @@ ATOMIC_NOTIFIER_HEAD(panic_notifier_list); · 11 unmodified lines
76 78
77EXPORT_SYMBOL(panic_notifier_list);79EXPORT_SYMBOL(panic_notifier_list);
78 80
79#if defined(CONFIG_SMP) && defined(CONFIG_SYSCTL)81#ifdef CONFIG_SYSCTL
80static struct ctl_table kern_panic_table[] = {82static struct ctl_table kern_panic_table[] = {
83#ifdef CONFIG_SMP
81 {84 {
82 .procname = "oops_all_cpu_backtrace",85 .procname = "oops_all_cpu_backtrace",
83 .data = &sysctl_oops_all_cpu_backtrace,86 .data = &sysctl_oops_all_cpu_backtrace,
@@ -87,6 +90,14 @@ static struct ctl_table kern_panic_table[] = { · 3 unmodified lines
87 .extra1 = SYSCTL_ZERO,90 .extra1 = SYSCTL_ZERO,
88 .extra2 = SYSCTL_ONE,91 .extra2 = SYSCTL_ONE,
89 },92 },
93#endif
94 {
95 .procname = "warn_limit",
96 .data = &warn_limit,
97 .maxlen = sizeof(warn_limit),
98 .mode = 0644,
99 .proc_handler = proc_douintvec,
100 },
90 { }101 { }
91};102};
92 103
@@ -98,6 +109,25 @@ static __init int kernel_panic_sysctls_init(void) · 5 unmodified lines
98late_initcall(kernel_panic_sysctls_init);109late_initcall(kernel_panic_sysctls_init);
99#endif110#endif
100 111
112static atomic_t warn_count = ATOMIC_INIT(0);
113
114#ifdef CONFIG_SYSFS
115static ssize_t warn_count_show(struct kobject *kobj, struct kobj_attribute *attr,
116 char *page)
117{
118 return sysfs_emit(page, "%d\n", atomic_read(&warn_count));
119}
120
121static struct kobj_attribute warn_count_attr = __ATTR_RO(warn_count);
122
123static __init int kernel_panic_sysfs_init(void)
124{
125 sysfs_add_file_to_group(kernel_kobj, &warn_count_attr.attr, NULL);
126 return 0;
127}
128late_initcall(kernel_panic_sysfs_init);
129#endif
130
101static long no_blink(int state)131static long no_blink(int state)
102{132{
103 return 0;133 return 0;
@@ -200,6 +230,16 @@ static void panic_print_sys_info(bool console_flush) · 96 unmodified lines
200 ftrace_dump(DUMP_ALL);230 ftrace_dump(DUMP_ALL);
201}231}
202 232
233void check_panic_on_warn(const char *origin)
234{
235 if (panic_on_warn)
236 panic("%s: panic_on_warn set ...\n", origin);
237
238 if (atomic_inc_return(&warn_count) >= READ_ONCE(warn_limit) && warn_limit)
239 panic("%s: system warned too often (kernel.warn_limit is %d)",
240 origin, warn_limit);
241}
242
203/**243/**
204 * panic - halt the system244 * panic - halt the system
205 * @fmt: The text string to print245 * @fmt: The text string to print
@@ -618,8 +658,7 @@ void __warn(const char *file, int line, void *caller, unsigned taint, · 412 unmodified lines
618 if (regs)658 if (regs)
619 show_regs(regs);659 show_regs(regs);
620 660
621 if (panic_on_warn)661 check_panic_on_warn("kernel");
622 panic("panic_on_warn set ...\n");
623 662
624 if (!regs)663 if (!regs)
625 dump_stack();664 dump_stack();
kernel/sched/core.c+1−2
@@ -5782,8 +5782,7 @@ static noinline void __schedule_bug(struct task_struct *prev) · 5781 unmodified lines
5782 pr_err("Preemption disabled at:");5782 pr_err("Preemption disabled at:");
5783 print_ip_sym(KERN_ERR, preempt_disable_ip);5783 print_ip_sym(KERN_ERR, preempt_disable_ip);
5784 }5784 }
5785 if (panic_on_warn)5785 check_panic_on_warn("scheduling while atomic");
5786 panic("scheduling while atomic\n");
5787 5786
5788 dump_stack();5787 dump_stack();
5789 add_taint(TAINT_WARN, LOCKDEP_STILL_OK);5788 add_taint(TAINT_WARN, LOCKDEP_STILL_OK);
kernel/signal.c+1−0
@@ -2693,6 +2693,7 @@ relock: · 2692 unmodified lines
2693 /* Has this task already been marked for death? */2693 /* Has this task already been marked for death? */
2694 if ((signal->flags & SIGNAL_GROUP_EXIT) ||2694 if ((signal->flags & SIGNAL_GROUP_EXIT) ||
2695 signal->group_exec_task) {2695 signal->group_exec_task) {
2696 clear_siginfo(&ksig->info);
2696 ksig->info.si_signo = signr = SIGKILL;2697 ksig->info.si_signo = signr = SIGKILL;
2697 sigdelset(&current->pending.signal, SIGKILL);2698 sigdelset(&current->pending.signal, SIGKILL);
2698 trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO,2699 trace_signal_deliver(SIGKILL, SEND_SIG_NOINFO,
lib/Kconfig.debug+16−12
@@ -2234,9 +2234,6 @@ config STRING_SELFTEST · 2233 unmodified lines
2234config TEST_STRING_HELPERS2234config TEST_STRING_HELPERS
2235 tristate "Test functions located in the string_helpers module at runtime"2235 tristate "Test functions located in the string_helpers module at runtime"
2236 2236
2237config TEST_STRSCPY
2238 tristate "Test strscpy*() family of functions at runtime"
2239
2240config TEST_KSTRTOX2237config TEST_KSTRTOX
2241 tristate "Test kstrto*() family of functions at runtime"2238 tristate "Test kstrto*() family of functions at runtime"
2242 2239
@@ -2271,15 +2268,6 @@ config TEST_RHASHTABLE · 28 unmodified lines
2271 2268
2272 If unsure, say N.2269 If unsure, say N.
2273 2270
2274config TEST_SIPHASH
2275 tristate "Perform selftest on siphash functions"
2276 help
2277 Enable this option to test the kernel's siphash (<linux/siphash.h>) hash
2278 functions on boot (or module load).
2279
2280 This is intended to help people writing architecture-specific
2281 optimized versions. If unsure, say N.
2282
2283config TEST_IDA2271config TEST_IDA
2284 tristate "Perform selftest on IDA functions"2272 tristate "Perform selftest on IDA functions"
2285 2273
@@ -2607,6 +2595,22 @@ config HW_BREAKPOINT_KUNIT_TEST · 321 unmodified lines
2607 2595
2608 If unsure, say N.2596 If unsure, say N.
2609 2597
2598config STRSCPY_KUNIT_TEST
2599 tristate "Test strscpy*() family of functions at runtime" if !KUNIT_ALL_TESTS
2600 depends on KUNIT
2601 default KUNIT_ALL_TESTS
2602
2603config SIPHASH_KUNIT_TEST
2604 tristate "Perform selftest on siphash functions" if !KUNIT_ALL_TESTS
2605 depends on KUNIT
2606 default KUNIT_ALL_TESTS
2607 help
2608 Enable this option to test the kernel's siphash (<linux/siphash.h>) hash
2609 functions on boot (or module load).
2610
2611 This is intended to help people writing architecture-specific
2612 optimized versions. If unsure, say N.
2613
2610config TEST_UDELAY2614config TEST_UDELAY
2611 tristate "udelay test driver"2615 tristate "udelay test driver"
2612 help2616 help
lib/Makefile+5−2
@@ -62,7 +62,6 @@ obj-$(CONFIG_TEST_BITOPS) += test_bitops.o · 61 unmodified lines
62CFLAGS_test_bitops.o += -Werror62CFLAGS_test_bitops.o += -Werror
63obj-$(CONFIG_CPUMASK_KUNIT_TEST) += cpumask_kunit.o63obj-$(CONFIG_CPUMASK_KUNIT_TEST) += cpumask_kunit.o
64obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o64obj-$(CONFIG_TEST_SYSCTL) += test_sysctl.o
65obj-$(CONFIG_TEST_SIPHASH) += test_siphash.o
66obj-$(CONFIG_HASH_KUNIT_TEST) += test_hash.o65obj-$(CONFIG_HASH_KUNIT_TEST) += test_hash.o
67obj-$(CONFIG_TEST_IDA) += test_ida.o66obj-$(CONFIG_TEST_IDA) += test_ida.o
68obj-$(CONFIG_TEST_UBSAN) += test_ubsan.o67obj-$(CONFIG_TEST_UBSAN) += test_ubsan.o
@@ -82,7 +81,6 @@ obj-$(CONFIG_TEST_DYNAMIC_DEBUG) += test_dynamic_debug.o · 13 unmodified lines
82obj-$(CONFIG_TEST_PRINTF) += test_printf.o81obj-$(CONFIG_TEST_PRINTF) += test_printf.o
83obj-$(CONFIG_TEST_SCANF) += test_scanf.o82obj-$(CONFIG_TEST_SCANF) += test_scanf.o
84obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o83obj-$(CONFIG_TEST_BITMAP) += test_bitmap.o
85obj-$(CONFIG_TEST_STRSCPY) += test_strscpy.o
86obj-$(CONFIG_TEST_UUID) += test_uuid.o84obj-$(CONFIG_TEST_UUID) += test_uuid.o
87obj-$(CONFIG_TEST_XARRAY) += test_xarray.o85obj-$(CONFIG_TEST_XARRAY) += test_xarray.o
88obj-$(CONFIG_TEST_MAPLE_TREE) += test_maple_tree.o86obj-$(CONFIG_TEST_MAPLE_TREE) += test_maple_tree.o
@@ -377,10 +375,15 @@ obj-$(CONFIG_CMDLINE_KUNIT_TEST) += cmdline_kunit.o · 288 unmodified lines
377obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o375obj-$(CONFIG_SLUB_KUNIT_TEST) += slub_kunit.o
378obj-$(CONFIG_MEMCPY_KUNIT_TEST) += memcpy_kunit.o376obj-$(CONFIG_MEMCPY_KUNIT_TEST) += memcpy_kunit.o
379obj-$(CONFIG_IS_SIGNED_TYPE_KUNIT_TEST) += is_signed_type_kunit.o377obj-$(CONFIG_IS_SIGNED_TYPE_KUNIT_TEST) += is_signed_type_kunit.o
378CFLAGS_overflow_kunit.o = $(call cc-disable-warning, tautological-constant-out-of-range-compare)
380obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o379obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o
381CFLAGS_stackinit_kunit.o += $(call cc-disable-warning, switch-unreachable)380CFLAGS_stackinit_kunit.o += $(call cc-disable-warning, switch-unreachable)
382obj-$(CONFIG_STACKINIT_KUNIT_TEST) += stackinit_kunit.o381obj-$(CONFIG_STACKINIT_KUNIT_TEST) += stackinit_kunit.o
382CFLAGS_fortify_kunit.o += $(call cc-disable-warning, unsequenced)
383CFLAGS_fortify_kunit.o += $(DISABLE_STRUCTLEAK_PLUGIN)
383obj-$(CONFIG_FORTIFY_KUNIT_TEST) += fortify_kunit.o384obj-$(CONFIG_FORTIFY_KUNIT_TEST) += fortify_kunit.o
385obj-$(CONFIG_STRSCPY_KUNIT_TEST) += strscpy_kunit.o
386obj-$(CONFIG_SIPHASH_KUNIT_TEST) += siphash_kunit.o
384 387
385obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o388obj-$(CONFIG_GENERIC_LIB_DEVMEM_IS_ALLOWED) += devmem_is_allowed.o
386 389
lib/fortify_kunit.c+255−0
@@ -16,7 +16,10 @@ · 15 unmodified lines
16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt16#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 17
18#include <kunit/test.h>18#include <kunit/test.h>
19#include <linux/device.h>
20#include <linux/slab.h>
19#include <linux/string.h>21#include <linux/string.h>
22#include <linux/vmalloc.h>
20 23
21static const char array_of_10[] = "this is 10";24static const char array_of_10[] = "this is 10";
22static const char *ptr_of_11 = "this is 11!";25static const char *ptr_of_11 = "this is 11!";
@@ -60,9 +63,261 @@ static void control_flow_split_test(struct kunit *test) · 37 unmodified lines
60 KUNIT_EXPECT_EQ(test, want_minus_one(pick), SIZE_MAX);63 KUNIT_EXPECT_EQ(test, want_minus_one(pick), SIZE_MAX);
61}64}
62 65
66#define KUNIT_EXPECT_BOS(test, p, expected, name) \
67 KUNIT_EXPECT_EQ_MSG(test, __builtin_object_size(p, 1), \
68 expected, \
69 "__alloc_size() not working with __bos on " name "\n")
70
71#if !__has_builtin(__builtin_dynamic_object_size)
72#define KUNIT_EXPECT_BDOS(test, p, expected, name) \
73 /* Silence "unused variable 'expected'" warning. */ \
74 KUNIT_EXPECT_EQ(test, expected, expected)
75#else
76#define KUNIT_EXPECT_BDOS(test, p, expected, name) \
77 KUNIT_EXPECT_EQ_MSG(test, __builtin_dynamic_object_size(p, 1), \
78 expected, \
79 "__alloc_size() not working with __bdos on " name "\n")
80#endif
81
82/* If the execpted size is a constant value, __bos can see it. */
83#define check_const(_expected, alloc, free) do { \
84 size_t expected = (_expected); \
85 void *p = alloc; \
86 KUNIT_EXPECT_TRUE_MSG(test, p != NULL, #alloc " failed?!\n"); \
87 KUNIT_EXPECT_BOS(test, p, expected, #alloc); \
88 KUNIT_EXPECT_BDOS(test, p, expected, #alloc); \
89 free; \
90} while (0)
91
92/* If the execpted size is NOT a constant value, __bos CANNOT see it. */
93#define check_dynamic(_expected, alloc, free) do { \
94 size_t expected = (_expected); \
95 void *p = alloc; \
96 KUNIT_EXPECT_TRUE_MSG(test, p != NULL, #alloc " failed?!\n"); \
97 KUNIT_EXPECT_BOS(test, p, SIZE_MAX, #alloc); \
98 KUNIT_EXPECT_BDOS(test, p, expected, #alloc); \
99 free; \
100} while (0)
101
102/* Assortment of constant-value kinda-edge cases. */
103#define CONST_TEST_BODY(TEST_alloc) do { \
104 /* Special-case vmalloc()-family to skip 0-sized allocs. */ \
105 if (strcmp(#TEST_alloc, "TEST_vmalloc") != 0) \
106 TEST_alloc(check_const, 0, 0); \
107 TEST_alloc(check_const, 1, 1); \
108 TEST_alloc(check_const, 128, 128); \
109 TEST_alloc(check_const, 1023, 1023); \
110 TEST_alloc(check_const, 1025, 1025); \
111 TEST_alloc(check_const, 4096, 4096); \
112 TEST_alloc(check_const, 4097, 4097); \
113} while (0)
114
115static volatile size_t zero_size;
116static volatile size_t unknown_size = 50;
117
118#if !__has_builtin(__builtin_dynamic_object_size)
119#define DYNAMIC_TEST_BODY(TEST_alloc) \
120 kunit_skip(test, "Compiler is missing __builtin_dynamic_object_size() support\n")
121#else
122#define DYNAMIC_TEST_BODY(TEST_alloc) do { \
123 size_t size = unknown_size; \
124 \
125 /* \
126 * Expected size is "size" in each test, before it is then \
127 * internally incremented in each test. Requires we disable \
128 * -Wunsequenced. \
129 */ \
130 TEST_alloc(check_dynamic, size, size++); \
131 /* Make sure incrementing actually happened. */ \
132 KUNIT_EXPECT_NE(test, size, unknown_size); \
133} while (0)
134#endif
135
136#define DEFINE_ALLOC_SIZE_TEST_PAIR(allocator) \
137static void alloc_size_##allocator##_const_test(struct kunit *test) \
138{ \
139 CONST_TEST_BODY(TEST_##allocator); \
140} \
141static void alloc_size_##allocator##_dynamic_test(struct kunit *test) \
142{ \
143 DYNAMIC_TEST_BODY(TEST_##allocator); \
144}
145
146#define TEST_kmalloc(checker, expected_size, alloc_size) do { \
147 gfp_t gfp = GFP_KERNEL | __GFP_NOWARN; \
148 void *orig; \
149 size_t len; \
150 \
151 checker(expected_size, kmalloc(alloc_size, gfp), \
152 kfree(p)); \
153 checker(expected_size, \
154 kmalloc_node(alloc_size, gfp, NUMA_NO_NODE), \
155 kfree(p)); \
156 checker(expected_size, kzalloc(alloc_size, gfp), \
157 kfree(p)); \
158 checker(expected_size, \
159 kzalloc_node(alloc_size, gfp, NUMA_NO_NODE), \
160 kfree(p)); \
161 checker(expected_size, kcalloc(1, alloc_size, gfp), \
162 kfree(p)); \
163 checker(expected_size, kcalloc(alloc_size, 1, gfp), \
164 kfree(p)); \
165 checker(expected_size, \
166 kcalloc_node(1, alloc_size, gfp, NUMA_NO_NODE), \
167 kfree(p)); \
168 checker(expected_size, \
169 kcalloc_node(alloc_size, 1, gfp, NUMA_NO_NODE), \
170 kfree(p)); \
171 checker(expected_size, kmalloc_array(1, alloc_size, gfp), \
172 kfree(p)); \
173 checker(expected_size, kmalloc_array(alloc_size, 1, gfp), \
174 kfree(p)); \
175 checker(expected_size, \
176 kmalloc_array_node(1, alloc_size, gfp, NUMA_NO_NODE), \
177 kfree(p)); \
178 checker(expected_size, \
179 kmalloc_array_node(alloc_size, 1, gfp, NUMA_NO_NODE), \
180 kfree(p)); \
181 checker(expected_size, __kmalloc(alloc_size, gfp), \
182 kfree(p)); \
183 checker(expected_size, \
184 __kmalloc_node(alloc_size, gfp, NUMA_NO_NODE), \
185 kfree(p)); \
186 \
187 orig = kmalloc(alloc_size, gfp); \
188 KUNIT_EXPECT_TRUE(test, orig != NULL); \
189 checker((expected_size) * 2, \
190 krealloc(orig, (alloc_size) * 2, gfp), \
191 kfree(p)); \
192 orig = kmalloc(alloc_size, gfp); \
193 KUNIT_EXPECT_TRUE(test, orig != NULL); \
194 checker((expected_size) * 2, \
195 krealloc_array(orig, 1, (alloc_size) * 2, gfp), \
196 kfree(p)); \
197 orig = kmalloc(alloc_size, gfp); \
198 KUNIT_EXPECT_TRUE(test, orig != NULL); \
199 checker((expected_size) * 2, \
200 krealloc_array(orig, (alloc_size) * 2, 1, gfp), \
201 kfree(p)); \
202 \
203 len = 11; \
204 /* Using memdup() with fixed size, so force unknown length. */ \
205 if (!__builtin_constant_p(expected_size)) \
206 len += zero_size; \
207 checker(len, kmemdup("hello there", len, gfp), kfree(p)); \
208} while (0)
209DEFINE_ALLOC_SIZE_TEST_PAIR(kmalloc)
210
211/* Sizes are in pages, not bytes. */
212#define TEST_vmalloc(checker, expected_pages, alloc_pages) do { \
213 gfp_t gfp = GFP_KERNEL | __GFP_NOWARN; \
214 checker((expected_pages) * PAGE_SIZE, \
215 vmalloc((alloc_pages) * PAGE_SIZE), vfree(p)); \
216 checker((expected_pages) * PAGE_SIZE, \
217 vzalloc((alloc_pages) * PAGE_SIZE), vfree(p)); \
218 checker((expected_pages) * PAGE_SIZE, \
219 __vmalloc((alloc_pages) * PAGE_SIZE, gfp), vfree(p)); \
220} while (0)
221DEFINE_ALLOC_SIZE_TEST_PAIR(vmalloc)
222
223/* Sizes are in pages (and open-coded for side-effects), not bytes. */
224#define TEST_kvmalloc(checker, expected_pages, alloc_pages) do { \
225 gfp_t gfp = GFP_KERNEL | __GFP_NOWARN; \
226 size_t prev_size; \
227 void *orig; \
228 \
229 checker((expected_pages) * PAGE_SIZE, \
230 kvmalloc((alloc_pages) * PAGE_SIZE, gfp), \
231 vfree(p)); \
232 checker((expected_pages) * PAGE_SIZE, \
233 kvmalloc_node((alloc_pages) * PAGE_SIZE, gfp, NUMA_NO_NODE), \
234 vfree(p)); \
235 checker((expected_pages) * PAGE_SIZE, \
236 kvzalloc((alloc_pages) * PAGE_SIZE, gfp), \
237 vfree(p)); \
238 checker((expected_pages) * PAGE_SIZE, \
239 kvzalloc_node((alloc_pages) * PAGE_SIZE, gfp, NUMA_NO_NODE), \
240 vfree(p)); \
241 checker((expected_pages) * PAGE_SIZE, \
242 kvcalloc(1, (alloc_pages) * PAGE_SIZE, gfp), \
243 vfree(p)); \
244 checker((expected_pages) * PAGE_SIZE, \
245 kvcalloc((alloc_pages) * PAGE_SIZE, 1, gfp), \
246 vfree(p)); \
247 checker((expected_pages) * PAGE_SIZE, \
248 kvmalloc_array(1, (alloc_pages) * PAGE_SIZE, gfp), \
249 vfree(p)); \
250 checker((expected_pages) * PAGE_SIZE, \
251 kvmalloc_array((alloc_pages) * PAGE_SIZE, 1, gfp), \
252 vfree(p)); \
253 \
254 prev_size = (expected_pages) * PAGE_SIZE; \
255 orig = kvmalloc(prev_size, gfp); \
256 KUNIT_EXPECT_TRUE(test, orig != NULL); \
257 checker(((expected_pages) * PAGE_SIZE) * 2, \
258 kvrealloc(orig, prev_size, \
259 ((alloc_pages) * PAGE_SIZE) * 2, gfp), \
260 kvfree(p)); \
261} while (0)
262DEFINE_ALLOC_SIZE_TEST_PAIR(kvmalloc)
263
264#define TEST_devm_kmalloc(checker, expected_size, alloc_size) do { \
265 gfp_t gfp = GFP_KERNEL | __GFP_NOWARN; \
266 const char dev_name[] = "fortify-test"; \
267 struct device *dev; \
268 void *orig; \
269 size_t len; \
270 \
271 /* Create dummy device for devm_kmalloc()-family tests. */ \
272 dev = root_device_register(dev_name); \
273 KUNIT_ASSERT_FALSE_MSG(test, IS_ERR(dev), \
274 "Cannot register test device\n"); \
275 \
276 checker(expected_size, devm_kmalloc(dev, alloc_size, gfp), \
277 devm_kfree(dev, p)); \
278 checker(expected_size, devm_kzalloc(dev, alloc_size, gfp), \
279 devm_kfree(dev, p)); \
280 checker(expected_size, \
281 devm_kmalloc_array(dev, 1, alloc_size, gfp), \
282 devm_kfree(dev, p)); \
283 checker(expected_size, \
284 devm_kmalloc_array(dev, alloc_size, 1, gfp), \
285 devm_kfree(dev, p)); \
286 checker(expected_size, \
287 devm_kcalloc(dev, 1, alloc_size, gfp), \
288 devm_kfree(dev, p)); \
289 checker(expected_size, \
290 devm_kcalloc(dev, alloc_size, 1, gfp), \
291 devm_kfree(dev, p)); \
292 \
293 orig = devm_kmalloc(dev, alloc_size, gfp); \
294 KUNIT_EXPECT_TRUE(test, orig != NULL); \
295 checker((expected_size) * 2, \
296 devm_krealloc(dev, orig, (alloc_size) * 2, gfp), \
297 devm_kfree(dev, p)); \
298 \
299 len = 4; \
300 /* Using memdup() with fixed size, so force unknown length. */ \
301 if (!__builtin_constant_p(expected_size)) \
302 len += zero_size; \
303 checker(len, devm_kmemdup(dev, "Ohai", len, gfp), \
304 devm_kfree(dev, p)); \
305 \
306 device_unregister(dev); \
307} while (0)
308DEFINE_ALLOC_SIZE_TEST_PAIR(devm_kmalloc)
309
63static struct kunit_case fortify_test_cases[] = {310static struct kunit_case fortify_test_cases[] = {
64 KUNIT_CASE(known_sizes_test),311 KUNIT_CASE(known_sizes_test),
65 KUNIT_CASE(control_flow_split_test),312 KUNIT_CASE(control_flow_split_test),
313 KUNIT_CASE(alloc_size_kmalloc_const_test),
314 KUNIT_CASE(alloc_size_kmalloc_dynamic_test),
315 KUNIT_CASE(alloc_size_vmalloc_const_test),
316 KUNIT_CASE(alloc_size_vmalloc_dynamic_test),
317 KUNIT_CASE(alloc_size_kvmalloc_const_test),
318 KUNIT_CASE(alloc_size_kvmalloc_dynamic_test),
319 KUNIT_CASE(alloc_size_devm_kmalloc_const_test),
320 KUNIT_CASE(alloc_size_devm_kmalloc_dynamic_test),
66 {}321 {}
67};322};
68 323
lib/memcpy_kunit.c+205−0
@@ -292,6 +292,208 @@ static void memset_test(struct kunit *test) · 291 unmodified lines
292#undef TEST_OP292#undef TEST_OP
293}293}
294 294
295static u8 large_src[1024];
296static u8 large_dst[2048];
297static const u8 large_zero[2048];
298
299static void set_random_nonzero(struct kunit *test, u8 *byte)
300{
301 int failed_rng = 0;
302
303 while (*byte == 0) {
304 get_random_bytes(byte, 1);
305 KUNIT_ASSERT_LT_MSG(test, failed_rng++, 100,
306 "Is the RNG broken?");
307 }
308}
309
310static void init_large(struct kunit *test)
311{
312
313 /* Get many bit patterns. */
314 get_random_bytes(large_src, ARRAY_SIZE(large_src));
315
316 /* Make sure we have non-zero edges. */
317 set_random_nonzero(test, &large_src[0]);
318 set_random_nonzero(test, &large_src[ARRAY_SIZE(large_src) - 1]);
319
320 /* Explicitly zero the entire destination. */
321 memset(large_dst, 0, ARRAY_SIZE(large_dst));
322}
323
324/*
325 * Instead of an indirect function call for "copy" or a giant macro,
326 * use a bool to pick memcpy or memmove.
327 */
328static void copy_large_test(struct kunit *test, bool use_memmove)
329{
330 init_large(test);
331
332 /* Copy a growing number of non-overlapping bytes ... */
333 for (int bytes = 1; bytes <= ARRAY_SIZE(large_src); bytes++) {
334 /* Over a shifting destination window ... */
335 for (int offset = 0; offset < ARRAY_SIZE(large_src); offset++) {
336 int right_zero_pos = offset + bytes;
337 int right_zero_size = ARRAY_SIZE(large_dst) - right_zero_pos;
338
339 /* Copy! */
340 if (use_memmove)
341 memmove(large_dst + offset, large_src, bytes);
342 else
343 memcpy(large_dst + offset, large_src, bytes);
344
345 /* Did we touch anything before the copy area? */
346 KUNIT_ASSERT_EQ_MSG(test,
347 memcmp(large_dst, large_zero, offset), 0,
348 "with size %d at offset %d", bytes, offset);
349 /* Did we touch anything after the copy area? */
350 KUNIT_ASSERT_EQ_MSG(test,
351 memcmp(&large_dst[right_zero_pos], large_zero, right_zero_size), 0,
352 "with size %d at offset %d", bytes, offset);
353
354 /* Are we byte-for-byte exact across the copy? */
355 KUNIT_ASSERT_EQ_MSG(test,
356 memcmp(large_dst + offset, large_src, bytes), 0,
357 "with size %d at offset %d", bytes, offset);
358
359 /* Zero out what we copied for the next cycle. */
360 memset(large_dst + offset, 0, bytes);
361 }
362 /* Avoid stall warnings if this loop gets slow. */
363 cond_resched();
364 }
365}
366
367static void memcpy_large_test(struct kunit *test)
368{
369 copy_large_test(test, false);
370}
371
372static void memmove_large_test(struct kunit *test)
373{
374 copy_large_test(test, true);
375}
376
377/*
378 * On the assumption that boundary conditions are going to be the most
379 * sensitive, instead of taking a full step (inc) each iteration,
380 * take single index steps for at least the first "inc"-many indexes
381 * from the "start" and at least the last "inc"-many indexes before
382 * the "end". When in the middle, take full "inc"-wide steps. For
383 * example, calling next_step(idx, 1, 15, 3) with idx starting at 0
384 * would see the following pattern: 1 2 3 4 7 10 11 12 13 14 15.
385 */
386static int next_step(int idx, int start, int end, int inc)
387{
388 start += inc;
389 end -= inc;
390
391 if (idx < start || idx + inc > end)
392 inc = 1;
393 return idx + inc;
394}
395
396static void inner_loop(struct kunit *test, int bytes, int d_off, int s_off)
397{
398 int left_zero_pos, left_zero_size;
399 int right_zero_pos, right_zero_size;
400 int src_pos, src_orig_pos, src_size;
401 int pos;
402
403 /* Place the source in the destination buffer. */
404 memcpy(&large_dst[s_off], large_src, bytes);
405
406 /* Copy to destination offset. */
407 memmove(&large_dst[d_off], &large_dst[s_off], bytes);
408
409 /* Make sure destination entirely matches. */
410 KUNIT_ASSERT_EQ_MSG(test, memcmp(&large_dst[d_off], large_src, bytes), 0,
411 "with size %d at src offset %d and dest offset %d",
412 bytes, s_off, d_off);
413
414 /* Calculate the expected zero spans. */
415 if (s_off < d_off) {
416 left_zero_pos = 0;
417 left_zero_size = s_off;
418
419 right_zero_pos = d_off + bytes;
420 right_zero_size = ARRAY_SIZE(large_dst) - right_zero_pos;
421
422 src_pos = s_off;
423 src_orig_pos = 0;
424 src_size = d_off - s_off;
425 } else {
426 left_zero_pos = 0;
427 left_zero_size = d_off;
428
429 right_zero_pos = s_off + bytes;
430 right_zero_size = ARRAY_SIZE(large_dst) - right_zero_pos;
431
432 src_pos = d_off + bytes;
433 src_orig_pos = src_pos - s_off;
434 src_size = right_zero_pos - src_pos;
435 }
436
437 /* Check non-overlapping source is unchanged.*/
438 KUNIT_ASSERT_EQ_MSG(test,
439 memcmp(&large_dst[src_pos], &large_src[src_orig_pos], src_size), 0,
440 "with size %d at src offset %d and dest offset %d",
441 bytes, s_off, d_off);
442
443 /* Check leading buffer contents are zero. */
444 KUNIT_ASSERT_EQ_MSG(test,
445 memcmp(&large_dst[left_zero_pos], large_zero, left_zero_size), 0,
446 "with size %d at src offset %d and dest offset %d",
447 bytes, s_off, d_off);
448 /* Check trailing buffer contents are zero. */
449 KUNIT_ASSERT_EQ_MSG(test,
450 memcmp(&large_dst[right_zero_pos], large_zero, right_zero_size), 0,
451 "with size %d at src offset %d and dest offset %d",
452 bytes, s_off, d_off);
453
454 /* Zero out everything not already zeroed.*/
455 pos = left_zero_pos + left_zero_size;
456 memset(&large_dst[pos], 0, right_zero_pos - pos);
457}
458
459static void memmove_overlap_test(struct kunit *test)
460{
461 /*
462 * Running all possible offset and overlap combinations takes a
463 * very long time. Instead, only check up to 128 bytes offset
464 * into the destination buffer (which should result in crossing
465 * cachelines), with a step size of 1 through 7 to try to skip some
466 * redundancy.
467 */
468 static const int offset_max = 128; /* less than ARRAY_SIZE(large_src); */
469 static const int bytes_step = 7;
470 static const int window_step = 7;
471
472 static const int bytes_start = 1;
473 static const int bytes_end = ARRAY_SIZE(large_src) + 1;
474
475 init_large(test);
476
477 /* Copy a growing number of overlapping bytes ... */
478 for (int bytes = bytes_start; bytes < bytes_end;
479 bytes = next_step(bytes, bytes_start, bytes_end, bytes_step)) {
480
481 /* Over a shifting destination window ... */
482 for (int d_off = 0; d_off < offset_max; d_off++) {
483 int s_start = max(d_off - bytes, 0);
484 int s_end = min_t(int, d_off + bytes, ARRAY_SIZE(large_src));
485
486 /* Over a shifting source window ... */
487 for (int s_off = s_start; s_off < s_end;
488 s_off = next_step(s_off, s_start, s_end, window_step))
489 inner_loop(test, bytes, d_off, s_off);
490
491 /* Avoid stall warnings. */
492 cond_resched();
493 }
494 }
495}
496
295static void strtomem_test(struct kunit *test)497static void strtomem_test(struct kunit *test)
296{498{
297 static const char input[sizeof(unsigned long)] = "hi";499 static const char input[sizeof(unsigned long)] = "hi";
@@ -347,7 +549,10 @@ static void strtomem_test(struct kunit *test) · 49 unmodified lines
347static struct kunit_case memcpy_test_cases[] = {549static struct kunit_case memcpy_test_cases[] = {
348 KUNIT_CASE(memset_test),550 KUNIT_CASE(memset_test),
349 KUNIT_CASE(memcpy_test),551 KUNIT_CASE(memcpy_test),
552 KUNIT_CASE(memcpy_large_test),
350 KUNIT_CASE(memmove_test),553 KUNIT_CASE(memmove_test),
554 KUNIT_CASE(memmove_large_test),
555 KUNIT_CASE(memmove_overlap_test),
351 KUNIT_CASE(strtomem_test),556 KUNIT_CASE(strtomem_test),
352 {}557 {}
353};558};
lib/overflow_kunit.c+381−0
@@ -736,6 +736,384 @@ static void overflow_size_helpers_test(struct kunit *test) · 735 unmodified lines
736#undef check_one_size_helper736#undef check_one_size_helper
737}737}
738 738
739static void overflows_type_test(struct kunit *test)
740{
741 int count = 0;
742 unsigned int var;
743
744#define __TEST_OVERFLOWS_TYPE(func, arg1, arg2, of) do { \
745 bool __of = func(arg1, arg2); \
746 KUNIT_EXPECT_EQ_MSG(test, __of, of, \
747 "expected " #func "(" #arg1 ", " #arg2 " to%s overflow\n",\
748 of ? "" : " not"); \
749 count++; \
750} while (0)
751
752/* Args are: first type, second type, value, overflow expected */
753#define TEST_OVERFLOWS_TYPE(__t1, __t2, v, of) do { \
754 __t1 t1 = (v); \
755 __t2 t2; \
756 __TEST_OVERFLOWS_TYPE(__overflows_type, t1, t2, of); \
757 __TEST_OVERFLOWS_TYPE(__overflows_type, t1, __t2, of); \
758 __TEST_OVERFLOWS_TYPE(__overflows_type_constexpr, t1, t2, of); \
759 __TEST_OVERFLOWS_TYPE(__overflows_type_constexpr, t1, __t2, of);\
760} while (0)
761
762 TEST_OVERFLOWS_TYPE(u8, u8, U8_MAX, false);
763 TEST_OVERFLOWS_TYPE(u8, u16, U8_MAX, false);
764 TEST_OVERFLOWS_TYPE(u8, s8, U8_MAX, true);
765 TEST_OVERFLOWS_TYPE(u8, s8, S8_MAX, false);
766 TEST_OVERFLOWS_TYPE(u8, s8, (u8)S8_MAX + 1, true);
767 TEST_OVERFLOWS_TYPE(u8, s16, U8_MAX, false);
768 TEST_OVERFLOWS_TYPE(s8, u8, S8_MAX, false);
769 TEST_OVERFLOWS_TYPE(s8, u8, -1, true);
770 TEST_OVERFLOWS_TYPE(s8, u8, S8_MIN, true);
771 TEST_OVERFLOWS_TYPE(s8, u16, S8_MAX, false);
772 TEST_OVERFLOWS_TYPE(s8, u16, -1, true);
773 TEST_OVERFLOWS_TYPE(s8, u16, S8_MIN, true);
774 TEST_OVERFLOWS_TYPE(s8, u32, S8_MAX, false);
775 TEST_OVERFLOWS_TYPE(s8, u32, -1, true);
776 TEST_OVERFLOWS_TYPE(s8, u32, S8_MIN, true);
777#if BITS_PER_LONG == 64
778 TEST_OVERFLOWS_TYPE(s8, u64, S8_MAX, false);
779 TEST_OVERFLOWS_TYPE(s8, u64, -1, true);
780 TEST_OVERFLOWS_TYPE(s8, u64, S8_MIN, true);
781#endif
782 TEST_OVERFLOWS_TYPE(s8, s8, S8_MAX, false);
783 TEST_OVERFLOWS_TYPE(s8, s8, S8_MIN, false);
784 TEST_OVERFLOWS_TYPE(s8, s16, S8_MAX, false);
785 TEST_OVERFLOWS_TYPE(s8, s16, S8_MIN, false);
786 TEST_OVERFLOWS_TYPE(u16, u8, U8_MAX, false);
787 TEST_OVERFLOWS_TYPE(u16, u8, (u16)U8_MAX + 1, true);
788 TEST_OVERFLOWS_TYPE(u16, u8, U16_MAX, true);
789 TEST_OVERFLOWS_TYPE(u16, s8, S8_MAX, false);
790 TEST_OVERFLOWS_TYPE(u16, s8, (u16)S8_MAX + 1, true);
791 TEST_OVERFLOWS_TYPE(u16, s8, U16_MAX, true);
792 TEST_OVERFLOWS_TYPE(u16, s16, S16_MAX, false);
793 TEST_OVERFLOWS_TYPE(u16, s16, (u16)S16_MAX + 1, true);
794 TEST_OVERFLOWS_TYPE(u16, s16, U16_MAX, true);
795 TEST_OVERFLOWS_TYPE(u16, u32, U16_MAX, false);
796 TEST_OVERFLOWS_TYPE(u16, s32, U16_MAX, false);
797 TEST_OVERFLOWS_TYPE(s16, u8, U8_MAX, false);
798 TEST_OVERFLOWS_TYPE(s16, u8, (s16)U8_MAX + 1, true);
799 TEST_OVERFLOWS_TYPE(s16, u8, -1, true);
800 TEST_OVERFLOWS_TYPE(s16, u8, S16_MIN, true);
801 TEST_OVERFLOWS_TYPE(s16, u16, S16_MAX, false);
802 TEST_OVERFLOWS_TYPE(s16, u16, -1, true);
803 TEST_OVERFLOWS_TYPE(s16, u16, S16_MIN, true);
804 TEST_OVERFLOWS_TYPE(s16, u32, S16_MAX, false);
805 TEST_OVERFLOWS_TYPE(s16, u32, -1, true);
806 TEST_OVERFLOWS_TYPE(s16, u32, S16_MIN, true);
807#if BITS_PER_LONG == 64
808 TEST_OVERFLOWS_TYPE(s16, u64, S16_MAX, false);
809 TEST_OVERFLOWS_TYPE(s16, u64, -1, true);
810 TEST_OVERFLOWS_TYPE(s16, u64, S16_MIN, true);
811#endif
812 TEST_OVERFLOWS_TYPE(s16, s8, S8_MAX, false);
813 TEST_OVERFLOWS_TYPE(s16, s8, S8_MIN, false);
814 TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MAX + 1, true);
815 TEST_OVERFLOWS_TYPE(s16, s8, (s16)S8_MIN - 1, true);
816 TEST_OVERFLOWS_TYPE(s16, s8, S16_MAX, true);
817 TEST_OVERFLOWS_TYPE(s16, s8, S16_MIN, true);
818 TEST_OVERFLOWS_TYPE(s16, s16, S16_MAX, false);
819 TEST_OVERFLOWS_TYPE(s16, s16, S16_MIN, false);
820 TEST_OVERFLOWS_TYPE(s16, s32, S16_MAX, false);
821 TEST_OVERFLOWS_TYPE(s16, s32, S16_MIN, false);
822 TEST_OVERFLOWS_TYPE(u32, u8, U8_MAX, false);
823 TEST_OVERFLOWS_TYPE(u32, u8, (u32)U8_MAX + 1, true);
824 TEST_OVERFLOWS_TYPE(u32, u8, U32_MAX, true);
825 TEST_OVERFLOWS_TYPE(u32, s8, S8_MAX, false);
826 TEST_OVERFLOWS_TYPE(u32, s8, (u32)S8_MAX + 1, true);
827 TEST_OVERFLOWS_TYPE(u32, s8, U32_MAX, true);
828 TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX, false);
829 TEST_OVERFLOWS_TYPE(u32, u16, U16_MAX + 1, true);
830 TEST_OVERFLOWS_TYPE(u32, u16, U32_MAX, true);
831 TEST_OVERFLOWS_TYPE(u32, s16, S16_MAX, false);
832 TEST_OVERFLOWS_TYPE(u32, s16, (u32)S16_MAX + 1, true);
833 TEST_OVERFLOWS_TYPE(u32, s16, U32_MAX, true);
834 TEST_OVERFLOWS_TYPE(u32, u32, U32_MAX, false);
835 TEST_OVERFLOWS_TYPE(u32, s32, S32_MAX, false);
836 TEST_OVERFLOWS_TYPE(u32, s32, U32_MAX, true);
837 TEST_OVERFLOWS_TYPE(u32, s32, (u32)S32_MAX + 1, true);
838#if BITS_PER_LONG == 64
839 TEST_OVERFLOWS_TYPE(u32, u64, U32_MAX, false);
840 TEST_OVERFLOWS_TYPE(u32, s64, U32_MAX, false);
841#endif
842 TEST_OVERFLOWS_TYPE(s32, u8, U8_MAX, false);
843 TEST_OVERFLOWS_TYPE(s32, u8, (s32)U8_MAX + 1, true);
844 TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
845 TEST_OVERFLOWS_TYPE(s32, u8, -1, true);
846 TEST_OVERFLOWS_TYPE(s32, u8, S32_MIN, true);
847 TEST_OVERFLOWS_TYPE(s32, u16, U16_MAX, false);
848 TEST_OVERFLOWS_TYPE(s32, u16, (s32)U16_MAX + 1, true);
849 TEST_OVERFLOWS_TYPE(s32, u16, S32_MAX, true);
850 TEST_OVERFLOWS_TYPE(s32, u16, -1, true);
851 TEST_OVERFLOWS_TYPE(s32, u16, S32_MIN, true);
852 TEST_OVERFLOWS_TYPE(s32, u32, S32_MAX, false);
853 TEST_OVERFLOWS_TYPE(s32, u32, -1, true);
854 TEST_OVERFLOWS_TYPE(s32, u32, S32_MIN, true);
855#if BITS_PER_LONG == 64
856 TEST_OVERFLOWS_TYPE(s32, u64, S32_MAX, false);
857 TEST_OVERFLOWS_TYPE(s32, u64, -1, true);
858 TEST_OVERFLOWS_TYPE(s32, u64, S32_MIN, true);
859#endif
860 TEST_OVERFLOWS_TYPE(s32, s8, S8_MAX, false);
861 TEST_OVERFLOWS_TYPE(s32, s8, S8_MIN, false);
862 TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MAX + 1, true);
863 TEST_OVERFLOWS_TYPE(s32, s8, (s32)S8_MIN - 1, true);
864 TEST_OVERFLOWS_TYPE(s32, s8, S32_MAX, true);
865 TEST_OVERFLOWS_TYPE(s32, s8, S32_MIN, true);
866 TEST_OVERFLOWS_TYPE(s32, s16, S16_MAX, false);
867 TEST_OVERFLOWS_TYPE(s32, s16, S16_MIN, false);
868 TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MAX + 1, true);
869 TEST_OVERFLOWS_TYPE(s32, s16, (s32)S16_MIN - 1, true);
870 TEST_OVERFLOWS_TYPE(s32, s16, S32_MAX, true);
871 TEST_OVERFLOWS_TYPE(s32, s16, S32_MIN, true);
872 TEST_OVERFLOWS_TYPE(s32, s32, S32_MAX, false);
873 TEST_OVERFLOWS_TYPE(s32, s32, S32_MIN, false);
874#if BITS_PER_LONG == 64
875 TEST_OVERFLOWS_TYPE(s32, s64, S32_MAX, false);
876 TEST_OVERFLOWS_TYPE(s32, s64, S32_MIN, false);
877 TEST_OVERFLOWS_TYPE(u64, u8, U64_MAX, true);
878 TEST_OVERFLOWS_TYPE(u64, u8, U8_MAX, false);
879 TEST_OVERFLOWS_TYPE(u64, u8, (u64)U8_MAX + 1, true);
880 TEST_OVERFLOWS_TYPE(u64, u16, U64_MAX, true);
881 TEST_OVERFLOWS_TYPE(u64, u16, U16_MAX, false);
882 TEST_OVERFLOWS_TYPE(u64, u16, (u64)U16_MAX + 1, true);
883 TEST_OVERFLOWS_TYPE(u64, u32, U64_MAX, true);
884 TEST_OVERFLOWS_TYPE(u64, u32, U32_MAX, false);
885 TEST_OVERFLOWS_TYPE(u64, u32, (u64)U32_MAX + 1, true);
886 TEST_OVERFLOWS_TYPE(u64, u64, U64_MAX, false);
887 TEST_OVERFLOWS_TYPE(u64, s8, S8_MAX, false);
888 TEST_OVERFLOWS_TYPE(u64, s8, (u64)S8_MAX + 1, true);
889 TEST_OVERFLOWS_TYPE(u64, s8, U64_MAX, true);
890 TEST_OVERFLOWS_TYPE(u64, s16, S16_MAX, false);
891 TEST_OVERFLOWS_TYPE(u64, s16, (u64)S16_MAX + 1, true);
892 TEST_OVERFLOWS_TYPE(u64, s16, U64_MAX, true);
893 TEST_OVERFLOWS_TYPE(u64, s32, S32_MAX, false);
894 TEST_OVERFLOWS_TYPE(u64, s32, (u64)S32_MAX + 1, true);
895 TEST_OVERFLOWS_TYPE(u64, s32, U64_MAX, true);
896 TEST_OVERFLOWS_TYPE(u64, s64, S64_MAX, false);
897 TEST_OVERFLOWS_TYPE(u64, s64, U64_MAX, true);
898 TEST_OVERFLOWS_TYPE(u64, s64, (u64)S64_MAX + 1, true);
899 TEST_OVERFLOWS_TYPE(s64, u8, S64_MAX, true);
900 TEST_OVERFLOWS_TYPE(s64, u8, S64_MIN, true);
901 TEST_OVERFLOWS_TYPE(s64, u8, -1, true);
902 TEST_OVERFLOWS_TYPE(s64, u8, U8_MAX, false);
903 TEST_OVERFLOWS_TYPE(s64, u8, (s64)U8_MAX + 1, true);
904 TEST_OVERFLOWS_TYPE(s64, u16, S64_MAX, true);
905 TEST_OVERFLOWS_TYPE(s64, u16, S64_MIN, true);
906 TEST_OVERFLOWS_TYPE(s64, u16, -1, true);
907 TEST_OVERFLOWS_TYPE(s64, u16, U16_MAX, false);
908 TEST_OVERFLOWS_TYPE(s64, u16, (s64)U16_MAX + 1, true);
909 TEST_OVERFLOWS_TYPE(s64, u32, S64_MAX, true);
910 TEST_OVERFLOWS_TYPE(s64, u32, S64_MIN, true);
911 TEST_OVERFLOWS_TYPE(s64, u32, -1, true);
912 TEST_OVERFLOWS_TYPE(s64, u32, U32_MAX, false);
913 TEST_OVERFLOWS_TYPE(s64, u32, (s64)U32_MAX + 1, true);
914 TEST_OVERFLOWS_TYPE(s64, u64, S64_MAX, false);
915 TEST_OVERFLOWS_TYPE(s64, u64, S64_MIN, true);
916 TEST_OVERFLOWS_TYPE(s64, u64, -1, true);
917 TEST_OVERFLOWS_TYPE(s64, s8, S8_MAX, false);
918 TEST_OVERFLOWS_TYPE(s64, s8, S8_MIN, false);
919 TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MAX + 1, true);
920 TEST_OVERFLOWS_TYPE(s64, s8, (s64)S8_MIN - 1, true);
921 TEST_OVERFLOWS_TYPE(s64, s8, S64_MAX, true);
922 TEST_OVERFLOWS_TYPE(s64, s16, S16_MAX, false);
923 TEST_OVERFLOWS_TYPE(s64, s16, S16_MIN, false);
924 TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MAX + 1, true);
925 TEST_OVERFLOWS_TYPE(s64, s16, (s64)S16_MIN - 1, true);
926 TEST_OVERFLOWS_TYPE(s64, s16, S64_MAX, true);
927 TEST_OVERFLOWS_TYPE(s64, s32, S32_MAX, false);
928 TEST_OVERFLOWS_TYPE(s64, s32, S32_MIN, false);
929 TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MAX + 1, true);
930 TEST_OVERFLOWS_TYPE(s64, s32, (s64)S32_MIN - 1, true);
931 TEST_OVERFLOWS_TYPE(s64, s32, S64_MAX, true);
932 TEST_OVERFLOWS_TYPE(s64, s64, S64_MAX, false);
933 TEST_OVERFLOWS_TYPE(s64, s64, S64_MIN, false);
934#endif
935
936 /* Check for macro side-effects. */
937 var = INT_MAX - 1;
938 __TEST_OVERFLOWS_TYPE(__overflows_type, var++, int, false);
939 __TEST_OVERFLOWS_TYPE(__overflows_type, var++, int, false);
940 __TEST_OVERFLOWS_TYPE(__overflows_type, var++, int, true);
941 var = INT_MAX - 1;
942 __TEST_OVERFLOWS_TYPE(overflows_type, var++, int, false);
943 __TEST_OVERFLOWS_TYPE(overflows_type, var++, int, false);
944 __TEST_OVERFLOWS_TYPE(overflows_type, var++, int, true);
945
946 kunit_info(test, "%d overflows_type() tests finished\n", count);
947#undef TEST_OVERFLOWS_TYPE
948#undef __TEST_OVERFLOWS_TYPE
949}
950
951static void same_type_test(struct kunit *test)
952{
953 int count = 0;
954 int var;
955
956#define TEST_SAME_TYPE(t1, t2, same) do { \
957 typeof(t1) __t1h = type_max(t1); \
958 typeof(t1) __t1l = type_min(t1); \
959 typeof(t2) __t2h = type_max(t2); \
960 typeof(t2) __t2l = type_min(t2); \
961 KUNIT_EXPECT_EQ(test, true, __same_type(t1, __t1h)); \
962 KUNIT_EXPECT_EQ(test, true, __same_type(t1, __t1l)); \
963 KUNIT_EXPECT_EQ(test, true, __same_type(__t1h, t1)); \
964 KUNIT_EXPECT_EQ(test, true, __same_type(__t1l, t1)); \
965 KUNIT_EXPECT_EQ(test, true, __same_type(t2, __t2h)); \
966 KUNIT_EXPECT_EQ(test, true, __same_type(t2, __t2l)); \
967 KUNIT_EXPECT_EQ(test, true, __same_type(__t2h, t2)); \
968 KUNIT_EXPECT_EQ(test, true, __same_type(__t2l, t2)); \
969 KUNIT_EXPECT_EQ(test, same, __same_type(t1, t2)); \
970 KUNIT_EXPECT_EQ(test, same, __same_type(t2, __t1h)); \
971 KUNIT_EXPECT_EQ(test, same, __same_type(t2, __t1l)); \
972 KUNIT_EXPECT_EQ(test, same, __same_type(__t1h, t2)); \
973 KUNIT_EXPECT_EQ(test, same, __same_type(__t1l, t2)); \
974 KUNIT_EXPECT_EQ(test, same, __same_type(t1, __t2h)); \
975 KUNIT_EXPECT_EQ(test, same, __same_type(t1, __t2l)); \
976 KUNIT_EXPECT_EQ(test, same, __same_type(__t2h, t1)); \
977 KUNIT_EXPECT_EQ(test, same, __same_type(__t2l, t1)); \
978} while (0)
979
980#if BITS_PER_LONG == 64
981# define TEST_SAME_TYPE64(base, t, m) TEST_SAME_TYPE(base, t, m)
982#else
983# define TEST_SAME_TYPE64(base, t, m) do { } while (0)
984#endif
985
986#define TEST_TYPE_SETS(base, mu8, mu16, mu32, ms8, ms16, ms32, mu64, ms64) \
987do { \
988 TEST_SAME_TYPE(base, u8, mu8); \
989 TEST_SAME_TYPE(base, u16, mu16); \
990 TEST_SAME_TYPE(base, u32, mu32); \
991 TEST_SAME_TYPE(base, s8, ms8); \
992 TEST_SAME_TYPE(base, s16, ms16); \
993 TEST_SAME_TYPE(base, s32, ms32); \
994 TEST_SAME_TYPE64(base, u64, mu64); \
995 TEST_SAME_TYPE64(base, s64, ms64); \
996} while (0)
997
998 TEST_TYPE_SETS(u8, true, false, false, false, false, false, false, false);
999 TEST_TYPE_SETS(u16, false, true, false, false, false, false, false, false);
1000 TEST_TYPE_SETS(u32, false, false, true, false, false, false, false, false);
1001 TEST_TYPE_SETS(s8, false, false, false, true, false, false, false, false);
1002 TEST_TYPE_SETS(s16, false, false, false, false, true, false, false, false);
1003 TEST_TYPE_SETS(s32, false, false, false, false, false, true, false, false);
1004#if BITS_PER_LONG == 64
1005 TEST_TYPE_SETS(u64, false, false, false, false, false, false, true, false);
1006 TEST_TYPE_SETS(s64, false, false, false, false, false, false, false, true);
1007#endif
1008
1009 /* Check for macro side-effects. */
1010 var = 4;
1011 KUNIT_EXPECT_EQ(test, var, 4);
1012 KUNIT_EXPECT_TRUE(test, __same_type(var++, int));
1013 KUNIT_EXPECT_EQ(test, var, 4);
1014 KUNIT_EXPECT_TRUE(test, __same_type(int, var++));
1015 KUNIT_EXPECT_EQ(test, var, 4);
1016 KUNIT_EXPECT_TRUE(test, __same_type(var++, var++));
1017 KUNIT_EXPECT_EQ(test, var, 4);
1018
1019 kunit_info(test, "%d __same_type() tests finished\n", count);
1020
1021#undef TEST_TYPE_SETS
1022#undef TEST_SAME_TYPE64
1023#undef TEST_SAME_TYPE
1024}
1025
1026static void castable_to_type_test(struct kunit *test)
1027{
1028 int count = 0;
1029
1030#define TEST_CASTABLE_TO_TYPE(arg1, arg2, pass) do { \
1031 bool __pass = castable_to_type(arg1, arg2); \
1032 KUNIT_EXPECT_EQ_MSG(test, __pass, pass, \
1033 "expected castable_to_type(" #arg1 ", " #arg2 ") to%s pass\n",\
1034 pass ? "" : " not"); \
1035 count++; \
1036} while (0)
1037
1038 TEST_CASTABLE_TO_TYPE(16, u8, true);
1039 TEST_CASTABLE_TO_TYPE(16, u16, true);
1040 TEST_CASTABLE_TO_TYPE(16, u32, true);
1041 TEST_CASTABLE_TO_TYPE(16, s8, true);
1042 TEST_CASTABLE_TO_TYPE(16, s16, true);
1043 TEST_CASTABLE_TO_TYPE(16, s32, true);
1044 TEST_CASTABLE_TO_TYPE(-16, s8, true);
1045 TEST_CASTABLE_TO_TYPE(-16, s16, true);
1046 TEST_CASTABLE_TO_TYPE(-16, s32, true);
1047#if BITS_PER_LONG == 64
1048 TEST_CASTABLE_TO_TYPE(16, u64, true);
1049 TEST_CASTABLE_TO_TYPE(-16, s64, true);
1050#endif
1051
1052#define TEST_CASTABLE_TO_TYPE_VAR(width) do { \
1053 u ## width u ## width ## var = 0; \
1054 s ## width s ## width ## var = 0; \
1055 \
1056 /* Constant expressions that fit types. */ \
1057 TEST_CASTABLE_TO_TYPE(type_max(u ## width), u ## width, true); \
1058 TEST_CASTABLE_TO_TYPE(type_min(u ## width), u ## width, true); \
1059 TEST_CASTABLE_TO_TYPE(type_max(u ## width), u ## width ## var, true); \
1060 TEST_CASTABLE_TO_TYPE(type_min(u ## width), u ## width ## var, true); \
1061 TEST_CASTABLE_TO_TYPE(type_max(s ## width), s ## width, true); \
1062 TEST_CASTABLE_TO_TYPE(type_min(s ## width), s ## width, true); \
1063 TEST_CASTABLE_TO_TYPE(type_max(s ## width), s ## width ## var, true); \
1064 TEST_CASTABLE_TO_TYPE(type_min(u ## width), s ## width ## var, true); \
1065 /* Constant expressions that do not fit types. */ \
1066 TEST_CASTABLE_TO_TYPE(type_max(u ## width), s ## width, false); \
1067 TEST_CASTABLE_TO_TYPE(type_max(u ## width), s ## width ## var, false); \
1068 TEST_CASTABLE_TO_TYPE(type_min(s ## width), u ## width, false); \
1069 TEST_CASTABLE_TO_TYPE(type_min(s ## width), u ## width ## var, false); \
1070 /* Non-constant expression with mismatched type. */ \
1071 TEST_CASTABLE_TO_TYPE(s ## width ## var, u ## width, false); \
1072 TEST_CASTABLE_TO_TYPE(u ## width ## var, s ## width, false); \
1073} while (0)
1074
1075#define TEST_CASTABLE_TO_TYPE_RANGE(width) do { \
1076 unsigned long big = U ## width ## _MAX; \
1077 signed long small = S ## width ## _MIN; \
1078 u ## width u ## width ## var = 0; \
1079 s ## width s ## width ## var = 0; \
1080 \
1081 /* Constant expression in range. */ \
1082 TEST_CASTABLE_TO_TYPE(U ## width ## _MAX, u ## width, true); \
1083 TEST_CASTABLE_TO_TYPE(U ## width ## _MAX, u ## width ## var, true); \
1084 TEST_CASTABLE_TO_TYPE(S ## width ## _MIN, s ## width, true); \
1085 TEST_CASTABLE_TO_TYPE(S ## width ## _MIN, s ## width ## var, true); \
1086 /* Constant expression out of range. */ \
1087 TEST_CASTABLE_TO_TYPE((unsigned long)U ## width ## _MAX + 1, u ## width, false); \
1088 TEST_CASTABLE_TO_TYPE((unsigned long)U ## width ## _MAX + 1, u ## width ## var, false); \
1089 TEST_CASTABLE_TO_TYPE((signed long)S ## width ## _MIN - 1, s ## width, false); \
1090 TEST_CASTABLE_TO_TYPE((signed long)S ## width ## _MIN - 1, s ## width ## var, false); \
1091 /* Non-constant expression with mismatched type. */ \
1092 TEST_CASTABLE_TO_TYPE(big, u ## width, false); \
1093 TEST_CASTABLE_TO_TYPE(big, u ## width ## var, false); \
1094 TEST_CASTABLE_TO_TYPE(small, s ## width, false); \
1095 TEST_CASTABLE_TO_TYPE(small, s ## width ## var, false); \
1096} while (0)
1097
1098 TEST_CASTABLE_TO_TYPE_VAR(8);
1099 TEST_CASTABLE_TO_TYPE_VAR(16);
1100 TEST_CASTABLE_TO_TYPE_VAR(32);
1101#if BITS_PER_LONG == 64
1102 TEST_CASTABLE_TO_TYPE_VAR(64);
1103#endif
1104
1105 TEST_CASTABLE_TO_TYPE_RANGE(8);
1106 TEST_CASTABLE_TO_TYPE_RANGE(16);
1107#if BITS_PER_LONG == 64
1108 TEST_CASTABLE_TO_TYPE_RANGE(32);
1109#endif
1110 kunit_info(test, "%d castable_to_type() tests finished\n", count);
1111
1112#undef TEST_CASTABLE_TO_TYPE_RANGE
1113#undef TEST_CASTABLE_TO_TYPE_VAR
1114#undef TEST_CASTABLE_TO_TYPE
1115}
1116
739static struct kunit_case overflow_test_cases[] = {1117static struct kunit_case overflow_test_cases[] = {
740 KUNIT_CASE(u8_u8__u8_overflow_test),1118 KUNIT_CASE(u8_u8__u8_overflow_test),
741 KUNIT_CASE(s8_s8__s8_overflow_test),1119 KUNIT_CASE(s8_s8__s8_overflow_test),
@@ -755,6 +1133,9 @@ static struct kunit_case overflow_test_cases[] = { · 13 unmodified lines
755 KUNIT_CASE(shift_nonsense_test),1133 KUNIT_CASE(shift_nonsense_test),
756 KUNIT_CASE(overflow_allocation_test),1134 KUNIT_CASE(overflow_allocation_test),
757 KUNIT_CASE(overflow_size_helpers_test),1135 KUNIT_CASE(overflow_size_helpers_test),
1136 KUNIT_CASE(overflows_type_test),
1137 KUNIT_CASE(same_type_test),
1138 KUNIT_CASE(castable_to_type_test),
758 {}1139 {}
759};1140};
760 1141
lib/siphash_kunit.crenamed from lib/test_siphash.c+70−95
@@ -13,6 +13,7 @@ · 12 unmodified lines
13 13
14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15 15
16#include <kunit/test.h>
16#include <linux/siphash.h>17#include <linux/siphash.h>
17#include <linux/kernel.h>18#include <linux/kernel.h>
18#include <linux/string.h>19#include <linux/string.h>
@@ -109,114 +110,88 @@ static const u32 test_vectors_hsiphash[64] = { · 90 unmodified lines
109};110};
110#endif111#endif
111 112
112static int __init siphash_test_init(void)113#define chk(hash, vector, fmt...) \
114 KUNIT_EXPECT_EQ_MSG(test, hash, vector, fmt)
115
116static void siphash_test(struct kunit *test)
113{117{
114 u8 in[64] __aligned(SIPHASH_ALIGNMENT);118 u8 in[64] __aligned(SIPHASH_ALIGNMENT);
115 u8 in_unaligned[65] __aligned(SIPHASH_ALIGNMENT);119 u8 in_unaligned[65] __aligned(SIPHASH_ALIGNMENT);
116 u8 i;120 u8 i;
117 int ret = 0;
118 121
119 for (i = 0; i < 64; ++i) {122 for (i = 0; i < 64; ++i) {
120 in[i] = i;123 in[i] = i;
121 in_unaligned[i + 1] = i;124 in_unaligned[i + 1] = i;
122 if (siphash(in, i, &test_key_siphash) !=125 chk(siphash(in, i, &test_key_siphash),
123 test_vectors_siphash[i]) {126 test_vectors_siphash[i],
124 pr_info("siphash self-test aligned %u: FAIL\n", i + 1);127 "siphash self-test aligned %u: FAIL", i + 1);
125 ret = -EINVAL;128 chk(siphash(in_unaligned + 1, i, &test_key_siphash),
126 }129 test_vectors_siphash[i],
127 if (siphash(in_unaligned + 1, i, &test_key_siphash) !=130 "siphash self-test unaligned %u: FAIL", i + 1);
128 test_vectors_siphash[i]) {131 chk(hsiphash(in, i, &test_key_hsiphash),
129 pr_info("siphash self-test unaligned %u: FAIL\n", i + 1);132 test_vectors_hsiphash[i],
130 ret = -EINVAL;133 "hsiphash self-test aligned %u: FAIL", i + 1);
131 }134 chk(hsiphash(in_unaligned + 1, i, &test_key_hsiphash),
132 if (hsiphash(in, i, &test_key_hsiphash) !=135 test_vectors_hsiphash[i],
133 test_vectors_hsiphash[i]) {136 "hsiphash self-test unaligned %u: FAIL", i + 1);
134 pr_info("hsiphash self-test aligned %u: FAIL\n", i + 1);
135 ret = -EINVAL;
136 }
137 if (hsiphash(in_unaligned + 1, i, &test_key_hsiphash) !=
138 test_vectors_hsiphash[i]) {
139 pr_info("hsiphash self-test unaligned %u: FAIL\n", i + 1);
140 ret = -EINVAL;
141 }
142 }
143 if (siphash_1u64(0x0706050403020100ULL, &test_key_siphash) !=
144 test_vectors_siphash[8]) {
145 pr_info("siphash self-test 1u64: FAIL\n");
146 ret = -EINVAL;
147 }
148 if (siphash_2u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
149 &test_key_siphash) != test_vectors_siphash[16]) {
150 pr_info("siphash self-test 2u64: FAIL\n");
151 ret = -EINVAL;
152 }137 }
153 if (siphash_3u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,138 chk(siphash_1u64(0x0706050403020100ULL, &test_key_siphash),
154 0x1716151413121110ULL, &test_key_siphash) !=139 test_vectors_siphash[8],
155 test_vectors_siphash[24]) {140 "siphash self-test 1u64: FAIL");
156 pr_info("siphash self-test 3u64: FAIL\n");141 chk(siphash_2u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
157 ret = -EINVAL;142 &test_key_siphash),
158 }143 test_vectors_siphash[16],
159 if (siphash_4u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,144 "siphash self-test 2u64: FAIL");
145 chk(siphash_3u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
146 0x1716151413121110ULL, &test_key_siphash),
147 test_vectors_siphash[24],
148 "siphash self-test 3u64: FAIL");
149 chk(siphash_4u64(0x0706050403020100ULL, 0x0f0e0d0c0b0a0908ULL,
160 0x1716151413121110ULL, 0x1f1e1d1c1b1a1918ULL,150 0x1716151413121110ULL, 0x1f1e1d1c1b1a1918ULL,
161 &test_key_siphash) != test_vectors_siphash[32]) {151 &test_key_siphash),
162 pr_info("siphash self-test 4u64: FAIL\n");152 test_vectors_siphash[32],
163 ret = -EINVAL;153 "siphash self-test 4u64: FAIL");
164 }154 chk(siphash_1u32(0x03020100U, &test_key_siphash),
165 if (siphash_1u32(0x03020100U, &test_key_siphash) !=155 test_vectors_siphash[4],
166 test_vectors_siphash[4]) {156 "siphash self-test 1u32: FAIL");
167 pr_info("siphash self-test 1u32: FAIL\n");157 chk(siphash_2u32(0x03020100U, 0x07060504U, &test_key_siphash),
168 ret = -EINVAL;158 test_vectors_siphash[8],
169 }159 "siphash self-test 2u32: FAIL");
170 if (siphash_2u32(0x03020100U, 0x07060504U, &test_key_siphash) !=160 chk(siphash_3u32(0x03020100U, 0x07060504U,
171 test_vectors_siphash[8]) {161 0x0b0a0908U, &test_key_siphash),
172 pr_info("siphash self-test 2u32: FAIL\n");162 test_vectors_siphash[12],
173 ret = -EINVAL;163 "siphash self-test 3u32: FAIL");
174 }164 chk(siphash_4u32(0x03020100U, 0x07060504U,
175 if (siphash_3u32(0x03020100U, 0x07060504U,165 0x0b0a0908U, 0x0f0e0d0cU, &test_key_siphash),
176 0x0b0a0908U, &test_key_siphash) !=166 test_vectors_siphash[16],
177 test_vectors_siphash[12]) {167 "siphash self-test 4u32: FAIL");
178 pr_info("siphash self-test 3u32: FAIL\n");168 chk(hsiphash_1u32(0x03020100U, &test_key_hsiphash),
179 ret = -EINVAL;169 test_vectors_hsiphash[4],
180 }170 "hsiphash self-test 1u32: FAIL");
181 if (siphash_4u32(0x03020100U, 0x07060504U,171 chk(hsiphash_2u32(0x03020100U, 0x07060504U, &test_key_hsiphash),
182 0x0b0a0908U, 0x0f0e0d0cU, &test_key_siphash) !=172 test_vectors_hsiphash[8],
183 test_vectors_siphash[16]) {173 "hsiphash self-test 2u32: FAIL");
184 pr_info("siphash self-test 4u32: FAIL\n");174 chk(hsiphash_3u32(0x03020100U, 0x07060504U,
185 ret = -EINVAL;175 0x0b0a0908U, &test_key_hsiphash),
186 }176 test_vectors_hsiphash[12],
187 if (hsiphash_1u32(0x03020100U, &test_key_hsiphash) !=177 "hsiphash self-test 3u32: FAIL");
188 test_vectors_hsiphash[4]) {178 chk(hsiphash_4u32(0x03020100U, 0x07060504U,
189 pr_info("hsiphash self-test 1u32: FAIL\n");179 0x0b0a0908U, 0x0f0e0d0cU, &test_key_hsiphash),
190 ret = -EINVAL;180 test_vectors_hsiphash[16],
191 }181 "hsiphash self-test 4u32: FAIL");
192 if (hsiphash_2u32(0x03020100U, 0x07060504U, &test_key_hsiphash) !=
193 test_vectors_hsiphash[8]) {
194 pr_info("hsiphash self-test 2u32: FAIL\n");
195 ret = -EINVAL;
196 }
197 if (hsiphash_3u32(0x03020100U, 0x07060504U,
198 0x0b0a0908U, &test_key_hsiphash) !=
199 test_vectors_hsiphash[12]) {
200 pr_info("hsiphash self-test 3u32: FAIL\n");
201 ret = -EINVAL;
202 }
203 if (hsiphash_4u32(0x03020100U, 0x07060504U,
204 0x0b0a0908U, 0x0f0e0d0cU, &test_key_hsiphash) !=
205 test_vectors_hsiphash[16]) {
206 pr_info("hsiphash self-test 4u32: FAIL\n");
207 ret = -EINVAL;
208 }
209 if (!ret)
210 pr_info("self-tests: pass\n");
211 return ret;
212}182}
213 183
214static void __exit siphash_test_exit(void)184static struct kunit_case siphash_test_cases[] = {
215{185 KUNIT_CASE(siphash_test),
216}186 {}
187};
188
189static struct kunit_suite siphash_test_suite = {
190 .name = "siphash",
191 .test_cases = siphash_test_cases,
192};
217 193
218module_init(siphash_test_init);194kunit_test_suite(siphash_test_suite);
219module_exit(siphash_test_exit);
220 195
221MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");196MODULE_AUTHOR("Jason A. Donenfeld <Jason@zx2c4.com>");
222MODULE_LICENSE("Dual BSD/GPL");197MODULE_LICENSE("Dual BSD/GPL");
lib/string.c+0−82
@@ -76,11 +76,6 @@ EXPORT_SYMBOL(strcasecmp); · 75 unmodified lines
76#endif76#endif
77 77
78#ifndef __HAVE_ARCH_STRCPY78#ifndef __HAVE_ARCH_STRCPY
79/**
80 * strcpy - Copy a %NUL terminated string
81 * @dest: Where to copy the string to
82 * @src: Where to copy the string from
83 */
84char *strcpy(char *dest, const char *src)79char *strcpy(char *dest, const char *src)
85{80{
86 char *tmp = dest;81 char *tmp = dest;
@@ -93,19 +88,6 @@ EXPORT_SYMBOL(strcpy); · 6 unmodified lines
93#endif88#endif
94 89
95#ifndef __HAVE_ARCH_STRNCPY90#ifndef __HAVE_ARCH_STRNCPY
96/**
97 * strncpy - Copy a length-limited, C-string
98 * @dest: Where to copy the string to
99 * @src: Where to copy the string from
100 * @count: The maximum number of bytes to copy
101 *
102 * The result is not %NUL-terminated if the source exceeds
103 * @count bytes.
104 *
105 * In the case where the length of @src is less than that of
106 * count, the remainder of @dest will be padded with %NUL.
107 *
108 */
109char *strncpy(char *dest, const char *src, size_t count)91char *strncpy(char *dest, const char *src, size_t count)
110{92{
111 char *tmp = dest;93 char *tmp = dest;
@@ -122,17 +104,6 @@ EXPORT_SYMBOL(strncpy); · 10 unmodified lines
122#endif104#endif
123 105
124#ifndef __HAVE_ARCH_STRLCPY106#ifndef __HAVE_ARCH_STRLCPY
125/**
126 * strlcpy - Copy a C-string into a sized buffer
127 * @dest: Where to copy the string to
128 * @src: Where to copy the string from
129 * @size: size of destination buffer
130 *
131 * Compatible with ``*BSD``: the result is always a valid
132 * NUL-terminated string that fits in the buffer (unless,
133 * of course, the buffer size is zero). It does not pad
134 * out the result like strncpy() does.
135 */
136size_t strlcpy(char *dest, const char *src, size_t size)107size_t strlcpy(char *dest, const char *src, size_t size)
137{108{
138 size_t ret = strlen(src);109 size_t ret = strlen(src);
@@ -148,30 +119,6 @@ EXPORT_SYMBOL(strlcpy); · 9 unmodified lines
148#endif119#endif
149 120
150#ifndef __HAVE_ARCH_STRSCPY121#ifndef __HAVE_ARCH_STRSCPY
151/**
152 * strscpy - Copy a C-string into a sized buffer
153 * @dest: Where to copy the string to
154 * @src: Where to copy the string from
155 * @count: Size of destination buffer
156 *
157 * Copy the string, or as much of it as fits, into the dest buffer. The
158 * behavior is undefined if the string buffers overlap. The destination
159 * buffer is always NUL terminated, unless it's zero-sized.
160 *
161 * Preferred to strlcpy() since the API doesn't require reading memory
162 * from the src string beyond the specified "count" bytes, and since
163 * the return value is easier to error-check than strlcpy()'s.
164 * In addition, the implementation is robust to the string changing out
165 * from underneath it, unlike the current strlcpy() implementation.
166 *
167 * Preferred to strncpy() since it always returns a valid string, and
168 * doesn't unnecessarily force the tail of the destination buffer to be
169 * zeroed. If zeroing is desired please use strscpy_pad().
170 *
171 * Returns:
172 * * The number of characters copied (not including the trailing %NUL)
173 * * -E2BIG if count is 0 or @src was truncated.
174 */
175ssize_t strscpy(char *dest, const char *src, size_t count)122ssize_t strscpy(char *dest, const char *src, size_t count)
176{123{
177 const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;124 const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
@@ -266,11 +213,6 @@ char *stpcpy(char *__restrict__ dest, const char *__restrict__ src) · 88 unmodified lines
266EXPORT_SYMBOL(stpcpy);213EXPORT_SYMBOL(stpcpy);
267 214
268#ifndef __HAVE_ARCH_STRCAT215#ifndef __HAVE_ARCH_STRCAT
269/**
270 * strcat - Append one %NUL-terminated string to another
271 * @dest: The string to be appended to
272 * @src: The string to append to it
273 */
274char *strcat(char *dest, const char *src)216char *strcat(char *dest, const char *src)
275{217{
276 char *tmp = dest;218 char *tmp = dest;
@@ -285,15 +227,6 @@ EXPORT_SYMBOL(strcat); · 8 unmodified lines
285#endif227#endif
286 228
287#ifndef __HAVE_ARCH_STRNCAT229#ifndef __HAVE_ARCH_STRNCAT
288/**
289 * strncat - Append a length-limited, C-string to another
290 * @dest: The string to be appended to
291 * @src: The string to append to it
292 * @count: The maximum numbers of bytes to copy
293 *
294 * Note that in contrast to strncpy(), strncat() ensures the result is
295 * terminated.
296 */
297char *strncat(char *dest, const char *src, size_t count)230char *strncat(char *dest, const char *src, size_t count)
298{231{
299 char *tmp = dest;232 char *tmp = dest;
@@ -314,12 +247,6 @@ EXPORT_SYMBOL(strncat); · 14 unmodified lines
314#endif247#endif
315 248
316#ifndef __HAVE_ARCH_STRLCAT249#ifndef __HAVE_ARCH_STRLCAT
317/**
318 * strlcat - Append a length-limited, C-string to another
319 * @dest: The string to be appended to
320 * @src: The string to append to it
321 * @count: The size of the destination buffer.
322 */
323size_t strlcat(char *dest, const char *src, size_t count)250size_t strlcat(char *dest, const char *src, size_t count)
324{251{
325 size_t dsize = strlen(dest);252 size_t dsize = strlen(dest);
@@ -484,10 +411,6 @@ EXPORT_SYMBOL(strnchr); · 158 unmodified lines
484#endif411#endif
485 412
486#ifndef __HAVE_ARCH_STRLEN413#ifndef __HAVE_ARCH_STRLEN
487/**
488 * strlen - Find the length of a string
489 * @s: The string to be sized
490 */
491size_t strlen(const char *s)414size_t strlen(const char *s)
492{415{
493 const char *sc;416 const char *sc;
@@ -500,11 +423,6 @@ EXPORT_SYMBOL(strlen); · 6 unmodified lines
500#endif423#endif
501 424
502#ifndef __HAVE_ARCH_STRNLEN425#ifndef __HAVE_ARCH_STRNLEN
503/**
504 * strnlen - Find the length of a length-limited string
505 * @s: The string to be sized
506 * @count: The maximum number of bytes to search
507 */
508size_t strnlen(const char *s, size_t count)426size_t strnlen(const char *s, size_t count)
509{427{
510 const char *sc;428 const char *sc;
lib/strscpy_kunit.c+142−0
@@ -0,0 +1,142 @@
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 */
25static 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
82static 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
129static struct kunit_case strscpy_test_cases[] = {
130 KUNIT_CASE(strscpy_test),
131 {}
132};
133
134static struct kunit_suite strscpy_test_suite = {
135 .name = "strscpy",
136 .test_cases = strscpy_test_cases,
137};
138
139kunit_test_suite(strscpy_test_suite);
140
141MODULE_AUTHOR("Tobin C. Harding <tobin@kernel.org>");
142MODULE_LICENSE("GPL");
lib/test_strscpy.c+0−150
@@ -1,150 +0,0 @@
1// SPDX-License-Identifier: GPL-2.0+
2
3#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
4
5#include <linux/string.h>
6
7#include "../tools/testing/selftests/kselftest_module.h"
8
9/*
10 * Kernel module for testing 'strscpy' family of functions.
11 */
12
13KSTM_MODULE_GLOBALS();
14
15/*
16 * tc() - Run a specific test case.
17 * @src: Source string, argument to strscpy_pad()
18 * @count: Size of destination buffer, argument to strscpy_pad()
19 * @expected: Expected return value from call to strscpy_pad()
20 * @terminator: 1 if there should be a terminating null byte 0 otherwise.
21 * @chars: Number of characters from the src string expected to be
22 * written to the dst buffer.
23 * @pad: Number of pad characters expected (in the tail of dst buffer).
24 * (@pad does not include the null terminator byte.)
25 *
26 * Calls strscpy_pad() and verifies the return value and state of the
27 * destination buffer after the call returns.
28 */
29static int __init tc(char *src, int count, int expected,
30 int chars, int terminator, int pad)
31{
32 int nr_bytes_poison;
33 int max_expected;
34 int max_count;
35 int written;
36 char buf[6];
37 int index, i;
38 const char POISON = 'z';
39
40 total_tests++;
41
42 if (!src) {
43 pr_err("null source string not supported\n");
44 return -1;
45 }
46
47 memset(buf, POISON, sizeof(buf));
48 /* Future proofing test suite, validate args */
49 max_count = sizeof(buf) - 2; /* Space for null and to verify overflow */
50 max_expected = count - 1; /* Space for the null */
51 if (count > max_count) {
52 pr_err("count (%d) is too big (%d) ... aborting", count, max_count);
53 return -1;
54 }
55 if (expected > max_expected) {
56 pr_warn("expected (%d) is bigger than can possibly be returned (%d)",
57 expected, max_expected);
58 }
59
60 written = strscpy_pad(buf, src, count);
61 if ((written) != (expected)) {
62 pr_err("%d != %d (written, expected)\n", written, expected);
63 goto fail;
64 }
65
66 if (count && written == -E2BIG) {
67 if (strncmp(buf, src, count - 1) != 0) {
68 pr_err("buffer state invalid for -E2BIG\n");
69 goto fail;
70 }
71 if (buf[count - 1] != '\0') {
72 pr_err("too big string is not null terminated correctly\n");
73 goto fail;
74 }
75 }
76
77 for (i = 0; i < chars; i++) {
78 if (buf[i] != src[i]) {
79 pr_err("buf[i]==%c != src[i]==%c\n", buf[i], src[i]);
80 goto fail;
81 }
82 }
83
84 if (terminator) {
85 if (buf[count - 1] != '\0') {
86 pr_err("string is not null terminated correctly\n");
87 goto fail;
88 }
89 }
90
91 for (i = 0; i < pad; i++) {
92 index = chars + terminator + i;
93 if (buf[index] != '\0') {
94 pr_err("padding missing at index: %d\n", i);
95 goto fail;
96 }
97 }
98
99 nr_bytes_poison = sizeof(buf) - chars - terminator - pad;
100 for (i = 0; i < nr_bytes_poison; i++) {
101 index = sizeof(buf) - 1 - i; /* Check from the end back */
102 if (buf[index] != POISON) {
103 pr_err("poison value missing at index: %d\n", i);
104 goto fail;
105 }
106 }
107
108 return 0;
109fail:
110 failed_tests++;
111 return -1;
112}
113
114static void __init selftest(void)
115{
116 /*
117 * tc() uses a destination buffer of size 6 and needs at
118 * least 2 characters spare (one for null and one to check for
119 * overflow). This means we should only call tc() with
120 * strings up to a maximum of 4 characters long and 'count'
121 * should not exceed 4. To test with longer strings increase
122 * the buffer size in tc().
123 */
124
125 /* tc(src, count, expected, chars, terminator, pad) */
126 KSTM_CHECK_ZERO(tc("a", 0, -E2BIG, 0, 0, 0));
127 KSTM_CHECK_ZERO(tc("", 0, -E2BIG, 0, 0, 0));
128
129 KSTM_CHECK_ZERO(tc("a", 1, -E2BIG, 0, 1, 0));
130 KSTM_CHECK_ZERO(tc("", 1, 0, 0, 1, 0));
131
132 KSTM_CHECK_ZERO(tc("ab", 2, -E2BIG, 1, 1, 0));
133 KSTM_CHECK_ZERO(tc("a", 2, 1, 1, 1, 0));
134 KSTM_CHECK_ZERO(tc("", 2, 0, 0, 1, 1));
135
136 KSTM_CHECK_ZERO(tc("abc", 3, -E2BIG, 2, 1, 0));
137 KSTM_CHECK_ZERO(tc("ab", 3, 2, 2, 1, 0));
138 KSTM_CHECK_ZERO(tc("a", 3, 1, 1, 1, 1));
139 KSTM_CHECK_ZERO(tc("", 3, 0, 0, 1, 2));
140
141 KSTM_CHECK_ZERO(tc("abcd", 4, -E2BIG, 3, 1, 0));
142 KSTM_CHECK_ZERO(tc("abc", 4, 3, 3, 1, 0));
143 KSTM_CHECK_ZERO(tc("ab", 4, 2, 2, 1, 1));
144 KSTM_CHECK_ZERO(tc("a", 4, 1, 1, 1, 2));
145 KSTM_CHECK_ZERO(tc("", 4, 0, 0, 1, 3));
146}
147
148KSTM_MODULE_LOADERS(test_strscpy);
149MODULE_AUTHOR("Tobin C. Harding <tobin@kernel.org>");
150MODULE_LICENSE("GPL");
lib/ubsan.c+1−2
@@ -154,8 +154,7 @@ static void ubsan_epilogue(void) · 153 unmodified lines
154 154
155 current->in_ubsan--;155 current->in_ubsan--;
156 156
157 if (panic_on_warn)157 check_panic_on_warn("UBSAN");
158 panic("panic_on_warn set ...\n");
159}158}
160 159
161void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs)160void __ubsan_handle_divrem_overflow(void *_data, void *lhs, void *rhs)
mm/kasan/kasan_test.c+13−6
@@ -825,23 +825,30 @@ static void kasan_global_oob_left(struct kunit *test) · 824 unmodified lines
825 KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)p);825 KUNIT_EXPECT_KASAN_FAIL(test, *(volatile char *)p);
826}826}
827 827
828/* Check that ksize() makes the whole object accessible. */828/* Check that ksize() does NOT unpoison whole object. */
829static void ksize_unpoisons_memory(struct kunit *test)829static void ksize_unpoisons_memory(struct kunit *test)
830{830{
831 char *ptr;831 char *ptr;
832 size_t size = 123, real_size;832 size_t size = 128 - KASAN_GRANULE_SIZE - 5;
833 size_t real_size;
833 834
834 ptr = kmalloc(size, GFP_KERNEL);835 ptr = kmalloc(size, GFP_KERNEL);
835 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);836 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
837
836 real_size = ksize(ptr);838 real_size = ksize(ptr);
839 KUNIT_EXPECT_GT(test, real_size, size);
837 840
838 OPTIMIZER_HIDE_VAR(ptr);841 OPTIMIZER_HIDE_VAR(ptr);
839 842
840 /* This access shouldn't trigger a KASAN report. */843 /* These accesses shouldn't trigger a KASAN report. */
841 ptr[size] = 'x';844 ptr[0] = 'x';
845 ptr[size - 1] = 'x';
842 846
843 /* This one must. */847 /* These must trigger a KASAN report. */
844 KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[real_size]);848 if (IS_ENABLED(CONFIG_KASAN_GENERIC))
849 KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[size]);
850 KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[size + 5]);
851 KUNIT_EXPECT_KASAN_FAIL(test, ((volatile char *)ptr)[real_size - 1]);
845 852
846 kfree(ptr);853 kfree(ptr);
847}854}
mm/kasan/report.c+2−2
@@ -186,8 +186,8 @@ static void end_report(unsigned long *flags, void *addr) · 185 unmodified lines
186 (unsigned long)addr);186 (unsigned long)addr);
187 pr_err("==================================================================\n");187 pr_err("==================================================================\n");
188 spin_unlock_irqrestore(&report_lock, *flags);188 spin_unlock_irqrestore(&report_lock, *flags);
189 if (panic_on_warn && !test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags))189 if (!test_bit(KASAN_BIT_MULTI_SHOT, &kasan_flags))
190 panic("panic_on_warn set ...\n");190 check_panic_on_warn("KASAN");
191 if (kasan_arg_fault == KASAN_ARG_FAULT_PANIC)191 if (kasan_arg_fault == KASAN_ARG_FAULT_PANIC)
192 panic("kasan.fault=panic set ...\n");192 panic("kasan.fault=panic set ...\n");
193 add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);193 add_taint(TAINT_BAD_PAGE, LOCKDEP_NOW_UNRELIABLE);
mm/kfence/report.c+1−2
@@ -273,8 +273,7 @@ void kfence_report_error(unsigned long address, bool is_write, struct pt_regs *r · 272 unmodified lines
273 273
274 lockdep_on();274 lockdep_on();
275 275
276 if (panic_on_warn)276 check_panic_on_warn("KFENCE");
277 panic("panic_on_warn set ...\n");
278 277
279 /* We encountered a memory safety error, taint the kernel! */278 /* We encountered a memory safety error, taint the kernel! */
280 add_taint(TAINT_BAD_PAGE, LOCKDEP_STILL_OK);279 add_taint(TAINT_BAD_PAGE, LOCKDEP_STILL_OK);
mm/slab_common.c+10−16
@@ -1348,11 +1348,11 @@ __do_krealloc(const void *p, size_t new_size, gfp_t flags) · 1347 unmodified lines
1348 void *ret;1348 void *ret;
1349 size_t ks;1349 size_t ks;
1350 1350
1351 /* Don't use instrumented ksize to allow precise KASAN poisoning. */1351 /* Check for double-free before calling ksize. */
1352 if (likely(!ZERO_OR_NULL_PTR(p))) {1352 if (likely(!ZERO_OR_NULL_PTR(p))) {
1353 if (!kasan_check_byte(p))1353 if (!kasan_check_byte(p))
1354 return NULL;1354 return NULL;
1355 ks = kfence_ksize(p) ?: __ksize(p);1355 ks = ksize(p);
1356 } else1356 } else
1357 ks = 0;1357 ks = 0;
1358 1358
@@ -1420,21 +1420,21 @@ void kfree_sensitive(const void *p) · 61 unmodified lines
1420 void *mem = (void *)p;1420 void *mem = (void *)p;
1421 1421
1422 ks = ksize(mem);1422 ks = ksize(mem);
1423 if (ks)1423 if (ks) {
1424 kasan_unpoison_range(mem, ks);
1424 memzero_explicit(mem, ks);1425 memzero_explicit(mem, ks);
1426 }
1425 kfree(mem);1427 kfree(mem);
1426}1428}
1427EXPORT_SYMBOL(kfree_sensitive);1429EXPORT_SYMBOL(kfree_sensitive);
1428 1430
1429size_t ksize(const void *objp)1431size_t ksize(const void *objp)
1430{1432{
1431 size_t size;
1432
1433 /*1433 /*
1434 * We need to first check that the pointer to the object is valid, and1434 * We need to first check that the pointer to the object is valid.
1435 * only then unpoison the memory. The report printed from ksize() is1435 * The KASAN report printed from ksize() is more useful, then when
1436 * more useful, then when it's printed later when the behaviour could1436 * it's printed later when the behaviour could be undefined due to
1437 * be undefined due to a potential use-after-free or double-free.1437 * a potential use-after-free or double-free.
1438 *1438 *
1439 * We use kasan_check_byte(), which is supported for the hardware1439 * We use kasan_check_byte(), which is supported for the hardware
1440 * tag-based KASAN mode, unlike kasan_check_read/write().1440 * tag-based KASAN mode, unlike kasan_check_read/write().
@@ -1448,13 +1448,7 @@ size_t ksize(const void *objp) · 7 unmodified lines
1448 if (unlikely(ZERO_OR_NULL_PTR(objp)) || !kasan_check_byte(objp))1448 if (unlikely(ZERO_OR_NULL_PTR(objp)) || !kasan_check_byte(objp))
1449 return 0;1449 return 0;
1450 1450
1451 size = kfence_ksize(objp) ?: __ksize(objp);1451 return kfence_ksize(objp) ?: __ksize(objp);
1452 /*
1453 * We assume that ksize callers could use whole allocated area,
1454 * so we need to unpoison this area.
1455 */
1456 kasan_unpoison_range(objp, size);
1457 return size;
1458}1452}
1459EXPORT_SYMBOL(ksize);1453EXPORT_SYMBOL(ksize);
1460 1454
net/dns_resolver/dns_key.c+1−1
@@ -337,7 +337,7 @@ static int __init init_dns_resolver(void) · 336 unmodified lines
337 * this is used to prevent malicious redirections from being installed337 * this is used to prevent malicious redirections from being installed
338 * with add_key().338 * with add_key().
339 */339 */
340 cred = prepare_kernel_cred(NULL);340 cred = prepare_kernel_cred(&init_task);
341 if (!cred)341 if (!cred)
342 return -ENOMEM;342 return -ENOMEM;
343 343
scripts/kernel-doc+5−1
@@ -1461,6 +1461,8 @@ sub create_parameterlist($$$$) { · 1460 unmodified lines
1461 foreach my $arg (split($splitter, $args)) {1461 foreach my $arg (split($splitter, $args)) {
1462 # strip comments1462 # strip comments
1463 $arg =~ s/\/\*.*\*\///;1463 $arg =~ s/\/\*.*\*\///;
1464 # ignore argument attributes
1465 $arg =~ s/\sPOS0?\s/ /;
1464 # strip leading/trailing spaces1466 # strip leading/trailing spaces
1465 $arg =~ s/^\s*//;1467 $arg =~ s/^\s*//;
1466 $arg =~ s/\s*$//;1468 $arg =~ s/\s*$//;
@@ -1670,6 +1672,7 @@ sub dump_function($$) { · 203 unmodified lines
1670 $prototype =~ s/^__inline +//;1672 $prototype =~ s/^__inline +//;
1671 $prototype =~ s/^__always_inline +//;1673 $prototype =~ s/^__always_inline +//;
1672 $prototype =~ s/^noinline +//;1674 $prototype =~ s/^noinline +//;
1675 $prototype =~ s/^__FORTIFY_INLINE +//;
1673 $prototype =~ s/__init +//;1676 $prototype =~ s/__init +//;
1674 $prototype =~ s/__init_or_module +//;1677 $prototype =~ s/__init_or_module +//;
1675 $prototype =~ s/__deprecated +//;1678 $prototype =~ s/__deprecated +//;
@@ -1679,7 +1682,8 @@ sub dump_function($$) { · 3 unmodified lines
1679 $prototype =~ s/__weak +//;1682 $prototype =~ s/__weak +//;
1680 $prototype =~ s/__sched +//;1683 $prototype =~ s/__sched +//;
1681 $prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//;1684 $prototype =~ s/__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +//;
1682 $prototype =~ s/__alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) +//;1685 $prototype =~ s/__(?:re)?alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) +//;
1686 $prototype =~ s/__diagnose_as\s*\(\s*\S+\s*(?:,\s*\d+\s*)*\) +//;
1683 my $define = $prototype =~ s/^#\s*define\s+//; #ak added1687 my $define = $prototype =~ s/^#\s*define\s+//; #ak added
1684 $prototype =~ s/__attribute_const__ +//;1688 $prototype =~ s/__attribute_const__ +//;
1685 $prototype =~ s/__attribute__\s*\(\(1689 $prototype =~ s/__attribute__\s*\(\(