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

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

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
...

+280 -90
+6
MAINTAINERS
··· 8649 8649 S: Maintained 8650 8650 T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening 8651 8651 F: Documentation/kbuild/gcc-plugins.rst 8652 + F: include/linux/stackleak.h 8653 + F: kernel/stackleak.c 8652 8654 F: scripts/Makefile.gcc-plugins 8653 8655 F: scripts/gcc-plugins/ 8654 8656 ··· 11417 11415 11418 11416 KERNEL HARDENING (not covered by other areas) 11419 11417 M: Kees Cook <keescook@chromium.org> 11418 + R: Gustavo A. R. Silva <gustavoars@kernel.org> 11420 11419 L: linux-hardening@vger.kernel.org 11421 11420 S: Supported 11422 11421 T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening 11423 11422 F: Documentation/ABI/testing/sysfs-kernel-oops_count 11424 11423 F: Documentation/ABI/testing/sysfs-kernel-warn_count 11424 + F: arch/*/configs/hardening.config 11425 11425 F: include/linux/overflow.h 11426 11426 F: include/linux/randomize_kstack.h 11427 + F: kernel/configs/hardening.config 11427 11428 F: mm/usercopy.c 11428 11429 K: \b(add|choose)_random_kstack_offset\b 11429 11430 K: \b__check_(object_size|heap_object)\b 11431 + K: \b__counted_by\b 11430 11432 11431 11433 KERNEL JANITORS 11432 11434 L: kernel-janitors@vger.kernel.org
+7
arch/arm/configs/hardening.config
··· 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
+22
arch/arm64/configs/hardening.config
··· 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
+10
arch/powerpc/configs/hardening.config
··· 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
+1 -1
arch/sparc/kernel/cpumap.c
··· 50 50 51 51 /* Offsets into nodes[] for each level of the tree */ 52 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
+1 -1
arch/um/os-Linux/drivers/ethertap_user.c
··· 105 105 sprintf(data_fd_buf, "%d", data_remote); 106 106 sprintf(version_buf, "%d", UML_NET_VERSION); 107 107 if (gate != NULL) { 108 - strncpy(gate_buf, gate, 15); 108 + strscpy(gate_buf, gate, sizeof(gate_buf)); 109 109 args = setup_args; 110 110 } 111 111 else args = nosetup_args;
+14
arch/x86/configs/hardening.config
··· 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
+1 -1
drivers/accel/ivpu/ivpu_job.h
··· 51 51 u32 job_id; 52 52 u32 engine_idx; 53 53 size_t bo_count; 54 - struct ivpu_bo *bos[]; 54 + struct ivpu_bo *bos[] __counted_by(bo_count); 55 55 }; 56 56 57 57 int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file);
+3 -4
drivers/auxdisplay/panel.c
··· 1449 1449 key->rise_time = 1; 1450 1450 key->fall_time = 1; 1451 1451 1452 - strncpy(key->u.kbd.press_str, press, sizeof(key->u.kbd.press_str)); 1453 - strncpy(key->u.kbd.repeat_str, repeat, sizeof(key->u.kbd.repeat_str)); 1454 - strncpy(key->u.kbd.release_str, release, 1455 - sizeof(key->u.kbd.release_str)); 1452 + strtomem_pad(key->u.kbd.press_str, press, '\0'); 1453 + strtomem_pad(key->u.kbd.repeat_str, repeat, '\0'); 1454 + strtomem_pad(key->u.kbd.release_str, release, '\0'); 1456 1455 list_add(&key->list, &logical_inputs); 1457 1456 return key; 1458 1457 }
+1 -1
drivers/block/drbd/drbd_int.h
··· 555 555 unsigned int head_index; 556 556 unsigned int size; 557 557 int total; /* sum of all values */ 558 - int values[]; 558 + int values[] __counted_by(size); 559 559 }; 560 560 extern struct fifo_buffer *fifo_alloc(unsigned int fifo_size); 561 561
+4 -8
drivers/bus/fsl-mc/dprc.c
··· 450 450 obj_desc->ver_major = le16_to_cpu(rsp_params->version_major); 451 451 obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor); 452 452 obj_desc->flags = le16_to_cpu(rsp_params->flags); 453 - strncpy(obj_desc->type, rsp_params->type, 16); 454 - obj_desc->type[15] = '\0'; 455 - strncpy(obj_desc->label, rsp_params->label, 16); 456 - obj_desc->label[15] = '\0'; 453 + strscpy_pad(obj_desc->type, rsp_params->type, 16); 454 + strscpy_pad(obj_desc->label, rsp_params->label, 16); 457 455 return 0; 458 456 } 459 457 EXPORT_SYMBOL_GPL(dprc_get_obj); ··· 489 491 cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr); 490 492 cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num); 491 493 cmd_params->obj_id = cpu_to_le32(obj_id); 492 - strncpy(cmd_params->obj_type, obj_type, 16); 493 - cmd_params->obj_type[15] = '\0'; 494 + strscpy_pad(cmd_params->obj_type, obj_type, 16); 494 495 495 496 /* send command to mc*/ 496 497 return mc_send_command(mc_io, &cmd); ··· 561 564 cmd_params = (struct dprc_cmd_get_obj_region *)cmd.params; 562 565 cmd_params->obj_id = cpu_to_le32(obj_id); 563 566 cmd_params->region_index = region_index; 564 - strncpy(cmd_params->obj_type, obj_type, 16); 565 - cmd_params->obj_type[15] = '\0'; 567 + strscpy_pad(cmd_params->obj_type, obj_type, 16); 566 568 567 569 /* send command to mc*/ 568 570 err = mc_send_command(mc_io, &cmd);
+1 -1
drivers/char/virtio_console.c
··· 106 106 unsigned int sgpages; 107 107 108 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 /*
+2 -2
drivers/cpufreq/cpufreq.c
··· 1650 1650 } 1651 1651 1652 1652 if (has_target()) 1653 - strncpy(policy->last_governor, policy->governor->name, 1653 + strscpy(policy->last_governor, policy->governor->name, 1654 1654 CPUFREQ_NAME_LEN); 1655 1655 else 1656 1656 policy->last_policy = policy->policy; ··· 2996 2996 BUG_ON(!cpufreq_global_kobject); 2997 2997 2998 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 3001 return 0; 3002 3002 }
+2 -2
drivers/cpuidle/dt_idle_states.c
··· 84 84 * replace with kstrdup and pointer assignment when name 85 85 * and desc become string pointers 86 86 */ 87 - strncpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN - 1); 88 - strncpy(idle_state->desc, desc, CPUIDLE_DESC_LEN - 1); 87 + strscpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN); 88 + strscpy(idle_state->desc, desc, CPUIDLE_DESC_LEN); 89 89 return 0; 90 90 } 91 91
+2 -2
drivers/edac/edac_mc_sysfs.c
··· 229 229 if (copy_count == 0 || copy_count >= sizeof(rank->dimm->label)) 230 230 return -EINVAL; 231 231 232 - strncpy(rank->dimm->label, data, copy_count); 232 + memcpy(rank->dimm->label, data, copy_count); 233 233 rank->dimm->label[copy_count] = '\0'; 234 234 235 235 return count; ··· 535 535 if (copy_count == 0 || copy_count >= sizeof(dimm->label)) 536 536 return -EINVAL; 537 537 538 - strncpy(dimm->label, data, copy_count); 538 + memcpy(dimm->label, data, copy_count); 539 539 dimm->label[copy_count] = '\0'; 540 540 541 541 return count;
+2 -2
drivers/firmware/tegra/bpmp-debugfs.c
··· 610 610 } 611 611 612 612 len = strlen(filename); 613 - strncpy(namevirt, filename, namesize); 613 + strscpy_pad(namevirt, filename, namesize); 614 614 615 615 err = mrq_debugfs_read(bpmp, namephys, len, dataphys, datasize, 616 616 &nbytes); ··· 661 661 } 662 662 663 663 len = strlen(filename); 664 - strncpy(namevirt, filename, namesize); 664 + strscpy_pad(namevirt, filename, namesize); 665 665 666 666 if (copy_from_user(datavirt, buf, count)) { 667 667 err = -EFAULT;
+1 -1
drivers/gpu/drm/gud/gud_pipe.c
··· 503 503 return -ENOENT; 504 504 505 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 507 req = kzalloc(len, GFP_KERNEL); 508 508 if (!req) 509 509 return -ENOMEM;
+3 -2
drivers/gpu/drm/nouveau/nouveau_svm.c
··· 67 67 struct nouveau_svmm *svmm; 68 68 } **fault; 69 69 int fault_nr; 70 - } buffer[1]; 70 + } buffer[]; 71 71 }; 72 72 73 73 #define FAULT_ACCESS_READ 0 ··· 1063 1063 if (drm->client.device.info.family > NV_DEVICE_INFO_V0_PASCAL) 1064 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 1068 return; 1068 1069 1069 1070 drm->svm->drm = drm;
+4 -4
drivers/hid/hid-prodikeys.c
··· 639 639 goto fail; 640 640 } 641 641 642 - strncpy(card->driver, shortname, sizeof(card->driver)); 643 - strncpy(card->shortname, shortname, sizeof(card->shortname)); 644 - strncpy(card->longname, longname, sizeof(card->longname)); 642 + strscpy(card->driver, shortname, sizeof(card->driver)); 643 + strscpy(card->shortname, shortname, sizeof(card->shortname)); 644 + strscpy(card->longname, longname, sizeof(card->longname)); 645 645 646 646 /* Set up rawmidi */ 647 647 err = snd_rawmidi_new(card, card->shortname, 0, ··· 652 652 goto fail; 653 653 } 654 654 pm->rwmidi = rwmidi; 655 - strncpy(rwmidi->name, card->shortname, sizeof(rwmidi->name)); 655 + strscpy(rwmidi->name, card->shortname, sizeof(rwmidi->name)); 656 656 rwmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT; 657 657 rwmidi->private_data = pm; 658 658
+2 -3
drivers/hwmon/acpi_power_meter.c
··· 796 796 goto error; 797 797 } 798 798 799 - *str = kcalloc(element->string.length + 1, sizeof(u8), 800 - GFP_KERNEL); 799 + *str = kmemdup_nul(element->string.pointer, element->string.length, 800 + GFP_KERNEL); 801 801 if (!*str) { 802 802 res = -ENOMEM; 803 803 goto error; 804 804 } 805 805 806 - strncpy(*str, element->string.pointer, element->string.length); 807 806 str++; 808 807 } 809 808
+1 -1
drivers/hwmon/asus_wmi_sensors.c
··· 300 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 305 data_type_obj = obj->package.elements[1]; 306 306 if (data_type_obj.type != ACPI_TYPE_INTEGER) {
+1 -1
drivers/hwmon/ibmpowernv.c
··· 234 234 if (copy_len >= sizeof(buf)) 235 235 return -EINVAL; 236 236 237 - strncpy(buf, hash_pos + 1, copy_len); 237 + memcpy(buf, hash_pos + 1, copy_len); 238 238 239 239 err = kstrtou32(buf, 10, index); 240 240 if (err)
+1 -1
drivers/irqchip/irq-imx-intmux.c
··· 73 73 void __iomem *regs; 74 74 struct clk *ipg_clk; 75 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 79 static void imx_intmux_irq_mask(struct irq_data *d)
+2 -2
drivers/isdn/capi/kcapi.c
··· 732 732 u16 ret; 733 733 734 734 if (contr == 0) { 735 - strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); 735 + strscpy_pad(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); 736 736 return CAPI_NOERROR; 737 737 } 738 738 ··· 740 740 741 741 ctr = get_capi_ctr_by_nr(contr); 742 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 744 ret = CAPI_NOERROR; 745 745 } else 746 746 ret = CAPI_REGNOTINSTALLED;
+1 -1
drivers/isdn/mISDN/clock.c
··· 96 96 printk(KERN_ERR "%s: No memory for clock entry.\n", __func__); 97 97 return NULL; 98 98 } 99 - strncpy(iclock->name, name, sizeof(iclock->name) - 1); 99 + strscpy(iclock->name, name, sizeof(iclock->name)); 100 100 iclock->pri = pri; 101 101 iclock->priv = priv; 102 102 iclock->ctl = ctl;
+1 -1
drivers/mailbox/zynqmp-ipi-mailbox.c
··· 108 108 unsigned int method; 109 109 u32 local_id; 110 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 114 static struct device_driver zynqmp_ipi_mbox_driver = {
+1 -1
drivers/md/dm-bio-prison-v1.c
··· 26 26 struct dm_bio_prison { 27 27 mempool_t cell_pool; 28 28 unsigned int num_locks; 29 - struct prison_region regions[]; 29 + struct prison_region regions[] __counted_by(num_locks); 30 30 }; 31 31 32 32 static struct kmem_cache *_cell_cache;
+1 -1
drivers/md/dm-crypt.c
··· 224 224 struct mutex bio_alloc_lock; 225 225 226 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 230 #define MIN_IOS 64
+1 -1
drivers/md/dm-raid.c
··· 254 254 int mode; 255 255 } journal_dev; 256 256 257 - struct raid_dev dev[]; 257 + struct raid_dev dev[] __counted_by(raid_disks); 258 258 }; 259 259 260 260 static void rs_config_backup(struct raid_set *rs, struct rs_layout *l)
+1 -1
drivers/md/dm-stats.c
··· 56 56 size_t percpu_alloc_size; 57 57 size_t histogram_alloc_size; 58 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 62 #define STAT_PRECISE_TIMESTAMPS 1
+1 -1
drivers/md/dm-stripe.c
··· 44 44 /* Work struct used for triggering events*/ 45 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 /*
+29 -1
drivers/misc/lkdtm/bugs.c
··· 6 6 * test source files. 7 7 */ 8 8 #include "lkdtm.h" 9 + #include <linux/cpu.h> 9 10 #include <linux/list.h> 10 11 #include <linux/sched.h> 11 12 #include <linux/sched/signal.h> 12 13 #include <linux/sched/task_stack.h> 13 - #include <linux/uaccess.h> 14 14 #include <linux/slab.h> 15 + #include <linux/stop_machine.h> 16 + #include <linux/uaccess.h> 15 17 16 18 #if IS_ENABLED(CONFIG_X86_32) && !IS_ENABLED(CONFIG_UML) 17 19 #include <asm/desc.h> ··· 73 71 static void lkdtm_PANIC(void) 74 72 { 75 73 panic("dumptest"); 74 + } 75 + 76 + static int panic_stop_irqoff_fn(void *arg) 77 + { 78 + atomic_t *v = arg; 79 + 80 + /* 81 + * As stop_machine() disables interrupts, all CPUs within this function 82 + * have interrupts disabled and cannot take a regular IPI. 83 + * 84 + * The last CPU which enters here will trigger a panic, and as all CPUs 85 + * cannot take a regular IPI, we'll only be able to stop secondaries if 86 + * smp_send_stop() or crash_smp_send_stop() uses an NMI. 87 + */ 88 + if (atomic_inc_return(v) == num_online_cpus()) 89 + panic("panic stop irqoff test"); 90 + 91 + for (;;) 92 + cpu_relax(); 93 + } 94 + 95 + static void lkdtm_PANIC_STOP_IRQOFF(void) 96 + { 97 + atomic_t v = ATOMIC_INIT(0); 98 + stop_machine(panic_stop_irqoff_fn, &v, cpu_online_mask); 76 99 } 77 100 78 101 static void lkdtm_BUG(void) ··· 665 638 666 639 static struct crashtype crashtypes[] = { 667 640 CRASHTYPE(PANIC), 641 + CRASHTYPE(PANIC_STOP_IRQOFF), 668 642 CRASHTYPE(BUG), 669 643 CRASHTYPE(WARNING), 670 644 CRASHTYPE(WARNING_MESSAGE),
+2 -2
drivers/reset/core.c
··· 60 60 struct reset_control_array { 61 61 struct reset_control base; 62 62 unsigned int num_rstcs; 63 - struct reset_control *rstc[]; 63 + struct reset_control *rstc[] __counted_by(num_rstcs); 64 64 }; 65 65 66 66 static const char *rcdev_name(struct reset_controller_dev *rcdev) ··· 1185 1185 resets = kzalloc(struct_size(resets, rstc, num), GFP_KERNEL); 1186 1186 if (!resets) 1187 1187 return ERR_PTR(-ENOMEM); 1188 + resets->num_rstcs = num; 1188 1189 1189 1190 for (i = 0; i < num; i++) { 1190 1191 rstc = __of_reset_control_get(np, NULL, i, shared, optional, ··· 1194 1193 goto err_rst; 1195 1194 resets->rstc[i] = rstc; 1196 1195 } 1197 - resets->num_rstcs = num; 1198 1196 resets->base.array = true; 1199 1197 1200 1198 return &resets->base;
+1 -1
drivers/thermal/qcom/tsens.h
··· 585 585 struct dentry *debug_root; 586 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 /**
+2 -1
drivers/usb/atm/usbatm.c
··· 1018 1018 size_t size; 1019 1019 1020 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 1023 instance = kzalloc(size, GFP_KERNEL); 1023 1024 if (!instance) 1024 1025 return -ENOMEM;
+1 -1
drivers/usb/gadget/function/f_fs.c
··· 202 202 struct ffs_buffer { 203 203 size_t length; 204 204 char *data; 205 - char storage[]; 205 + char storage[] __counted_by(length); 206 206 }; 207 207 208 208 /* ffs_io_data structure ***************************************************/
+2 -2
drivers/usb/gadget/function/f_midi.c
··· 99 99 unsigned int in_last_port; 100 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 105 static inline struct f_midi *func_to_midi(struct usb_function *f) ··· 1349 1349 status = -ENOMEM; 1350 1350 goto setup_fail; 1351 1351 } 1352 + midi->in_ports = opts->in_ports; 1352 1353 1353 1354 for (i = 0; i < opts->in_ports; i++) 1354 1355 midi->in_ports_array[i].cable = i; ··· 1360 1359 status = -ENOMEM; 1361 1360 goto midi_free; 1362 1361 } 1363 - midi->in_ports = opts->in_ports; 1364 1362 midi->out_ports = opts->out_ports; 1365 1363 midi->index = opts->index; 1366 1364 midi->buflen = opts->buflen;
+1 -1
drivers/usb/host/ohci.h
··· 337 337 u16 length; // # tds in this request 338 338 u16 td_cnt; // tds already serviced 339 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 342 } urb_priv_t; 343 343
+1 -1
drivers/usb/host/xhci.h
··· 1666 1666 struct urb_priv { 1667 1667 int num_tds; 1668 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 /*
+1 -1
drivers/virt/acrn/acrn_drv.h
··· 60 60 u16 reserved[3]; 61 61 u32 regions_num; 62 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 /**
+1 -1
drivers/virt/acrn/mm.c
··· 250 250 ret = -ENOMEM; 251 251 goto unmap_kernel_map; 252 252 } 253 + regions_info->regions_num = nr_regions; 253 254 254 255 /* Fill each vm_memory_region_op */ 255 256 vm_region = regions_info->regions_op; 256 257 regions_info->vmid = vm->vmid; 257 - regions_info->regions_num = nr_regions; 258 258 regions_info->regions_gpa = virt_to_phys(vm_region); 259 259 user_vm_pa = memmap->user_vm_pa; 260 260 i = 0;
+2 -2
fs/afs/internal.h
··· 87 87 enum dns_lookup_status status:8; 88 88 unsigned long failed; /* Mask of addrs that failed locally/ICMP */ 89 89 unsigned long responded; /* Mask of addrs that responded */ 90 - struct sockaddr_rxrpc addrs[]; 90 + struct sockaddr_rxrpc addrs[] __counted_by(max_addrs); 91 91 #define AFS_MAX_ADDRESSES ((unsigned int)(sizeof(unsigned long) * 8)) 92 92 }; 93 93 ··· 705 705 refcount_t usage; 706 706 unsigned short nr_permits; /* Number of records */ 707 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 /*
+1 -1
fs/nfs/filelayout/filelayout.h
··· 51 51 u32 stripe_count; 52 52 u8 *stripe_indices; 53 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 57 struct nfs4_filelayout_segment {
+1 -1
fs/nfs/flexfilelayout/flexfilelayout.h
··· 99 99 u64 stripe_unit; 100 100 u32 flags; 101 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 105 struct nfs4_flexfile_layout {
+1 -1
fs/ocfs2/slot_map.c
··· 37 37 unsigned int si_blocks; 38 38 struct buffer_head **si_bh; 39 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
+1 -1
include/linux/ceph/osd_client.h
··· 278 278 int r_attempts; 279 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 284 struct ceph_request_redirect {
+1 -1
include/linux/crash_core.h
··· 92 92 struct crash_mem { 93 93 unsigned int max_nr_ranges; 94 94 unsigned int nr_ranges; 95 - struct range ranges[]; 95 + struct range ranges[] __counted_by(max_nr_ranges); 96 96 }; 97 97 98 98 extern int crash_exclude_mem_range(struct crash_mem *mem,
+4 -3
include/linux/cred.h
··· 12 12 #include <linux/init.h> 13 13 #include <linux/key.h> 14 14 #include <linux/atomic.h> 15 + #include <linux/refcount.h> 15 16 #include <linux/uidgid.h> 16 17 #include <linux/sched.h> 17 18 #include <linux/sched/user.h> ··· 24 23 * COW Supplementary groups list 25 24 */ 26 25 struct group_info { 27 - atomic_t usage; 26 + refcount_t usage; 28 27 int ngroups; 29 28 kgid_t gid[]; 30 29 } __randomize_layout; ··· 40 39 */ 41 40 static inline struct group_info *get_group_info(struct group_info *gi) 42 41 { 43 - atomic_inc(&gi->usage); 42 + refcount_inc(&gi->usage); 44 43 return gi; 45 44 } 46 45 ··· 50 49 */ 51 50 #define put_group_info(group_info) \ 52 51 do { \ 53 - if (atomic_dec_and_test(&(group_info)->usage)) \ 52 + if (refcount_dec_and_test(&(group_info)->usage)) \ 54 53 groups_free(group_info); \ 55 54 } while (0) 56 55
+1 -1
include/linux/kvm_host.h
··· 664 664 * Array indexed by gsi. Each entry contains list of irq chips 665 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 669 #endif 670 670
+1 -1
include/linux/platform_data/gsc_hwmon.h
··· 40 40 unsigned int resolution; 41 41 unsigned int vreference; 42 42 unsigned int fan_base; 43 - struct gsc_hwmon_channel channels[]; 43 + struct gsc_hwmon_channel channels[] __counted_by(nchannels); 44 44 }; 45 45 #endif
+5 -2
include/linux/string.h
··· 277 277 */ 278 278 #define strtomem_pad(dest, src, pad) do { \ 279 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 282 BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ 282 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 286 } while (0) 285 287 286 288 /** ··· 300 298 */ 301 299 #define strtomem(dest, src) do { \ 302 300 const size_t _dest_len = __builtin_object_size(dest, 1); \ 301 + const size_t _src_len = __builtin_object_size(src, 1); \ 303 302 \ 304 303 BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ 305 304 _dest_len == (size_t)-1); \ 306 - memcpy(dest, src, min(_dest_len, strnlen(src, _dest_len))); \ 305 + memcpy(dest, src, strnlen(src, min(_src_len, _dest_len))); \ 307 306 } while (0) 308 307 309 308 /**
+3 -3
init/version.c
··· 21 21 { 22 22 size_t bufsize = sizeof(init_uts_ns.name.nodename); 23 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); 27 - if (arglen > maxlen) { 26 + arglen = strscpy(init_uts_ns.name.nodename, arg, bufsize); 27 + if (arglen < 0) { 28 28 pr_warn("hostname parameter exceeds %zd characters and will be truncated", 29 29 maxlen); 30 30 }
+98
kernel/configs/hardening.config
··· 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
+1 -1
kernel/cred.c
··· 36 36 static struct kmem_cache *cred_jar; 37 37 38 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 42 * The initial credentials for the initial task
+1 -1
kernel/groups.c
··· 19 19 if (!gi) 20 20 return NULL; 21 21 22 - atomic_set(&gi->usage, 1); 22 + refcount_set(&gi->usage, 1); 23 23 gi->ngroups = gidsetsize; 24 24 return gi; 25 25 }
+4 -4
lib/kobject_uevent.c
··· 254 254 int buffer_size = sizeof(env->buf) - env->buflen; 255 255 int len; 256 256 257 - len = strlcpy(&env->buf[env->buflen], subsystem, buffer_size); 258 - if (len >= buffer_size) { 259 - pr_warn("init_uevent_argv: buffer size of %d too small, needed %d\n", 260 - buffer_size, len); 257 + len = strscpy(&env->buf[env->buflen], subsystem, buffer_size); 258 + if (len < 0) { 259 + pr_warn("%s: insufficient buffer space (%u left) for %s\n", 260 + __func__, buffer_size, subsystem); 261 261 return -ENOMEM; 262 262 } 263 263
+8 -3
scripts/gcc-plugins/randomize_layout_plugin.c
··· 191 191 192 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 195 struct partition_group size_group[length]; 196 196 unsigned long num_groups = 0; 197 197 unsigned long randnum; 198 198 199 199 partition_struct(newtree, length, (struct partition_group *)&size_group, &num_groups); 200 + 201 + /* FIXME: this group shuffle is currently a no-op. */ 200 202 for (i = num_groups - 1; i > 0; i--) { 201 203 struct partition_group tmp; 202 204 randnum = ranval(prng_state) % (i + 1); ··· 208 206 } 209 207 210 208 for (x = 0; x < num_groups; x++) { 211 - for (i = size_group[x].start + size_group[x].length - 1; i > size_group[x].start; i--) { 209 + for (index = size_group[x].length - 1; index > 0; index--) { 212 210 tree tmp; 211 + 212 + i = size_group[x].start + index; 213 213 if (DECL_BIT_FIELD_TYPE(newtree[i])) 214 214 continue; 215 - randnum = ranval(prng_state) % (i + 1); 215 + randnum = ranval(prng_state) % (index + 1); 216 + randnum += size_group[x].start; 216 217 // we could handle this case differently if desired 217 218 if (DECL_BIT_FIELD_TYPE(newtree[randnum])) 218 219 continue;
+3 -3
security/integrity/ima/ima_modsig.c
··· 29 29 * storing the signature. 30 30 */ 31 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 65 buf_len -= sig_len + sizeof(*sig); 66 66 67 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 69 if (!hdr) 70 70 return -ENOMEM; 71 71 72 + hdr->raw_pkcs7_len = sig_len; 72 73 hdr->pkcs7_msg = pkcs7_parse_message(buf + buf_len, sig_len); 73 74 if (IS_ERR(hdr->pkcs7_msg)) { 74 75 rc = PTR_ERR(hdr->pkcs7_msg); ··· 78 77 } 79 78 80 79 memcpy(hdr->raw_pkcs7, buf + buf_len, sig_len); 81 - hdr->raw_pkcs7_len = sig_len; 82 80 83 81 /* We don't know the hash algorithm yet. */ 84 82 hdr->hash_algo = HASH_ALGO__LAST;
-1
tools/testing/selftests/lkdtm/config
··· 9 9 CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y 10 10 CONFIG_UBSAN=y 11 11 CONFIG_UBSAN_BOUNDS=y 12 - CONFIG_UBSAN_TRAP=y 13 12 CONFIG_STACKPROTECTOR_STRONG=y 14 13 CONFIG_SLUB_DEBUG=y 15 14 CONFIG_SLUB_DEBUG_ON=y
+2 -1
tools/testing/selftests/lkdtm/tests.txt
··· 1 1 #PANIC 2 + #PANIC_STOP_IRQOFF Crashes entire system 2 3 BUG kernel BUG at 3 4 WARNING WARNING: 4 5 WARNING_MESSAGE message trigger ··· 8 7 #EXHAUST_STACK Corrupts memory on failure 9 8 #CORRUPT_STACK Crashes entire system on success 10 9 #CORRUPT_STACK_STRONG Crashes entire system on success 11 - ARRAY_BOUNDS 10 + ARRAY_BOUNDS call trace:|UBSAN: array-index-out-of-bounds 12 11 CORRUPT_LIST_ADD list_add corruption 13 12 CORRUPT_LIST_DEL list_del corruption 14 13 STACK_GUARD_PAGE_LEADING