Pull hardening updates from Kees Cook: "One of the more voluminous set of changes is for adding the new __counted_by annotation[1] to gain run-time bounds checking of dynamically sized arrays with UBSan. - Add LKDTM test for stuck CPUs (Mark Rutland) - Improve LKDTM selftest behavior under UBSan (Ricardo Cañuelo) - Refactor more 1-element arrays into flexible arrays (Gustavo A. R. Silva) - Analyze and replace strlcpy and strncpy uses (Justin Stitt, Azeem Shaikh) - Convert group_info.usage to refcount_t (Elena Reshetova) - Add __counted_by annotations (Kees Cook, Gustavo A. R. Silva) - Add Kconfig fragment for basic hardening options (Kees Cook, Lukas Bulwahn) - Fix randstruct GCC plugin performance mode to stay in groups (Kees Cook) - Fix strtomem() compile-time check for small sources (Kees Cook)" * tag 'hardening-v6.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: (56 commits) hwmon: (acpi_power_meter) replace open-coded kmemdup_nul reset: Annotate struct reset_control_array with __counted_by kexec: Annotate struct crash_mem with __counted_by virtio_console: Annotate struct port_buffer with __counted_by ima: Add __counted_by for struct modsig and use struct_size() MAINTAINERS: Include stackleak paths in hardening entry string: Adjust strtomem() logic to allow for smaller sources hardening: x86: drop reference to removed config AMD_IOMMU_V2 randstruct: Fix gcc-plugin performance mode to stay in group mailbox: zynqmp: Annotate struct zynqmp_ipi_pdata with __counted_by drivers: thermal: tsens: Annotate struct tsens_priv with __counted_by irqchip/imx-intmux: Annotate struct intmux_data with __counted_by KVM: Annotate struct kvm_irq_routing_table with __counted_by virt: acrn: Annotate struct vm_memory_region_batch with __counted_by hwmon: Annotate struct gsc_hwmon_platform_data with __counted_by sparc: Annotate struct cpuinfo_tree with __counted_by isdn: kcapi: replace deprecated strncpy with strscpy_pad isdn: replace deprecated strncpy with strscpy NFS/flexfiles: Annotate struct nfs4_ff_layout_segment with __counted_by nfs41: Annotate struct nfs4_file_layout_dsaddr with __counted_by ...
Unified · Split
| @@ -8649,6 +8649,8 @@ L: linux-hardening@vger.kernel.org · 8648 unmodified lines | |||
| 8649 | S: Maintained | 8649 | S: Maintained |
| 8650 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening | 8650 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening |
| 8651 | F: Documentation/kbuild/gcc-plugins.rst | 8651 | F: Documentation/kbuild/gcc-plugins.rst |
| 8652 | F: include/linux/stackleak.h | ||
| 8653 | F: kernel/stackleak.c | ||
| 8652 | F: scripts/Makefile.gcc-plugins | 8654 | F: scripts/Makefile.gcc-plugins |
| 8653 | F: scripts/gcc-plugins/ | 8655 | F: scripts/gcc-plugins/ |
| 8654 | 8656 | ||
| @@ -11415,16 +11417,20 @@ F: usr/ · 2760 unmodified lines | |||
| 11415 | 11417 | ||
| 11416 | KERNEL HARDENING (not covered by other areas) | 11418 | KERNEL HARDENING (not covered by other areas) |
| 11417 | M: Kees Cook <keescook@chromium.org> | 11419 | M: Kees Cook <keescook@chromium.org> |
| 11420 | R: Gustavo A. R. Silva <gustavoars@kernel.org> | ||
| 11418 | L: linux-hardening@vger.kernel.org | 11421 | L: linux-hardening@vger.kernel.org |
| 11419 | S: Supported | 11422 | S: Supported |
| 11420 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening | 11423 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening |
| 11421 | F: Documentation/ABI/testing/sysfs-kernel-oops_count | 11424 | F: Documentation/ABI/testing/sysfs-kernel-oops_count |
| 11422 | F: Documentation/ABI/testing/sysfs-kernel-warn_count | 11425 | F: Documentation/ABI/testing/sysfs-kernel-warn_count |
| 11426 | F: arch/*/configs/hardening.config | ||
| 11423 | F: include/linux/overflow.h | 11427 | F: include/linux/overflow.h |
| 11424 | F: include/linux/randomize_kstack.h | 11428 | F: include/linux/randomize_kstack.h |
| 11429 | F: kernel/configs/hardening.config | ||
| 11425 | F: mm/usercopy.c | 11430 | F: mm/usercopy.c |
| 11426 | K: \b(add|choose)_random_kstack_offset\b | 11431 | K: \b(add|choose)_random_kstack_offset\b |
| 11427 | K: \b__check_(object_size|heap_object)\b | 11432 | K: \b__check_(object_size|heap_object)\b |
| 11433 | K: \b__counted_by\b | ||
| 11428 | 11434 | ||
| 11429 | KERNEL JANITORS | 11435 | KERNEL JANITORS |
| 11430 | L: kernel-janitors@vger.kernel.org | 11436 | L: kernel-janitors@vger.kernel.org |
| @@ -0,0 +1,7 @@ | |||
| 1 | # Basic kernel hardening options (specific to arm) | ||
| 2 | |||
| 3 | # Make sure PXN/PAN emulation is enabled. | ||
| 4 | CONFIG_CPU_SW_DOMAIN_PAN=y | ||
| 5 | |||
| 6 | # Dangerous; old interfaces and needless additional attack surface. | ||
| 7 | # CONFIG_OABI_COMPAT is not set | ||
| @@ -0,0 +1,22 @@ | |||
| 1 | # Basic kernel hardening options (specific to arm64) | ||
| 2 | |||
| 3 | # Make sure PAN emulation is enabled. | ||
| 4 | CONFIG_ARM64_SW_TTBR0_PAN=y | ||
| 5 | |||
| 6 | # Software Shadow Stack or PAC | ||
| 7 | CONFIG_SHADOW_CALL_STACK=y | ||
| 8 | |||
| 9 | # Pointer authentication (ARMv8.3 and later). If hardware actually supports | ||
| 10 | # it, one can turn off CONFIG_STACKPROTECTOR_STRONG with this enabled. | ||
| 11 | CONFIG_ARM64_PTR_AUTH=y | ||
| 12 | CONFIG_ARM64_PTR_AUTH_KERNEL=y | ||
| 13 | |||
| 14 | # Available in ARMv8.5 and later. | ||
| 15 | CONFIG_ARM64_BTI=y | ||
| 16 | CONFIG_ARM64_BTI_KERNEL=y | ||
| 17 | CONFIG_ARM64_MTE=y | ||
| 18 | CONFIG_KASAN_HW_TAGS=y | ||
| 19 | CONFIG_ARM64_E0PD=y | ||
| 20 | |||
| 21 | # Available in ARMv8.7 and later. | ||
| 22 | CONFIG_ARM64_EPAN=y | ||
| @@ -0,0 +1,10 @@ | |||
| 1 | # PowerPC specific hardening options | ||
| 2 | |||
| 3 | # Block kernel from unexpectedly reading userspace memory. | ||
| 4 | CONFIG_PPC_KUAP=y | ||
| 5 | |||
| 6 | # Attack surface reduction. | ||
| 7 | # CONFIG_SCOM_DEBUGFS is not set | ||
| 8 | |||
| 9 | # Disable internal kernel debugger. | ||
| 10 | # CONFIG_XMON is not set | ||
| @@ -50,7 +50,7 @@ struct cpuinfo_tree { · 49 unmodified lines | |||
| 50 | 50 | ||
| 51 | /* Offsets into nodes[] for each level of the tree */ | 51 | /* Offsets into nodes[] for each level of the tree */ |
| 52 | struct cpuinfo_level level[CPUINFO_LVL_MAX]; | 52 | struct cpuinfo_level level[CPUINFO_LVL_MAX]; |
| 53 | struct cpuinfo_node nodes[]; | 53 | struct cpuinfo_node nodes[] __counted_by(total_nodes); |
| 54 | }; | 54 | }; |
| 55 | 55 | ||
| 56 | 56 | ||
| @@ -105,7 +105,7 @@ static int etap_tramp(char *dev, char *gate, int control_me, · 104 unmodified lines | |||
| 105 | sprintf(data_fd_buf, "%d", data_remote); | 105 | sprintf(data_fd_buf, "%d", data_remote); |
| 106 | sprintf(version_buf, "%d", UML_NET_VERSION); | 106 | sprintf(version_buf, "%d", UML_NET_VERSION); |
| 107 | if (gate != NULL) { | 107 | if (gate != NULL) { |
| 108 | strncpy(gate_buf, gate, 15); | 108 | strscpy(gate_buf, gate, sizeof(gate_buf)); |
| 109 | args = setup_args; | 109 | args = setup_args; |
| 110 | } | 110 | } |
| 111 | else args = nosetup_args; | 111 | else args = nosetup_args; |
| @@ -0,0 +1,14 @@ | |||
| 1 | # Basic kernel hardening options (specific to x86) | ||
| 2 | |||
| 3 | # Modern libc no longer needs a fixed-position mapping in userspace, remove | ||
| 4 | # it as a possible target. | ||
| 5 | CONFIG_LEGACY_VSYSCALL_NONE=y | ||
| 6 | |||
| 7 | # Enable chip-specific IOMMU support. | ||
| 8 | CONFIG_INTEL_IOMMU=y | ||
| 9 | CONFIG_INTEL_IOMMU_DEFAULT_ON=y | ||
| 10 | CONFIG_INTEL_IOMMU_SVM=y | ||
| 11 | CONFIG_AMD_IOMMU=y | ||
| 12 | |||
| 13 | # Enable CET Shadow Stack for userspace. | ||
| 14 | CONFIG_X86_USER_SHADOW_STACK=y | ||
| @@ -51,7 +51,7 @@ struct ivpu_job { · 50 unmodified lines | |||
| 51 | u32 job_id; | 51 | u32 job_id; |
| 52 | u32 engine_idx; | 52 | u32 engine_idx; |
| 53 | size_t bo_count; | 53 | size_t bo_count; |
| 54 | struct ivpu_bo *bos[]; | 54 | struct ivpu_bo *bos[] __counted_by(bo_count); |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file); | 57 | int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file); |
| @@ -1449,10 +1449,9 @@ static struct logical_input *panel_bind_key(const char *name, const char *press, · 1448 unmodified lines | |||
| 1449 | key->rise_time = 1; | 1449 | key->rise_time = 1; |
| 1450 | key->fall_time = 1; | 1450 | key->fall_time = 1; |
| 1451 | 1451 | ||
| 1452 | strncpy(key->u.kbd.press_str, press, sizeof(key->u.kbd.press_str)); | 1452 | strtomem_pad(key->u.kbd.press_str, press, '\0'); |
| 1453 | strncpy(key->u.kbd.repeat_str, repeat, sizeof(key->u.kbd.repeat_str)); | 1453 | strtomem_pad(key->u.kbd.repeat_str, repeat, '\0'); |
| 1454 | strncpy(key->u.kbd.release_str, release, | 1454 | strtomem_pad(key->u.kbd.release_str, release, '\0'); |
| 1455 | sizeof(key->u.kbd.release_str)); | ||
| 1456 | list_add(&key->list, &logical_inputs); | 1455 | list_add(&key->list, &logical_inputs); |
| 1457 | return key; | 1456 | return key; |
| 1458 | } | 1457 | } |
| @@ -555,7 +555,7 @@ struct fifo_buffer { · 554 unmodified lines | |||
| 555 | unsigned int head_index; | 555 | unsigned int head_index; |
| 556 | unsigned int size; | 556 | unsigned int size; |
| 557 | int total; /* sum of all values */ | 557 | int total; /* sum of all values */ |
| 558 | int values[]; | 558 | int values[] __counted_by(size); |
| 559 | }; | 559 | }; |
| 560 | extern struct fifo_buffer *fifo_alloc(unsigned int fifo_size); | 560 | extern struct fifo_buffer *fifo_alloc(unsigned int fifo_size); |
| 561 | 561 | ||
| @@ -450,10 +450,8 @@ int dprc_get_obj(struct fsl_mc_io *mc_io, · 449 unmodified lines | |||
| 450 | obj_desc->ver_major = le16_to_cpu(rsp_params->version_major); | 450 | obj_desc->ver_major = le16_to_cpu(rsp_params->version_major); |
| 451 | obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor); | 451 | obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor); |
| 452 | obj_desc->flags = le16_to_cpu(rsp_params->flags); | 452 | obj_desc->flags = le16_to_cpu(rsp_params->flags); |
| 453 | strncpy(obj_desc->type, rsp_params->type, 16); | 453 | strscpy_pad(obj_desc->type, rsp_params->type, 16); |
| 454 | obj_desc->type[15] = '\0'; | 454 | strscpy_pad(obj_desc->label, rsp_params->label, 16); |
| 455 | strncpy(obj_desc->label, rsp_params->label, 16); | ||
| 456 | obj_desc->label[15] = '\0'; | ||
| 457 | return 0; | 455 | return 0; |
| 458 | } | 456 | } |
| 459 | EXPORT_SYMBOL_GPL(dprc_get_obj); | 457 | EXPORT_SYMBOL_GPL(dprc_get_obj); |
| @@ -491,8 +489,7 @@ int dprc_set_obj_irq(struct fsl_mc_io *mc_io, · 31 unmodified lines | |||
| 491 | cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr); | 489 | cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr); |
| 492 | cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num); | 490 | cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num); |
| 493 | cmd_params->obj_id = cpu_to_le32(obj_id); | 491 | cmd_params->obj_id = cpu_to_le32(obj_id); |
| 494 | strncpy(cmd_params->obj_type, obj_type, 16); | 492 | strscpy_pad(cmd_params->obj_type, obj_type, 16); |
| 495 | cmd_params->obj_type[15] = '\0'; | ||
| 496 | 493 | ||
| 497 | /* send command to mc*/ | 494 | /* send command to mc*/ |
| 498 | return mc_send_command(mc_io, &cmd); | 495 | return mc_send_command(mc_io, &cmd); |
| @@ -564,8 +561,7 @@ int dprc_get_obj_region(struct fsl_mc_io *mc_io, · 65 unmodified lines | |||
| 564 | cmd_params = (struct dprc_cmd_get_obj_region *)cmd.params; | 561 | cmd_params = (struct dprc_cmd_get_obj_region *)cmd.params; |
| 565 | cmd_params->obj_id = cpu_to_le32(obj_id); | 562 | cmd_params->obj_id = cpu_to_le32(obj_id); |
| 566 | cmd_params->region_index = region_index; | 563 | cmd_params->region_index = region_index; |
| 567 | strncpy(cmd_params->obj_type, obj_type, 16); | 564 | strscpy_pad(cmd_params->obj_type, obj_type, 16); |
| 568 | cmd_params->obj_type[15] = '\0'; | ||
| 569 | 565 | ||
| 570 | /* send command to mc*/ | 566 | /* send command to mc*/ |
| 571 | err = mc_send_command(mc_io, &cmd); | 567 | err = mc_send_command(mc_io, &cmd); |
| @@ -106,7 +106,7 @@ struct port_buffer { · 105 unmodified lines | |||
| 106 | unsigned int sgpages; | 106 | unsigned int sgpages; |
| 107 | 107 | ||
| 108 | /* sg is used if spages > 0. sg must be the last in is struct */ | 108 | /* sg is used if spages > 0. sg must be the last in is struct */ |
| 109 | struct scatterlist sg[]; | 109 | struct scatterlist sg[] __counted_by(sgpages); |
| 110 | }; | 110 | }; |
| 111 | 111 | ||
| 112 | /* | 112 | /* |
| @@ -1650,7 +1650,7 @@ static void __cpufreq_offline(unsigned int cpu, struct cpufreq_policy *policy) · 1649 unmodified lines | |||
| 1650 | } | 1650 | } |
| 1651 | 1651 | ||
| 1652 | if (has_target()) | 1652 | if (has_target()) |
| 1653 | strncpy(policy->last_governor, policy->governor->name, | 1653 | strscpy(policy->last_governor, policy->governor->name, |
| 1654 | CPUFREQ_NAME_LEN); | 1654 | CPUFREQ_NAME_LEN); |
| 1655 | else | 1655 | else |
| 1656 | policy->last_policy = policy->policy; | 1656 | policy->last_policy = policy->policy; |
| @@ -2996,7 +2996,7 @@ static int __init cpufreq_core_init(void) · 1339 unmodified lines | |||
| 2996 | BUG_ON(!cpufreq_global_kobject); | 2996 | BUG_ON(!cpufreq_global_kobject); |
| 2997 | 2997 | ||
| 2998 | if (!strlen(default_governor)) | 2998 | if (!strlen(default_governor)) |
| 2999 | strncpy(default_governor, gov->name, CPUFREQ_NAME_LEN); | 2999 | strscpy(default_governor, gov->name, CPUFREQ_NAME_LEN); |
| 3000 | 3000 | ||
| 3001 | return 0; | 3001 | return 0; |
| 3002 | } | 3002 | } |
| @@ -84,8 +84,8 @@ static int init_state_node(struct cpuidle_state *idle_state, · 83 unmodified lines | |||
| 84 | * replace with kstrdup and pointer assignment when name | 84 | * replace with kstrdup and pointer assignment when name |
| 85 | * and desc become string pointers | 85 | * and desc become string pointers |
| 86 | */ | 86 | */ |
| 87 | strncpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN - 1); | 87 | strscpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN); |
| 88 | strncpy(idle_state->desc, desc, CPUIDLE_DESC_LEN - 1); | 88 | strscpy(idle_state->desc, desc, CPUIDLE_DESC_LEN); |
| 89 | return 0; | 89 | return 0; |
| 90 | } | 90 | } |
| 91 | 91 | ||
| @@ -229,7 +229,7 @@ static ssize_t channel_dimm_label_store(struct device *dev, · 228 unmodified lines | |||
| 229 | if (copy_count == 0 || copy_count >= sizeof(rank->dimm->label)) | 229 | if (copy_count == 0 || copy_count >= sizeof(rank->dimm->label)) |
| 230 | return -EINVAL; | 230 | return -EINVAL; |
| 231 | 231 | ||
| 232 | strncpy(rank->dimm->label, data, copy_count); | 232 | memcpy(rank->dimm->label, data, copy_count); |
| 233 | rank->dimm->label[copy_count] = '\0'; | 233 | rank->dimm->label[copy_count] = '\0'; |
| 234 | 234 | ||
| 235 | return count; | 235 | return count; |
| @@ -535,7 +535,7 @@ static ssize_t dimmdev_label_store(struct device *dev, · 299 unmodified lines | |||
| 535 | if (copy_count == 0 || copy_count >= sizeof(dimm->label)) | 535 | if (copy_count == 0 || copy_count >= sizeof(dimm->label)) |
| 536 | return -EINVAL; | 536 | return -EINVAL; |
| 537 | 537 | ||
| 538 | strncpy(dimm->label, data, copy_count); | 538 | memcpy(dimm->label, data, copy_count); |
| 539 | dimm->label[copy_count] = '\0'; | 539 | dimm->label[copy_count] = '\0'; |
| 540 | 540 | ||
| 541 | return count; | 541 | return count; |
| @@ -610,7 +610,7 @@ static int debugfs_show(struct seq_file *m, void *p) · 609 unmodified lines | |||
| 610 | } | 610 | } |
| 611 | 611 | ||
| 612 | len = strlen(filename); | 612 | len = strlen(filename); |
| 613 | strncpy(namevirt, filename, namesize); | 613 | strscpy_pad(namevirt, filename, namesize); |
| 614 | 614 | ||
| 615 | err = mrq_debugfs_read(bpmp, namephys, len, dataphys, datasize, | 615 | err = mrq_debugfs_read(bpmp, namephys, len, dataphys, datasize, |
| 616 | &nbytes); | 616 | &nbytes); |
| @@ -661,7 +661,7 @@ static ssize_t debugfs_store(struct file *file, const char __user *buf, · 44 unmodified lines | |||
| 661 | } | 661 | } |
| 662 | 662 | ||
| 663 | len = strlen(filename); | 663 | len = strlen(filename); |
| 664 | strncpy(namevirt, filename, namesize); | 664 | strscpy_pad(namevirt, filename, namesize); |
| 665 | 665 | ||
| 666 | if (copy_from_user(datavirt, buf, count)) { | 666 | if (copy_from_user(datavirt, buf, count)) { |
| 667 | err = -EFAULT; | 667 | err = -EFAULT; |
| @@ -503,7 +503,7 @@ int gud_pipe_check(struct drm_simple_display_pipe *pipe, · 502 unmodified lines | |||
| 503 | return -ENOENT; | 503 | return -ENOENT; |
| 504 | 504 | ||
| 505 | len = struct_size(req, properties, | 505 | len = struct_size(req, properties, |
| 506 | GUD_PROPERTIES_MAX_NUM + GUD_CONNECTOR_PROPERTIES_MAX_NUM); | 506 | size_add(GUD_PROPERTIES_MAX_NUM, GUD_CONNECTOR_PROPERTIES_MAX_NUM)); |
| 507 | req = kzalloc(len, GFP_KERNEL); | 507 | req = kzalloc(len, GFP_KERNEL); |
| 508 | if (!req) | 508 | if (!req) |
| 509 | return -ENOMEM; | 509 | return -ENOMEM; |
| @@ -67,7 +67,7 @@ struct nouveau_svm { · 66 unmodified lines | |||
| 67 | struct nouveau_svmm *svmm; | 67 | struct nouveau_svmm *svmm; |
| 68 | } **fault; | 68 | } **fault; |
| 69 | int fault_nr; | 69 | int fault_nr; |
| 70 | } buffer[1]; | 70 | } buffer[]; |
| 71 | }; | 71 | }; |
| 72 | 72 | ||
| 73 | #define FAULT_ACCESS_READ 0 | 73 | #define FAULT_ACCESS_READ 0 |
| @@ -1063,7 +1063,8 @@ nouveau_svm_init(struct nouveau_drm *drm) · 989 unmodified lines | |||
| 1063 | if (drm->client.device.info.family > NV_DEVICE_INFO_V0_PASCAL) | 1063 | if (drm->client.device.info.family > NV_DEVICE_INFO_V0_PASCAL) |
| 1064 | return; | 1064 | return; |
| 1065 | 1065 | ||
| 1066 | if (!(drm->svm = svm = kzalloc(sizeof(*drm->svm), GFP_KERNEL))) | 1066 | drm->svm = svm = kzalloc(struct_size(drm->svm, buffer, 1), GFP_KERNEL); |
| 1067 | if (!drm->svm) | ||
| 1067 | return; | 1068 | return; |
| 1068 | 1069 | ||
| 1069 | drm->svm->drm = drm; | 1070 | drm->svm->drm = drm; |
| @@ -639,9 +639,9 @@ static int pcmidi_snd_initialise(struct pcmidi_snd *pm) · 638 unmodified lines | |||
| 639 | goto fail; | 639 | goto fail; |
| 640 | } | 640 | } |
| 641 | 641 | ||
| 642 | strncpy(card->driver, shortname, sizeof(card->driver)); | 642 | strscpy(card->driver, shortname, sizeof(card->driver)); |
| 643 | strncpy(card->shortname, shortname, sizeof(card->shortname)); | 643 | strscpy(card->shortname, shortname, sizeof(card->shortname)); |
| 644 | strncpy(card->longname, longname, sizeof(card->longname)); | 644 | strscpy(card->longname, longname, sizeof(card->longname)); |
| 645 | 645 | ||
| 646 | /* Set up rawmidi */ | 646 | /* Set up rawmidi */ |
| 647 | err = snd_rawmidi_new(card, card->shortname, 0, | 647 | err = snd_rawmidi_new(card, card->shortname, 0, |
| @@ -652,7 +652,7 @@ static int pcmidi_snd_initialise(struct pcmidi_snd *pm) · 4 unmodified lines | |||
| 652 | goto fail; | 652 | goto fail; |
| 653 | } | 653 | } |
| 654 | pm->rwmidi = rwmidi; | 654 | pm->rwmidi = rwmidi; |
| 655 | strncpy(rwmidi->name, card->shortname, sizeof(rwmidi->name)); | 655 | strscpy(rwmidi->name, card->shortname, sizeof(rwmidi->name)); |
| 656 | rwmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT; | 656 | rwmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT; |
| 657 | rwmidi->private_data = pm; | 657 | rwmidi->private_data = pm; |
| 658 | 658 | ||
| @@ -796,14 +796,13 @@ static int read_capabilities(struct acpi_power_meter_resource *resource) · 795 unmodified lines | |||
| 796 | goto error; | 796 | goto error; |
| 797 | } | 797 | } |
| 798 | 798 | ||
| 799 | *str = kcalloc(element->string.length + 1, sizeof(u8), | 799 | *str = kmemdup_nul(element->string.pointer, element->string.length, |
| 800 | GFP_KERNEL); | 800 | GFP_KERNEL); |
| 801 | if (!*str) { | 801 | if (!*str) { |
| 802 | res = -ENOMEM; | 802 | res = -ENOMEM; |
| 803 | goto error; | 803 | goto error; |
| 804 | } | 804 | } |
| 805 | 805 | ||
| 806 | strncpy(*str, element->string.pointer, element->string.length); | ||
| 807 | str++; | 806 | str++; |
| 808 | } | 807 | } |
| 809 | 808 | ||
| @@ -300,7 +300,7 @@ static int asus_wmi_sensor_info(int index, struct asus_wmi_sensor_info *s) · 299 unmodified lines | |||
| 300 | goto out_free_obj; | 300 | goto out_free_obj; |
| 301 | } | 301 | } |
| 302 | 302 | ||
| 303 | strncpy(s->name, name_obj.string.pointer, sizeof(s->name) - 1); | 303 | strscpy(s->name, name_obj.string.pointer, sizeof(s->name)); |
| 304 | 304 | ||
| 305 | data_type_obj = obj->package.elements[1]; | 305 | data_type_obj = obj->package.elements[1]; |
| 306 | if (data_type_obj.type != ACPI_TYPE_INTEGER) { | 306 | if (data_type_obj.type != ACPI_TYPE_INTEGER) { |
| @@ -234,7 +234,7 @@ static int get_sensor_index_attr(const char *name, u32 *index, char *attr) · 233 unmodified lines | |||
| 234 | if (copy_len >= sizeof(buf)) | 234 | if (copy_len >= sizeof(buf)) |
| 235 | return -EINVAL; | 235 | return -EINVAL; |
| 236 | 236 | ||
| 237 | strncpy(buf, hash_pos + 1, copy_len); | 237 | memcpy(buf, hash_pos + 1, copy_len); |
| 238 | 238 | ||
| 239 | err = kstrtou32(buf, 10, index); | 239 | err = kstrtou32(buf, 10, index); |
| 240 | if (err) | 240 | if (err) |
| @@ -73,7 +73,7 @@ struct intmux_data { · 72 unmodified lines | |||
| 73 | void __iomem *regs; | 73 | void __iomem *regs; |
| 74 | struct clk *ipg_clk; | 74 | struct clk *ipg_clk; |
| 75 | int channum; | 75 | int channum; |
| 76 | struct intmux_irqchip_data irqchip_data[]; | 76 | struct intmux_irqchip_data irqchip_data[] __counted_by(channum); |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | static void imx_intmux_irq_mask(struct irq_data *d) | 79 | static void imx_intmux_irq_mask(struct irq_data *d) |
| @@ -732,7 +732,7 @@ u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]) · 731 unmodified lines | |||
| 732 | u16 ret; | 732 | u16 ret; |
| 733 | 733 | ||
| 734 | if (contr == 0) { | 734 | if (contr == 0) { |
| 735 | strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); | 735 | strscpy_pad(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); |
| 736 | return CAPI_NOERROR; | 736 | return CAPI_NOERROR; |
| 737 | } | 737 | } |
| 738 | 738 | ||
| @@ -740,7 +740,7 @@ u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]) · 1 unmodified line | |||
| 740 | 740 | ||
| 741 | ctr = get_capi_ctr_by_nr(contr); | 741 | ctr = get_capi_ctr_by_nr(contr); |
| 742 | if (ctr && ctr->state == CAPI_CTR_RUNNING) { | 742 | if (ctr && ctr->state == CAPI_CTR_RUNNING) { |
| 743 | strncpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN); | 743 | strscpy_pad(buf, ctr->manu, CAPI_MANUFACTURER_LEN); |
| 744 | ret = CAPI_NOERROR; | 744 | ret = CAPI_NOERROR; |
| 745 | } else | 745 | } else |
| 746 | ret = CAPI_REGNOTINSTALLED; | 746 | ret = CAPI_REGNOTINSTALLED; |
| @@ -96,7 +96,7 @@ struct mISDNclock · 95 unmodified lines | |||
| 96 | printk(KERN_ERR "%s: No memory for clock entry.\n", __func__); | 96 | printk(KERN_ERR "%s: No memory for clock entry.\n", __func__); |
| 97 | return NULL; | 97 | return NULL; |
| 98 | } | 98 | } |
| 99 | strncpy(iclock->name, name, sizeof(iclock->name) - 1); | 99 | strscpy(iclock->name, name, sizeof(iclock->name)); |
| 100 | iclock->pri = pri; | 100 | iclock->pri = pri; |
| 101 | iclock->priv = priv; | 101 | iclock->priv = priv; |
| 102 | iclock->ctl = ctl; | 102 | iclock->ctl = ctl; |
| @@ -108,7 +108,7 @@ struct zynqmp_ipi_pdata { · 107 unmodified lines | |||
| 108 | unsigned int method; | 108 | unsigned int method; |
| 109 | u32 local_id; | 109 | u32 local_id; |
| 110 | int num_mboxes; | 110 | int num_mboxes; |
| 111 | struct zynqmp_ipi_mbox ipi_mboxes[]; | 111 | struct zynqmp_ipi_mbox ipi_mboxes[] __counted_by(num_mboxes); |
| 112 | }; | 112 | }; |
| 113 | 113 | ||
| 114 | static struct device_driver zynqmp_ipi_mbox_driver = { | 114 | static struct device_driver zynqmp_ipi_mbox_driver = { |
| @@ -26,7 +26,7 @@ struct prison_region { · 25 unmodified lines | |||
| 26 | struct dm_bio_prison { | 26 | struct dm_bio_prison { |
| 27 | mempool_t cell_pool; | 27 | mempool_t cell_pool; |
| 28 | unsigned int num_locks; | 28 | unsigned int num_locks; |
| 29 | struct prison_region regions[]; | 29 | struct prison_region regions[] __counted_by(num_locks); |
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | static struct kmem_cache *_cell_cache; | 32 | static struct kmem_cache *_cell_cache; |
| @@ -224,7 +224,7 @@ struct crypt_config { · 223 unmodified lines | |||
| 224 | struct mutex bio_alloc_lock; | 224 | struct mutex bio_alloc_lock; |
| 225 | 225 | ||
| 226 | u8 *authenc_key; /* space for keys in authenc() format (if used) */ | 226 | u8 *authenc_key; /* space for keys in authenc() format (if used) */ |
| 227 | u8 key[]; | 227 | u8 key[] __counted_by(key_size); |
| 228 | }; | 228 | }; |
| 229 | 229 | ||
| 230 | #define MIN_IOS 64 | 230 | #define MIN_IOS 64 |
| @@ -254,7 +254,7 @@ struct raid_set { · 253 unmodified lines | |||
| 254 | int mode; | 254 | int mode; |
| 255 | } journal_dev; | 255 | } journal_dev; |
| 256 | 256 | ||
| 257 | struct raid_dev dev[]; | 257 | struct raid_dev dev[] __counted_by(raid_disks); |
| 258 | }; | 258 | }; |
| 259 | 259 | ||
| 260 | static void rs_config_backup(struct raid_set *rs, struct rs_layout *l) | 260 | static void rs_config_backup(struct raid_set *rs, struct rs_layout *l) |
| @@ -56,7 +56,7 @@ struct dm_stat { · 55 unmodified lines | |||
| 56 | size_t percpu_alloc_size; | 56 | size_t percpu_alloc_size; |
| 57 | size_t histogram_alloc_size; | 57 | size_t histogram_alloc_size; |
| 58 | struct dm_stat_percpu *stat_percpu[NR_CPUS]; | 58 | struct dm_stat_percpu *stat_percpu[NR_CPUS]; |
| 59 | struct dm_stat_shared stat_shared[]; | 59 | struct dm_stat_shared stat_shared[] __counted_by(n_entries); |
| 60 | }; | 60 | }; |
| 61 | 61 | ||
| 62 | #define STAT_PRECISE_TIMESTAMPS 1 | 62 | #define STAT_PRECISE_TIMESTAMPS 1 |
| @@ -44,7 +44,7 @@ struct stripe_c { · 43 unmodified lines | |||
| 44 | /* Work struct used for triggering events*/ | 44 | /* Work struct used for triggering events*/ |
| 45 | struct work_struct trigger_event; | 45 | struct work_struct trigger_event; |
| 46 | 46 | ||
| 47 | struct stripe stripe[]; | 47 | struct stripe stripe[] __counted_by(stripes); |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | /* | 50 | /* |
| @@ -6,12 +6,14 @@ · 5 unmodified lines | |||
| 6 | * test source files. | 6 | * test source files. |
| 7 | */ | 7 | */ |
| 8 | #include "lkdtm.h" | 8 | #include "lkdtm.h" |
| 9 | #include <linux/cpu.h> | ||
| 9 | #include <linux/list.h> | 10 | #include <linux/list.h> |
| 10 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
| 11 | #include <linux/sched/signal.h> | 12 | #include <linux/sched/signal.h> |
| 12 | #include <linux/sched/task_stack.h> | 13 | #include <linux/sched/task_stack.h> |
| 13 | #include <linux/uaccess.h> | ||
| 14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
| 15 | #include <linux/stop_machine.h> | ||
| 16 | #include <linux/uaccess.h> | ||
| 15 | 17 | ||
| 16 | #if IS_ENABLED(CONFIG_X86_32) && !IS_ENABLED(CONFIG_UML) | 18 | #if IS_ENABLED(CONFIG_X86_32) && !IS_ENABLED(CONFIG_UML) |
| 17 | #include <asm/desc.h> | 19 | #include <asm/desc.h> |
| @@ -73,6 +75,31 @@ static void lkdtm_PANIC(void) · 55 unmodified lines | |||
| 73 | panic("dumptest"); | 75 | panic("dumptest"); |
| 74 | } | 76 | } |
| 75 | 77 | ||
| 78 | static int panic_stop_irqoff_fn(void *arg) | ||
| 79 | { | ||
| 80 | atomic_t *v = arg; | ||
| 81 | |||
| 82 | /* | ||
| 83 | * As stop_machine() disables interrupts, all CPUs within this function | ||
| 84 | * have interrupts disabled and cannot take a regular IPI. | ||
| 85 | * | ||
| 86 | * The last CPU which enters here will trigger a panic, and as all CPUs | ||
| 87 | * cannot take a regular IPI, we'll only be able to stop secondaries if | ||
| 88 | * smp_send_stop() or crash_smp_send_stop() uses an NMI. | ||
| 89 | */ | ||
| 90 | if (atomic_inc_return(v) == num_online_cpus()) | ||
| 91 | panic("panic stop irqoff test"); | ||
| 92 | |||
| 93 | for (;;) | ||
| 94 | cpu_relax(); | ||
| 95 | } | ||
| 96 | |||
| 97 | static void lkdtm_PANIC_STOP_IRQOFF(void) | ||
| 98 | { | ||
| 99 | atomic_t v = ATOMIC_INIT(0); | ||
| 100 | stop_machine(panic_stop_irqoff_fn, &v, cpu_online_mask); | ||
| 101 | } | ||
| 102 | |||
| 76 | static void lkdtm_BUG(void) | 103 | static void lkdtm_BUG(void) |
| 77 | { | 104 | { |
| 78 | BUG(); | 105 | BUG(); |
| @@ -638,6 +665,7 @@ static noinline void lkdtm_CORRUPT_PAC(void) · 559 unmodified lines | |||
| 638 | 665 | ||
| 639 | static struct crashtype crashtypes[] = { | 666 | static struct crashtype crashtypes[] = { |
| 640 | CRASHTYPE(PANIC), | 667 | CRASHTYPE(PANIC), |
| 668 | CRASHTYPE(PANIC_STOP_IRQOFF), | ||
| 641 | CRASHTYPE(BUG), | 669 | CRASHTYPE(BUG), |
| 642 | CRASHTYPE(WARNING), | 670 | CRASHTYPE(WARNING), |
| 643 | CRASHTYPE(WARNING_MESSAGE), | 671 | CRASHTYPE(WARNING_MESSAGE), |
| @@ -60,7 +60,7 @@ struct reset_control { · 59 unmodified lines | |||
| 60 | struct reset_control_array { | 60 | struct reset_control_array { |
| 61 | struct reset_control base; | 61 | struct reset_control base; |
| 62 | unsigned int num_rstcs; | 62 | unsigned int num_rstcs; |
| 63 | struct reset_control *rstc[]; | 63 | struct reset_control *rstc[] __counted_by(num_rstcs); |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | static const char *rcdev_name(struct reset_controller_dev *rcdev) | 66 | static const char *rcdev_name(struct reset_controller_dev *rcdev) |
| @@ -1185,6 +1185,7 @@ of_reset_control_array_get(struct device_node *np, bool shared, bool optional, · 1118 unmodified lines | |||
| 1185 | resets = kzalloc(struct_size(resets, rstc, num), GFP_KERNEL); | 1185 | resets = kzalloc(struct_size(resets, rstc, num), GFP_KERNEL); |
| 1186 | if (!resets) | 1186 | if (!resets) |
| 1187 | return ERR_PTR(-ENOMEM); | 1187 | return ERR_PTR(-ENOMEM); |
| 1188 | resets->num_rstcs = num; | ||
| 1188 | 1189 | ||
| 1189 | for (i = 0; i < num; i++) { | 1190 | for (i = 0; i < num; i++) { |
| 1190 | rstc = __of_reset_control_get(np, NULL, i, shared, optional, | 1191 | rstc = __of_reset_control_get(np, NULL, i, shared, optional, |
| @@ -1193,7 +1194,6 @@ of_reset_control_array_get(struct device_node *np, bool shared, bool optional, · 2 unmodified lines | |||
| 1193 | goto err_rst; | 1194 | goto err_rst; |
| 1194 | resets->rstc[i] = rstc; | 1195 | resets->rstc[i] = rstc; |
| 1195 | } | 1196 | } |
| 1196 | resets->num_rstcs = num; | ||
| 1197 | resets->base.array = true; | 1197 | resets->base.array = true; |
| 1198 | 1198 | ||
| 1199 | return &resets->base; | 1199 | return &resets->base; |
| @@ -585,7 +585,7 @@ struct tsens_priv { · 584 unmodified lines | |||
| 585 | struct dentry *debug_root; | 585 | struct dentry *debug_root; |
| 586 | struct dentry *debug; | 586 | struct dentry *debug; |
| 587 | 587 | ||
| 588 | struct tsens_sensor sensor[]; | 588 | struct tsens_sensor sensor[] __counted_by(num_sensors); |
| 589 | }; | 589 | }; |
| 590 | 590 | ||
| 591 | /** | 591 | /** |
| @@ -1018,7 +1018,8 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id, · 1017 unmodified lines | |||
| 1018 | size_t size; | 1018 | size_t size; |
| 1019 | 1019 | ||
| 1020 | /* instance init */ | 1020 | /* instance init */ |
| 1021 | size = struct_size(instance, urbs, num_rcv_urbs + num_snd_urbs); | 1021 | size = struct_size(instance, urbs, |
| 1022 | size_add(num_rcv_urbs, num_snd_urbs)); | ||
| 1022 | instance = kzalloc(size, GFP_KERNEL); | 1023 | instance = kzalloc(size, GFP_KERNEL); |
| 1023 | if (!instance) | 1024 | if (!instance) |
| 1024 | return -ENOMEM; | 1025 | return -ENOMEM; |
| @@ -202,7 +202,7 @@ struct ffs_epfile { · 201 unmodified lines | |||
| 202 | struct ffs_buffer { | 202 | struct ffs_buffer { |
| 203 | size_t length; | 203 | size_t length; |
| 204 | char *data; | 204 | char *data; |
| 205 | char storage[]; | 205 | char storage[] __counted_by(length); |
| 206 | }; | 206 | }; |
| 207 | 207 | ||
| 208 | /* ffs_io_data structure ***************************************************/ | 208 | /* ffs_io_data structure ***************************************************/ |
| @@ -99,7 +99,7 @@ struct f_midi { · 98 unmodified lines | |||
| 99 | unsigned int in_last_port; | 99 | unsigned int in_last_port; |
| 100 | unsigned char free_ref; | 100 | unsigned char free_ref; |
| 101 | 101 | ||
| 102 | struct gmidi_in_port in_ports_array[/* in_ports */]; | 102 | struct gmidi_in_port in_ports_array[] __counted_by(in_ports); |
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | static inline struct f_midi *func_to_midi(struct usb_function *f) | 105 | static inline struct f_midi *func_to_midi(struct usb_function *f) |
| @@ -1349,6 +1349,7 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) · 1243 unmodified lines | |||
| 1349 | status = -ENOMEM; | 1349 | status = -ENOMEM; |
| 1350 | goto setup_fail; | 1350 | goto setup_fail; |
| 1351 | } | 1351 | } |
| 1352 | midi->in_ports = opts->in_ports; | ||
| 1352 | 1353 | ||
| 1353 | for (i = 0; i < opts->in_ports; i++) | 1354 | for (i = 0; i < opts->in_ports; i++) |
| 1354 | midi->in_ports_array[i].cable = i; | 1355 | midi->in_ports_array[i].cable = i; |
| @@ -1359,7 +1360,6 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi) · 4 unmodified lines | |||
| 1359 | status = -ENOMEM; | 1360 | status = -ENOMEM; |
| 1360 | goto midi_free; | 1361 | goto midi_free; |
| 1361 | } | 1362 | } |
| 1362 | midi->in_ports = opts->in_ports; | ||
| 1363 | midi->out_ports = opts->out_ports; | 1363 | midi->out_ports = opts->out_ports; |
| 1364 | midi->index = opts->index; | 1364 | midi->index = opts->index; |
| 1365 | midi->buflen = opts->buflen; | 1365 | midi->buflen = opts->buflen; |
| @@ -337,7 +337,7 @@ typedef struct urb_priv { · 336 unmodified lines | |||
| 337 | u16 length; // # tds in this request | 337 | u16 length; // # tds in this request |
| 338 | u16 td_cnt; // tds already serviced | 338 | u16 td_cnt; // tds already serviced |
| 339 | struct list_head pending; | 339 | struct list_head pending; |
| 340 | struct td *td[]; // all TDs in this request | 340 | struct td *td[] __counted_by(length); // all TDs in this request |
| 341 | 341 | ||
| 342 | } urb_priv_t; | 342 | } urb_priv_t; |
| 343 | 343 | ||
| @@ -1666,7 +1666,7 @@ struct xhci_scratchpad { · 1665 unmodified lines | |||
| 1666 | struct urb_priv { | 1666 | struct urb_priv { |
| 1667 | int num_tds; | 1667 | int num_tds; |
| 1668 | int num_tds_done; | 1668 | int num_tds_done; |
| 1669 | struct xhci_td td[]; | 1669 | struct xhci_td td[] __counted_by(num_tds); |
| 1670 | }; | 1670 | }; |
| 1671 | 1671 | ||
| 1672 | /* | 1672 | /* |
| @@ -60,7 +60,7 @@ struct vm_memory_region_batch { · 59 unmodified lines | |||
| 60 | u16 reserved[3]; | 60 | u16 reserved[3]; |
| 61 | u32 regions_num; | 61 | u32 regions_num; |
| 62 | u64 regions_gpa; | 62 | u64 regions_gpa; |
| 63 | struct vm_memory_region_op regions_op[]; | 63 | struct vm_memory_region_op regions_op[] __counted_by(regions_num); |
| 64 | }; | 64 | }; |
| 65 | 65 | ||
| 66 | /** | 66 | /** |
| @@ -250,11 +250,11 @@ int acrn_vm_ram_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap) · 249 unmodified lines | |||
| 250 | ret = -ENOMEM; | 250 | ret = -ENOMEM; |
| 251 | goto unmap_kernel_map; | 251 | goto unmap_kernel_map; |
| 252 | } | 252 | } |
| 253 | regions_info->regions_num = nr_regions; | ||
| 253 | 254 | ||
| 254 | /* Fill each vm_memory_region_op */ | 255 | /* Fill each vm_memory_region_op */ |
| 255 | vm_region = regions_info->regions_op; | 256 | vm_region = regions_info->regions_op; |
| 256 | regions_info->vmid = vm->vmid; | 257 | regions_info->vmid = vm->vmid; |
| 257 | regions_info->regions_num = nr_regions; | ||
| 258 | regions_info->regions_gpa = virt_to_phys(vm_region); | 258 | regions_info->regions_gpa = virt_to_phys(vm_region); |
| 259 | user_vm_pa = memmap->user_vm_pa; | 259 | user_vm_pa = memmap->user_vm_pa; |
| 260 | i = 0; | 260 | i = 0; |
| @@ -87,7 +87,7 @@ struct afs_addr_list { · 86 unmodified lines | |||
| 87 | enum dns_lookup_status status:8; | 87 | enum dns_lookup_status status:8; |
| 88 | unsigned long failed; /* Mask of addrs that failed locally/ICMP */ | 88 | unsigned long failed; /* Mask of addrs that failed locally/ICMP */ |
| 89 | unsigned long responded; /* Mask of addrs that responded */ | 89 | unsigned long responded; /* Mask of addrs that responded */ |
| 90 | struct sockaddr_rxrpc addrs[]; | 90 | struct sockaddr_rxrpc addrs[] __counted_by(max_addrs); |
| 91 | #define AFS_MAX_ADDRESSES ((unsigned int)(sizeof(unsigned long) * 8)) | 91 | #define AFS_MAX_ADDRESSES ((unsigned int)(sizeof(unsigned long) * 8)) |
| 92 | }; | 92 | }; |
| 93 | 93 | ||
| @@ -705,7 +705,7 @@ struct afs_permits { · 611 unmodified lines | |||
| 705 | refcount_t usage; | 705 | refcount_t usage; |
| 706 | unsigned short nr_permits; /* Number of records */ | 706 | unsigned short nr_permits; /* Number of records */ |
| 707 | bool invalidated; /* Invalidated due to key change */ | 707 | bool invalidated; /* Invalidated due to key change */ |
| 708 | struct afs_permit permits[]; /* List of permits sorted by key pointer */ | 708 | struct afs_permit permits[] __counted_by(nr_permits); /* List of permits sorted by key pointer */ |
| 709 | }; | 709 | }; |
| 710 | 710 | ||
| 711 | /* | 711 | /* |
| @@ -51,7 +51,7 @@ struct nfs4_file_layout_dsaddr { · 50 unmodified lines | |||
| 51 | u32 stripe_count; | 51 | u32 stripe_count; |
| 52 | u8 *stripe_indices; | 52 | u8 *stripe_indices; |
| 53 | u32 ds_num; | 53 | u32 ds_num; |
| 54 | struct nfs4_pnfs_ds *ds_list[]; | 54 | struct nfs4_pnfs_ds *ds_list[] __counted_by(ds_num); |
| 55 | }; | 55 | }; |
| 56 | 56 | ||
| 57 | struct nfs4_filelayout_segment { | 57 | struct nfs4_filelayout_segment { |
| @@ -99,7 +99,7 @@ struct nfs4_ff_layout_segment { · 98 unmodified lines | |||
| 99 | u64 stripe_unit; | 99 | u64 stripe_unit; |
| 100 | u32 flags; | 100 | u32 flags; |
| 101 | u32 mirror_array_cnt; | 101 | u32 mirror_array_cnt; |
| 102 | struct nfs4_ff_layout_mirror *mirror_array[]; | 102 | struct nfs4_ff_layout_mirror *mirror_array[] __counted_by(mirror_array_cnt); |
| 103 | }; | 103 | }; |
| 104 | 104 | ||
| 105 | struct nfs4_flexfile_layout { | 105 | struct nfs4_flexfile_layout { |
| @@ -37,7 +37,7 @@ struct ocfs2_slot_info { · 36 unmodified lines | |||
| 37 | unsigned int si_blocks; | 37 | unsigned int si_blocks; |
| 38 | struct buffer_head **si_bh; | 38 | struct buffer_head **si_bh; |
| 39 | unsigned int si_num_slots; | 39 | unsigned int si_num_slots; |
| 40 | struct ocfs2_slot si_slots[]; | 40 | struct ocfs2_slot si_slots[] __counted_by(si_num_slots); |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | 43 | ||
| @@ -278,7 +278,7 @@ struct ceph_osd_request { · 277 unmodified lines | |||
| 278 | int r_attempts; | 278 | int r_attempts; |
| 279 | u32 r_map_dne_bound; | 279 | u32 r_map_dne_bound; |
| 280 | 280 | ||
| 281 | struct ceph_osd_req_op r_ops[]; | 281 | struct ceph_osd_req_op r_ops[] __counted_by(r_num_ops); |
| 282 | }; | 282 | }; |
| 283 | 283 | ||
| 284 | struct ceph_request_redirect { | 284 | struct ceph_request_redirect { |
| @@ -92,7 +92,7 @@ int parse_crashkernel_low(char *cmdline, unsigned long long system_ram, · 91 unmodified lines | |||
| 92 | struct crash_mem { | 92 | struct crash_mem { |
| 93 | unsigned int max_nr_ranges; | 93 | unsigned int max_nr_ranges; |
| 94 | unsigned int nr_ranges; | 94 | unsigned int nr_ranges; |
| 95 | struct range ranges[]; | 95 | struct range ranges[] __counted_by(max_nr_ranges); |
| 96 | }; | 96 | }; |
| 97 | 97 | ||
| 98 | extern int crash_exclude_mem_range(struct crash_mem *mem, | 98 | extern int crash_exclude_mem_range(struct crash_mem *mem, |
| @@ -12,6 +12,7 @@ · 11 unmodified lines | |||
| 12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
| 13 | #include <linux/key.h> | 13 | #include <linux/key.h> |
| 14 | #include <linux/atomic.h> | 14 | #include <linux/atomic.h> |
| 15 | #include <linux/refcount.h> | ||
| 15 | #include <linux/uidgid.h> | 16 | #include <linux/uidgid.h> |
| 16 | #include <linux/sched.h> | 17 | #include <linux/sched.h> |
| 17 | #include <linux/sched/user.h> | 18 | #include <linux/sched/user.h> |
| @@ -23,7 +24,7 @@ struct inode; · 5 unmodified lines | |||
| 23 | * COW Supplementary groups list | 24 | * COW Supplementary groups list |
| 24 | */ | 25 | */ |
| 25 | struct group_info { | 26 | struct group_info { |
| 26 | atomic_t usage; | 27 | refcount_t usage; |
| 27 | int ngroups; | 28 | int ngroups; |
| 28 | kgid_t gid[]; | 29 | kgid_t gid[]; |
| 29 | } __randomize_layout; | 30 | } __randomize_layout; |
| @@ -39,7 +40,7 @@ struct group_info { · 9 unmodified lines | |||
| 39 | */ | 40 | */ |
| 40 | static inline struct group_info *get_group_info(struct group_info *gi) | 41 | static inline struct group_info *get_group_info(struct group_info *gi) |
| 41 | { | 42 | { |
| 42 | atomic_inc(&gi->usage); | 43 | refcount_inc(&gi->usage); |
| 43 | return gi; | 44 | return gi; |
| 44 | } | 45 | } |
| 45 | 46 | ||
| @@ -49,7 +50,7 @@ static inline struct group_info *get_group_info(struct group_info *gi) · 3 unmodified lines | |||
| 49 | */ | 50 | */ |
| 50 | #define put_group_info(group_info) \ | 51 | #define put_group_info(group_info) \ |
| 51 | do { \ | 52 | do { \ |
| 52 | if (atomic_dec_and_test(&(group_info)->usage)) \ | 53 | if (refcount_dec_and_test(&(group_info)->usage)) \ |
| 53 | groups_free(group_info); \ | 54 | groups_free(group_info); \ |
| 54 | } while (0) | 55 | } while (0) |
| 55 | 56 | ||
| @@ -664,7 +664,7 @@ struct kvm_irq_routing_table { · 663 unmodified lines | |||
| 664 | * Array indexed by gsi. Each entry contains list of irq chips | 664 | * Array indexed by gsi. Each entry contains list of irq chips |
| 665 | * the gsi is connected to. | 665 | * the gsi is connected to. |
| 666 | */ | 666 | */ |
| 667 | struct hlist_head map[]; | 667 | struct hlist_head map[] __counted_by(nr_rt_entries); |
| 668 | }; | 668 | }; |
| 669 | #endif | 669 | #endif |
| 670 | 670 | ||
| @@ -40,6 +40,6 @@ struct gsc_hwmon_platform_data { · 39 unmodified lines | |||
| 40 | unsigned int resolution; | 40 | unsigned int resolution; |
| 41 | unsigned int vreference; | 41 | unsigned int vreference; |
| 42 | unsigned int fan_base; | 42 | unsigned int fan_base; |
| 43 | struct gsc_hwmon_channel channels[]; | 43 | struct gsc_hwmon_channel channels[] __counted_by(nchannels); |
| 44 | }; | 44 | }; |
| 45 | #endif | 45 | #endif |
| @@ -277,10 +277,12 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count, · 276 unmodified lines | |||
| 277 | */ | 277 | */ |
| 278 | #define strtomem_pad(dest, src, pad) do { \ | 278 | #define strtomem_pad(dest, src, pad) do { \ |
| 279 | const size_t _dest_len = __builtin_object_size(dest, 1); \ | 279 | const size_t _dest_len = __builtin_object_size(dest, 1); \ |
| 280 | const size_t _src_len = __builtin_object_size(src, 1); \ | ||
| 280 | \ | 281 | \ |
| 281 | BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ | 282 | BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ |
| 282 | _dest_len == (size_t)-1); \ | 283 | _dest_len == (size_t)-1); \ |
| 283 | memcpy_and_pad(dest, _dest_len, src, strnlen(src, _dest_len), pad); \ | 284 | memcpy_and_pad(dest, _dest_len, src, \ |
| 285 | strnlen(src, min(_src_len, _dest_len)), pad); \ | ||
| 284 | } while (0) | 286 | } while (0) |
| 285 | 287 | ||
| 286 | /** | 288 | /** |
| @@ -298,10 +300,11 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count, · 11 unmodified lines | |||
| 298 | */ | 300 | */ |
| 299 | #define strtomem(dest, src) do { \ | 301 | #define strtomem(dest, src) do { \ |
| 300 | const size_t _dest_len = __builtin_object_size(dest, 1); \ | 302 | const size_t _dest_len = __builtin_object_size(dest, 1); \ |
| 303 | const size_t _src_len = __builtin_object_size(src, 1); \ | ||
| 301 | \ | 304 | \ |
| 302 | BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ | 305 | BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ |
| 303 | _dest_len == (size_t)-1); \ | 306 | _dest_len == (size_t)-1); \ |
| 304 | memcpy(dest, src, min(_dest_len, strnlen(src, _dest_len))); \ | 307 | memcpy(dest, src, strnlen(src, min(_src_len, _dest_len))); \ |
| 305 | } while (0) | 308 | } while (0) |
| 306 | 309 | ||
| 307 | /** | 310 | /** |
| @@ -21,10 +21,10 @@ static int __init early_hostname(char *arg) · 20 unmodified lines | |||
| 21 | { | 21 | { |
| 22 | size_t bufsize = sizeof(init_uts_ns.name.nodename); | 22 | size_t bufsize = sizeof(init_uts_ns.name.nodename); |
| 23 | size_t maxlen = bufsize - 1; | 23 | size_t maxlen = bufsize - 1; |
| 24 | size_t arglen; | 24 | ssize_t arglen; |
| 25 | 25 | ||
| 26 | arglen = strlcpy(init_uts_ns.name.nodename, arg, bufsize); | 26 | arglen = strscpy(init_uts_ns.name.nodename, arg, bufsize); |
| 27 | if (arglen > maxlen) { | 27 | if (arglen < 0) { |
| 28 | pr_warn("hostname parameter exceeds %zd characters and will be truncated", | 28 | pr_warn("hostname parameter exceeds %zd characters and will be truncated", |
| 29 | maxlen); | 29 | maxlen); |
| 30 | } | 30 | } |
| @@ -0,0 +1,98 @@ | |||
| 1 | # Help: Basic kernel hardening options | ||
| 2 | # | ||
| 3 | # These are considered the basic kernel hardening, self-protection, and | ||
| 4 | # attack surface reduction options. They are expected to have low (or | ||
| 5 | # no) performance impact on most workloads, and have a reasonable level | ||
| 6 | # of legacy API removals. | ||
| 7 | |||
| 8 | # Make sure reporting of various hardening actions is possible. | ||
| 9 | CONFIG_BUG=y | ||
| 10 | |||
| 11 | # Basic kernel memory permission enforcement. | ||
| 12 | CONFIG_STRICT_KERNEL_RWX=y | ||
| 13 | CONFIG_STRICT_MODULE_RWX=y | ||
| 14 | CONFIG_VMAP_STACK=y | ||
| 15 | |||
| 16 | # Kernel image and memory ASLR. | ||
| 17 | CONFIG_RANDOMIZE_BASE=y | ||
| 18 | CONFIG_RANDOMIZE_MEMORY=y | ||
| 19 | |||
| 20 | # Randomize allocator freelists, harden metadata. | ||
| 21 | CONFIG_SLAB_FREELIST_RANDOM=y | ||
| 22 | CONFIG_SLAB_FREELIST_HARDENED=y | ||
| 23 | CONFIG_SHUFFLE_PAGE_ALLOCATOR=y | ||
| 24 | CONFIG_RANDOM_KMALLOC_CACHES=y | ||
| 25 | |||
| 26 | # Randomize kernel stack offset on syscall entry. | ||
| 27 | CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y | ||
| 28 | |||
| 29 | # Basic stack frame overflow protection. | ||
| 30 | CONFIG_STACKPROTECTOR=y | ||
| 31 | CONFIG_STACKPROTECTOR_STRONG=y | ||
| 32 | |||
| 33 | # Basic buffer length bounds checking. | ||
| 34 | CONFIG_HARDENED_USERCOPY=y | ||
| 35 | CONFIG_FORTIFY_SOURCE=y | ||
| 36 | |||
| 37 | # Basic array index bounds checking. | ||
| 38 | CONFIG_UBSAN=y | ||
| 39 | CONFIG_UBSAN_TRAP=y | ||
| 40 | CONFIG_UBSAN_BOUNDS=y | ||
| 41 | # CONFIG_UBSAN_SHIFT is not set | ||
| 42 | # CONFIG_UBSAN_DIV_ZERO | ||
| 43 | # CONFIG_UBSAN_UNREACHABLE | ||
| 44 | # CONFIG_UBSAN_BOOL | ||
| 45 | # CONFIG_UBSAN_ENUM | ||
| 46 | # CONFIG_UBSAN_ALIGNMENT | ||
| 47 | CONFIG_UBSAN_SANITIZE_ALL=y | ||
| 48 | |||
| 49 | # Linked list integrity checking. | ||
| 50 | CONFIG_LIST_HARDENED=y | ||
| 51 | |||
| 52 | # Initialize all heap variables to zero on allocation. | ||
| 53 | CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y | ||
| 54 | |||
| 55 | # Initialize all stack variables to zero on function entry. | ||
| 56 | CONFIG_INIT_STACK_ALL_ZERO=y | ||
| 57 | |||
| 58 | # Wipe RAM at reboot via EFI. For more details, see: | ||
| 59 | # https://trustedcomputinggroup.org/resource/pc-client-work-group-platform-reset-attack-mitigation-specification/ | ||
| 60 | # https://bugzilla.redhat.com/show_bug.cgi?id=1532058 | ||
| 61 | CONFIG_RESET_ATTACK_MITIGATION=y | ||
| 62 | |||
| 63 | # Disable DMA between EFI hand-off and the kernel's IOMMU setup. | ||
| 64 | CONFIG_EFI_DISABLE_PCI_DMA=y | ||
| 65 | |||
| 66 | # Force IOMMU TLB invalidation so devices will never be able to access stale | ||
| 67 | # data content. | ||
| 68 | CONFIG_IOMMU_SUPPORT=y | ||
| 69 | CONFIG_IOMMU_DEFAULT_DMA_STRICT=y | ||
| 70 | |||
| 71 | # Do not allow direct physical memory access to non-device memory. | ||
| 72 | CONFIG_STRICT_DEVMEM=y | ||
| 73 | CONFIG_IO_STRICT_DEVMEM=y | ||
| 74 | |||
| 75 | # Provide userspace with seccomp BPF API for syscall attack surface reduction. | ||
| 76 | CONFIG_SECCOMP=y | ||
| 77 | CONFIG_SECCOMP_FILTER=y | ||
| 78 | |||
| 79 | # Provides some protections against SYN flooding. | ||
| 80 | CONFIG_SYN_COOKIES=y | ||
| 81 | |||
| 82 | # Attack surface reduction: do not autoload TTY line disciplines. | ||
| 83 | # CONFIG_LDISC_AUTOLOAD is not set | ||
| 84 | |||
| 85 | # Dangerous; enabling this disables userspace brk ASLR. | ||
| 86 | # CONFIG_COMPAT_BRK is not set | ||
| 87 | |||
| 88 | # Dangerous; exposes kernel text image layout. | ||
| 89 | # CONFIG_PROC_KCORE is not set | ||
| 90 | |||
| 91 | # Dangerous; enabling this disables userspace VDSO ASLR. | ||
| 92 | # CONFIG_COMPAT_VDSO is not set | ||
| 93 | |||
| 94 | # Attack surface reduction: Use the modern PTY interface (devpts) only. | ||
| 95 | # CONFIG_LEGACY_PTYS is not set | ||
| 96 | |||
| 97 | # Attack surface reduction: Use only modesetting video drivers. | ||
| 98 | # CONFIG_DRM_LEGACY is not set | ||
| @@ -36,7 +36,7 @@ do { \ · 35 unmodified lines | |||
| 36 | static struct kmem_cache *cred_jar; | 36 | static struct kmem_cache *cred_jar; |
| 37 | 37 | ||
| 38 | /* init to 2 - one for init_task, one to ensure it is never freed */ | 38 | /* init to 2 - one for init_task, one to ensure it is never freed */ |
| 39 | static struct group_info init_groups = { .usage = ATOMIC_INIT(2) }; | 39 | static struct group_info init_groups = { .usage = REFCOUNT_INIT(2) }; |
| 40 | 40 | ||
| 41 | /* | 41 | /* |
| 42 | * The initial credentials for the initial task | 42 | * The initial credentials for the initial task |
| @@ -19,7 +19,7 @@ struct group_info *groups_alloc(int gidsetsize) · 18 unmodified lines | |||
| 19 | if (!gi) | 19 | if (!gi) |
| 20 | return NULL; | 20 | return NULL; |
| 21 | 21 | ||
| 22 | atomic_set(&gi->usage, 1); | 22 | refcount_set(&gi->usage, 1); |
| 23 | gi->ngroups = gidsetsize; | 23 | gi->ngroups = gidsetsize; |
| 24 | return gi; | 24 | return gi; |
| 25 | } | 25 | } |
| @@ -254,10 +254,10 @@ static int init_uevent_argv(struct kobj_uevent_env *env, const char *subsystem) · 253 unmodified lines | |||
| 254 | int buffer_size = sizeof(env->buf) - env->buflen; | 254 | int buffer_size = sizeof(env->buf) - env->buflen; |
| 255 | int len; | 255 | int len; |
| 256 | 256 | ||
| 257 | len = strlcpy(&env->buf[env->buflen], subsystem, buffer_size); | 257 | len = strscpy(&env->buf[env->buflen], subsystem, buffer_size); |
| 258 | if (len >= buffer_size) { | 258 | if (len < 0) { |
| 259 | pr_warn("init_uevent_argv: buffer size of %d too small, needed %d\n", | 259 | pr_warn("%s: insufficient buffer space (%u left) for %s\n", |
| 260 | buffer_size, len); | 260 | __func__, buffer_size, subsystem); |
| 261 | return -ENOMEM; | 261 | return -ENOMEM; |
| 262 | } | 262 | } |
| 263 | 263 | ||
| @@ -191,12 +191,14 @@ static void partition_struct(tree *fields, unsigned long length, struct partitio · 190 unmodified lines | |||
| 191 | 191 | ||
| 192 | static void performance_shuffle(tree *newtree, unsigned long length, ranctx *prng_state) | 192 | static void performance_shuffle(tree *newtree, unsigned long length, ranctx *prng_state) |
| 193 | { | 193 | { |
| 194 | unsigned long i, x; | 194 | unsigned long i, x, index; |
| 195 | struct partition_group size_group[length]; | 195 | struct partition_group size_group[length]; |
| 196 | unsigned long num_groups = 0; | 196 | unsigned long num_groups = 0; |
| 197 | unsigned long randnum; | 197 | unsigned long randnum; |
| 198 | 198 | ||
| 199 | partition_struct(newtree, length, (struct partition_group *)&size_group, &num_groups); | 199 | partition_struct(newtree, length, (struct partition_group *)&size_group, &num_groups); |
| 200 | |||
| 201 | /* FIXME: this group shuffle is currently a no-op. */ | ||
| 200 | for (i = num_groups - 1; i > 0; i--) { | 202 | for (i = num_groups - 1; i > 0; i--) { |
| 201 | struct partition_group tmp; | 203 | struct partition_group tmp; |
| 202 | randnum = ranval(prng_state) % (i + 1); | 204 | randnum = ranval(prng_state) % (i + 1); |
| @@ -206,11 +208,14 @@ static void performance_shuffle(tree *newtree, unsigned long length, ranctx *prn · 3 unmodified lines | |||
| 206 | } | 208 | } |
| 207 | 209 | ||
| 208 | for (x = 0; x < num_groups; x++) { | 210 | for (x = 0; x < num_groups; x++) { |
| 209 | for (i = size_group[x].start + size_group[x].length - 1; i > size_group[x].start; i--) { | 211 | for (index = size_group[x].length - 1; index > 0; index--) { |
| 210 | tree tmp; | 212 | tree tmp; |
| 213 | |||
| 214 | i = size_group[x].start + index; | ||
| 211 | if (DECL_BIT_FIELD_TYPE(newtree[i])) | 215 | if (DECL_BIT_FIELD_TYPE(newtree[i])) |
| 212 | continue; | 216 | continue; |
| 213 | randnum = ranval(prng_state) % (i + 1); | 217 | randnum = ranval(prng_state) % (index + 1); |
| 218 | randnum += size_group[x].start; | ||
| 214 | // we could handle this case differently if desired | 219 | // we could handle this case differently if desired |
| 215 | if (DECL_BIT_FIELD_TYPE(newtree[randnum])) | 220 | if (DECL_BIT_FIELD_TYPE(newtree[randnum])) |
| 216 | continue; | 221 | continue; |
| @@ -29,7 +29,7 @@ struct modsig { · 28 unmodified lines | |||
| 29 | * storing the signature. | 29 | * storing the signature. |
| 30 | */ | 30 | */ |
| 31 | int raw_pkcs7_len; | 31 | int raw_pkcs7_len; |
| 32 | u8 raw_pkcs7[]; | 32 | u8 raw_pkcs7[] __counted_by(raw_pkcs7_len); |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | /* | 35 | /* |
| @@ -65,10 +65,11 @@ int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len, · 29 unmodified lines | |||
| 65 | buf_len -= sig_len + sizeof(*sig); | 65 | buf_len -= sig_len + sizeof(*sig); |
| 66 | 66 | ||
| 67 | /* Allocate sig_len additional bytes to hold the raw PKCS#7 data. */ | 67 | /* Allocate sig_len additional bytes to hold the raw PKCS#7 data. */ |
| 68 | hdr = kzalloc(sizeof(*hdr) + sig_len, GFP_KERNEL); | 68 | hdr = kzalloc(struct_size(hdr, raw_pkcs7, sig_len), GFP_KERNEL); |
| 69 | if (!hdr) | 69 | if (!hdr) |
| 70 | return -ENOMEM; | 70 | return -ENOMEM; |
| 71 | 71 | ||
| 72 | hdr->raw_pkcs7_len = sig_len; | ||
| 72 | hdr->pkcs7_msg = pkcs7_parse_message(buf + buf_len, sig_len); | 73 | hdr->pkcs7_msg = pkcs7_parse_message(buf + buf_len, sig_len); |
| 73 | if (IS_ERR(hdr->pkcs7_msg)) { | 74 | if (IS_ERR(hdr->pkcs7_msg)) { |
| 74 | rc = PTR_ERR(hdr->pkcs7_msg); | 75 | rc = PTR_ERR(hdr->pkcs7_msg); |
| @@ -77,7 +78,6 @@ int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len, · 2 unmodified lines | |||
| 77 | } | 78 | } |
| 78 | 79 | ||
| 79 | memcpy(hdr->raw_pkcs7, buf + buf_len, sig_len); | 80 | memcpy(hdr->raw_pkcs7, buf + buf_len, sig_len); |
| 80 | hdr->raw_pkcs7_len = sig_len; | ||
| 81 | 81 | ||
| 82 | /* We don't know the hash algorithm yet. */ | 82 | /* We don't know the hash algorithm yet. */ |
| 83 | hdr->hash_algo = HASH_ALGO__LAST; | 83 | hdr->hash_algo = HASH_ALGO__LAST; |
| @@ -9,7 +9,6 @@ CONFIG_INIT_ON_FREE_DEFAULT_ON=y · 8 unmodified lines | |||
| 9 | CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y | 9 | CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y |
| 10 | CONFIG_UBSAN=y | 10 | CONFIG_UBSAN=y |
| 11 | CONFIG_UBSAN_BOUNDS=y | 11 | CONFIG_UBSAN_BOUNDS=y |
| 12 | CONFIG_UBSAN_TRAP=y | ||
| 13 | CONFIG_STACKPROTECTOR_STRONG=y | 12 | CONFIG_STACKPROTECTOR_STRONG=y |
| 14 | CONFIG_SLUB_DEBUG=y | 13 | CONFIG_SLUB_DEBUG=y |
| 15 | CONFIG_SLUB_DEBUG_ON=y | 14 | CONFIG_SLUB_DEBUG_ON=y |
| @@ -1,4 +1,5 @@ | |||
| 1 | #PANIC | 1 | #PANIC |
| 2 | #PANIC_STOP_IRQOFF Crashes entire system | ||
| 2 | BUG kernel BUG at | 3 | BUG kernel BUG at |
| 3 | WARNING WARNING: | 4 | WARNING WARNING: |
| 4 | WARNING_MESSAGE message trigger | 5 | WARNING_MESSAGE message trigger |
| @@ -7,7 +8,7 @@ EXCEPTION · 2 unmodified lines | |||
| 7 | #EXHAUST_STACK Corrupts memory on failure | 8 | #EXHAUST_STACK Corrupts memory on failure |
| 8 | #CORRUPT_STACK Crashes entire system on success | 9 | #CORRUPT_STACK Crashes entire system on success |
| 9 | #CORRUPT_STACK_STRONG Crashes entire system on success | 10 | #CORRUPT_STACK_STRONG Crashes entire system on success |
| 10 | ARRAY_BOUNDS | 11 | ARRAY_BOUNDS call trace:|UBSAN: array-index-out-of-bounds |
| 11 | CORRUPT_LIST_ADD list_add corruption | 12 | CORRUPT_LIST_ADD list_add corruption |
| 12 | CORRUPT_LIST_DEL list_del corruption | 13 | CORRUPT_LIST_DEL list_del corruption |
| 13 | STACK_GUARD_PAGE_LEADING | 14 | STACK_GUARD_PAGE_LEADING |