hardening updates for v6.7-rc1

- 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)
 -----BEGIN PGP SIGNATURE-----
 
 iQJKBAABCgA0FiEEpcP2jyKd1g9yPm4TiXL039xtwCYFAmU/3cUWHGtlZXNjb29r
 QGNocm9taXVtLm9yZwAKCRCJcvTf3G3AJsEoEACBGPSiOmfSWdH3TOnIG270PD24
 jGjg8KFv7RC/JTOdYmpLl0okdlGT9LvjN/ToSSDEw3PIayxoXUdhkbYy0MYtiV3m
 yz2ozDTzJuplQX/W2fPE+nXSzIwHao2zjPPFjHnT7lt8IIjhgjiOtLfZ2gGUkW99
 Mdu2aWh3u0r4tC8OS23++yN5ibRc5l72efsjDWjZ0aPXnxE1bjmLMiIPiizpndIf
 beasPuDBs98sJVYouemCwnsPXuXOPz3Q1Cpo/fTd+TMTJCLSemCQZCTuOBU0acI/
 ZjLCgCaJU1yIYKBMtrIN4G9kITZniXX3/Nm4o6NQMVlcCqMeNaHuflomqWoqWfhE
 UPbRo2eghZOaMNiCKLLvZDIqPrh1IcsiEl6Ef3W4hICc42GTK96IuGisIvDXwQ4N
 /SzTOupJuN42noh3z1M3XuZy5RoXJ99IYDNY5CTKf9IdqvA0bbGkU3nb1gZH/xw9
 BjTqKzR/7K1kTXuSgagDZ1Wceej9pZxhX7E3IHYsP8ZOvKug3EeL4yybVwQ3HRfq
 Qnzcp/qPB9cOkLSQXveRTFTsj2mX28Gixct/iDuc1jIYwGQlY1gI6dcUcqby6ptM
 BrQti7eR2NH2+T3aE2UVCIWsZVhx7NaSF+z8JxfAuu56jicc4xJVsi8zrNveWX5M
 m2VXyBl3121BVtKi4w==
 =0iVF
 -----END PGP SIGNATURE-----

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
  ...
This commit is contained in:
Linus Torvalds 2023-10-30 19:09:55 -10:00
commit befaa609f4
60 changed files with 280 additions and 90 deletions

View File

@ -8649,6 +8649,8 @@ L: linux-hardening@vger.kernel.org
S: Maintained S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
F: Documentation/kbuild/gcc-plugins.rst F: Documentation/kbuild/gcc-plugins.rst
F: include/linux/stackleak.h
F: kernel/stackleak.c
F: scripts/Makefile.gcc-plugins F: scripts/Makefile.gcc-plugins
F: scripts/gcc-plugins/ F: scripts/gcc-plugins/
@ -11415,16 +11417,20 @@ F: usr/
KERNEL HARDENING (not covered by other areas) KERNEL HARDENING (not covered by other areas)
M: Kees Cook <keescook@chromium.org> M: Kees Cook <keescook@chromium.org>
R: Gustavo A. R. Silva <gustavoars@kernel.org>
L: linux-hardening@vger.kernel.org L: linux-hardening@vger.kernel.org
S: Supported S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
F: Documentation/ABI/testing/sysfs-kernel-oops_count F: Documentation/ABI/testing/sysfs-kernel-oops_count
F: Documentation/ABI/testing/sysfs-kernel-warn_count F: Documentation/ABI/testing/sysfs-kernel-warn_count
F: arch/*/configs/hardening.config
F: include/linux/overflow.h F: include/linux/overflow.h
F: include/linux/randomize_kstack.h F: include/linux/randomize_kstack.h
F: kernel/configs/hardening.config
F: mm/usercopy.c F: mm/usercopy.c
K: \b(add|choose)_random_kstack_offset\b K: \b(add|choose)_random_kstack_offset\b
K: \b__check_(object_size|heap_object)\b K: \b__check_(object_size|heap_object)\b
K: \b__counted_by\b
KERNEL JANITORS KERNEL JANITORS
L: kernel-janitors@vger.kernel.org L: kernel-janitors@vger.kernel.org

View File

@ -0,0 +1,7 @@
# Basic kernel hardening options (specific to arm)
# Make sure PXN/PAN emulation is enabled.
CONFIG_CPU_SW_DOMAIN_PAN=y
# Dangerous; old interfaces and needless additional attack surface.
# CONFIG_OABI_COMPAT is not set

View File

@ -0,0 +1,22 @@
# Basic kernel hardening options (specific to arm64)
# Make sure PAN emulation is enabled.
CONFIG_ARM64_SW_TTBR0_PAN=y
# Software Shadow Stack or PAC
CONFIG_SHADOW_CALL_STACK=y
# Pointer authentication (ARMv8.3 and later). If hardware actually supports
# it, one can turn off CONFIG_STACKPROTECTOR_STRONG with this enabled.
CONFIG_ARM64_PTR_AUTH=y
CONFIG_ARM64_PTR_AUTH_KERNEL=y
# Available in ARMv8.5 and later.
CONFIG_ARM64_BTI=y
CONFIG_ARM64_BTI_KERNEL=y
CONFIG_ARM64_MTE=y
CONFIG_KASAN_HW_TAGS=y
CONFIG_ARM64_E0PD=y
# Available in ARMv8.7 and later.
CONFIG_ARM64_EPAN=y

View File

@ -0,0 +1,10 @@
# PowerPC specific hardening options
# Block kernel from unexpectedly reading userspace memory.
CONFIG_PPC_KUAP=y
# Attack surface reduction.
# CONFIG_SCOM_DEBUGFS is not set
# Disable internal kernel debugger.
# CONFIG_XMON is not set

View File

@ -50,7 +50,7 @@ struct cpuinfo_tree {
/* Offsets into nodes[] for each level of the tree */ /* Offsets into nodes[] for each level of the tree */
struct cpuinfo_level level[CPUINFO_LVL_MAX]; struct cpuinfo_level level[CPUINFO_LVL_MAX];
struct cpuinfo_node nodes[]; struct cpuinfo_node nodes[] __counted_by(total_nodes);
}; };

View File

@ -105,7 +105,7 @@ static int etap_tramp(char *dev, char *gate, int control_me,
sprintf(data_fd_buf, "%d", data_remote); sprintf(data_fd_buf, "%d", data_remote);
sprintf(version_buf, "%d", UML_NET_VERSION); sprintf(version_buf, "%d", UML_NET_VERSION);
if (gate != NULL) { if (gate != NULL) {
strncpy(gate_buf, gate, 15); strscpy(gate_buf, gate, sizeof(gate_buf));
args = setup_args; args = setup_args;
} }
else args = nosetup_args; else args = nosetup_args;

View File

@ -0,0 +1,14 @@
# Basic kernel hardening options (specific to x86)
# Modern libc no longer needs a fixed-position mapping in userspace, remove
# it as a possible target.
CONFIG_LEGACY_VSYSCALL_NONE=y
# Enable chip-specific IOMMU support.
CONFIG_INTEL_IOMMU=y
CONFIG_INTEL_IOMMU_DEFAULT_ON=y
CONFIG_INTEL_IOMMU_SVM=y
CONFIG_AMD_IOMMU=y
# Enable CET Shadow Stack for userspace.
CONFIG_X86_USER_SHADOW_STACK=y

View File

@ -51,7 +51,7 @@ struct ivpu_job {
u32 job_id; u32 job_id;
u32 engine_idx; u32 engine_idx;
size_t bo_count; size_t bo_count;
struct ivpu_bo *bos[]; struct ivpu_bo *bos[] __counted_by(bo_count);
}; };
int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file); int ivpu_submit_ioctl(struct drm_device *dev, void *data, struct drm_file *file);

View File

@ -1449,10 +1449,9 @@ static struct logical_input *panel_bind_key(const char *name, const char *press,
key->rise_time = 1; key->rise_time = 1;
key->fall_time = 1; key->fall_time = 1;
strncpy(key->u.kbd.press_str, press, sizeof(key->u.kbd.press_str)); strtomem_pad(key->u.kbd.press_str, press, '\0');
strncpy(key->u.kbd.repeat_str, repeat, sizeof(key->u.kbd.repeat_str)); strtomem_pad(key->u.kbd.repeat_str, repeat, '\0');
strncpy(key->u.kbd.release_str, release, strtomem_pad(key->u.kbd.release_str, release, '\0');
sizeof(key->u.kbd.release_str));
list_add(&key->list, &logical_inputs); list_add(&key->list, &logical_inputs);
return key; return key;
} }

View File

@ -555,7 +555,7 @@ struct fifo_buffer {
unsigned int head_index; unsigned int head_index;
unsigned int size; unsigned int size;
int total; /* sum of all values */ int total; /* sum of all values */
int values[]; int values[] __counted_by(size);
}; };
extern struct fifo_buffer *fifo_alloc(unsigned int fifo_size); extern struct fifo_buffer *fifo_alloc(unsigned int fifo_size);

View File

@ -450,10 +450,8 @@ int dprc_get_obj(struct fsl_mc_io *mc_io,
obj_desc->ver_major = le16_to_cpu(rsp_params->version_major); obj_desc->ver_major = le16_to_cpu(rsp_params->version_major);
obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor); obj_desc->ver_minor = le16_to_cpu(rsp_params->version_minor);
obj_desc->flags = le16_to_cpu(rsp_params->flags); obj_desc->flags = le16_to_cpu(rsp_params->flags);
strncpy(obj_desc->type, rsp_params->type, 16); strscpy_pad(obj_desc->type, rsp_params->type, 16);
obj_desc->type[15] = '\0'; strscpy_pad(obj_desc->label, rsp_params->label, 16);
strncpy(obj_desc->label, rsp_params->label, 16);
obj_desc->label[15] = '\0';
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(dprc_get_obj); EXPORT_SYMBOL_GPL(dprc_get_obj);
@ -491,8 +489,7 @@ int dprc_set_obj_irq(struct fsl_mc_io *mc_io,
cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr); cmd_params->irq_addr = cpu_to_le64(irq_cfg->paddr);
cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num); cmd_params->irq_num = cpu_to_le32(irq_cfg->irq_num);
cmd_params->obj_id = cpu_to_le32(obj_id); cmd_params->obj_id = cpu_to_le32(obj_id);
strncpy(cmd_params->obj_type, obj_type, 16); strscpy_pad(cmd_params->obj_type, obj_type, 16);
cmd_params->obj_type[15] = '\0';
/* send command to mc*/ /* send command to mc*/
return mc_send_command(mc_io, &cmd); return mc_send_command(mc_io, &cmd);
@ -564,8 +561,7 @@ int dprc_get_obj_region(struct fsl_mc_io *mc_io,
cmd_params = (struct dprc_cmd_get_obj_region *)cmd.params; cmd_params = (struct dprc_cmd_get_obj_region *)cmd.params;
cmd_params->obj_id = cpu_to_le32(obj_id); cmd_params->obj_id = cpu_to_le32(obj_id);
cmd_params->region_index = region_index; cmd_params->region_index = region_index;
strncpy(cmd_params->obj_type, obj_type, 16); strscpy_pad(cmd_params->obj_type, obj_type, 16);
cmd_params->obj_type[15] = '\0';
/* send command to mc*/ /* send command to mc*/
err = mc_send_command(mc_io, &cmd); err = mc_send_command(mc_io, &cmd);

View File

@ -106,7 +106,7 @@ struct port_buffer {
unsigned int sgpages; unsigned int sgpages;
/* sg is used if spages > 0. sg must be the last in is struct */ /* sg is used if spages > 0. sg must be the last in is struct */
struct scatterlist sg[]; struct scatterlist sg[] __counted_by(sgpages);
}; };
/* /*

View File

@ -1650,7 +1650,7 @@ static void __cpufreq_offline(unsigned int cpu, struct cpufreq_policy *policy)
} }
if (has_target()) if (has_target())
strncpy(policy->last_governor, policy->governor->name, strscpy(policy->last_governor, policy->governor->name,
CPUFREQ_NAME_LEN); CPUFREQ_NAME_LEN);
else else
policy->last_policy = policy->policy; policy->last_policy = policy->policy;
@ -2996,7 +2996,7 @@ static int __init cpufreq_core_init(void)
BUG_ON(!cpufreq_global_kobject); BUG_ON(!cpufreq_global_kobject);
if (!strlen(default_governor)) if (!strlen(default_governor))
strncpy(default_governor, gov->name, CPUFREQ_NAME_LEN); strscpy(default_governor, gov->name, CPUFREQ_NAME_LEN);
return 0; return 0;
} }

View File

@ -84,8 +84,8 @@ static int init_state_node(struct cpuidle_state *idle_state,
* replace with kstrdup and pointer assignment when name * replace with kstrdup and pointer assignment when name
* and desc become string pointers * and desc become string pointers
*/ */
strncpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN - 1); strscpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN);
strncpy(idle_state->desc, desc, CPUIDLE_DESC_LEN - 1); strscpy(idle_state->desc, desc, CPUIDLE_DESC_LEN);
return 0; return 0;
} }

View File

@ -229,7 +229,7 @@ static ssize_t channel_dimm_label_store(struct device *dev,
if (copy_count == 0 || copy_count >= sizeof(rank->dimm->label)) if (copy_count == 0 || copy_count >= sizeof(rank->dimm->label))
return -EINVAL; return -EINVAL;
strncpy(rank->dimm->label, data, copy_count); memcpy(rank->dimm->label, data, copy_count);
rank->dimm->label[copy_count] = '\0'; rank->dimm->label[copy_count] = '\0';
return count; return count;
@ -535,7 +535,7 @@ static ssize_t dimmdev_label_store(struct device *dev,
if (copy_count == 0 || copy_count >= sizeof(dimm->label)) if (copy_count == 0 || copy_count >= sizeof(dimm->label))
return -EINVAL; return -EINVAL;
strncpy(dimm->label, data, copy_count); memcpy(dimm->label, data, copy_count);
dimm->label[copy_count] = '\0'; dimm->label[copy_count] = '\0';
return count; return count;

View File

@ -610,7 +610,7 @@ static int debugfs_show(struct seq_file *m, void *p)
} }
len = strlen(filename); len = strlen(filename);
strncpy(namevirt, filename, namesize); strscpy_pad(namevirt, filename, namesize);
err = mrq_debugfs_read(bpmp, namephys, len, dataphys, datasize, err = mrq_debugfs_read(bpmp, namephys, len, dataphys, datasize,
&nbytes); &nbytes);
@ -661,7 +661,7 @@ static ssize_t debugfs_store(struct file *file, const char __user *buf,
} }
len = strlen(filename); len = strlen(filename);
strncpy(namevirt, filename, namesize); strscpy_pad(namevirt, filename, namesize);
if (copy_from_user(datavirt, buf, count)) { if (copy_from_user(datavirt, buf, count)) {
err = -EFAULT; err = -EFAULT;

View File

@ -503,7 +503,7 @@ int gud_pipe_check(struct drm_simple_display_pipe *pipe,
return -ENOENT; return -ENOENT;
len = struct_size(req, properties, len = struct_size(req, properties,
GUD_PROPERTIES_MAX_NUM + GUD_CONNECTOR_PROPERTIES_MAX_NUM); size_add(GUD_PROPERTIES_MAX_NUM, GUD_CONNECTOR_PROPERTIES_MAX_NUM));
req = kzalloc(len, GFP_KERNEL); req = kzalloc(len, GFP_KERNEL);
if (!req) if (!req)
return -ENOMEM; return -ENOMEM;

View File

@ -67,7 +67,7 @@ struct nouveau_svm {
struct nouveau_svmm *svmm; struct nouveau_svmm *svmm;
} **fault; } **fault;
int fault_nr; int fault_nr;
} buffer[1]; } buffer[];
}; };
#define FAULT_ACCESS_READ 0 #define FAULT_ACCESS_READ 0
@ -1063,7 +1063,8 @@ nouveau_svm_init(struct nouveau_drm *drm)
if (drm->client.device.info.family > NV_DEVICE_INFO_V0_PASCAL) if (drm->client.device.info.family > NV_DEVICE_INFO_V0_PASCAL)
return; return;
if (!(drm->svm = svm = kzalloc(sizeof(*drm->svm), GFP_KERNEL))) drm->svm = svm = kzalloc(struct_size(drm->svm, buffer, 1), GFP_KERNEL);
if (!drm->svm)
return; return;
drm->svm->drm = drm; drm->svm->drm = drm;

View File

@ -639,9 +639,9 @@ static int pcmidi_snd_initialise(struct pcmidi_snd *pm)
goto fail; goto fail;
} }
strncpy(card->driver, shortname, sizeof(card->driver)); strscpy(card->driver, shortname, sizeof(card->driver));
strncpy(card->shortname, shortname, sizeof(card->shortname)); strscpy(card->shortname, shortname, sizeof(card->shortname));
strncpy(card->longname, longname, sizeof(card->longname)); strscpy(card->longname, longname, sizeof(card->longname));
/* Set up rawmidi */ /* Set up rawmidi */
err = snd_rawmidi_new(card, card->shortname, 0, err = snd_rawmidi_new(card, card->shortname, 0,
@ -652,7 +652,7 @@ static int pcmidi_snd_initialise(struct pcmidi_snd *pm)
goto fail; goto fail;
} }
pm->rwmidi = rwmidi; pm->rwmidi = rwmidi;
strncpy(rwmidi->name, card->shortname, sizeof(rwmidi->name)); strscpy(rwmidi->name, card->shortname, sizeof(rwmidi->name));
rwmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT; rwmidi->info_flags = SNDRV_RAWMIDI_INFO_INPUT;
rwmidi->private_data = pm; rwmidi->private_data = pm;

View File

@ -796,14 +796,13 @@ static int read_capabilities(struct acpi_power_meter_resource *resource)
goto error; goto error;
} }
*str = kcalloc(element->string.length + 1, sizeof(u8), *str = kmemdup_nul(element->string.pointer, element->string.length,
GFP_KERNEL); GFP_KERNEL);
if (!*str) { if (!*str) {
res = -ENOMEM; res = -ENOMEM;
goto error; goto error;
} }
strncpy(*str, element->string.pointer, element->string.length);
str++; str++;
} }

View File

@ -300,7 +300,7 @@ static int asus_wmi_sensor_info(int index, struct asus_wmi_sensor_info *s)
goto out_free_obj; goto out_free_obj;
} }
strncpy(s->name, name_obj.string.pointer, sizeof(s->name) - 1); strscpy(s->name, name_obj.string.pointer, sizeof(s->name));
data_type_obj = obj->package.elements[1]; data_type_obj = obj->package.elements[1];
if (data_type_obj.type != ACPI_TYPE_INTEGER) { if (data_type_obj.type != ACPI_TYPE_INTEGER) {

View File

@ -234,7 +234,7 @@ static int get_sensor_index_attr(const char *name, u32 *index, char *attr)
if (copy_len >= sizeof(buf)) if (copy_len >= sizeof(buf))
return -EINVAL; return -EINVAL;
strncpy(buf, hash_pos + 1, copy_len); memcpy(buf, hash_pos + 1, copy_len);
err = kstrtou32(buf, 10, index); err = kstrtou32(buf, 10, index);
if (err) if (err)

View File

@ -73,7 +73,7 @@ struct intmux_data {
void __iomem *regs; void __iomem *regs;
struct clk *ipg_clk; struct clk *ipg_clk;
int channum; int channum;
struct intmux_irqchip_data irqchip_data[]; struct intmux_irqchip_data irqchip_data[] __counted_by(channum);
}; };
static void imx_intmux_irq_mask(struct irq_data *d) static void imx_intmux_irq_mask(struct irq_data *d)

View File

@ -732,7 +732,7 @@ u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN])
u16 ret; u16 ret;
if (contr == 0) { if (contr == 0) {
strncpy(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN); strscpy_pad(buf, capi_manufakturer, CAPI_MANUFACTURER_LEN);
return CAPI_NOERROR; return CAPI_NOERROR;
} }
@ -740,7 +740,7 @@ u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN])
ctr = get_capi_ctr_by_nr(contr); ctr = get_capi_ctr_by_nr(contr);
if (ctr && ctr->state == CAPI_CTR_RUNNING) { if (ctr && ctr->state == CAPI_CTR_RUNNING) {
strncpy(buf, ctr->manu, CAPI_MANUFACTURER_LEN); strscpy_pad(buf, ctr->manu, CAPI_MANUFACTURER_LEN);
ret = CAPI_NOERROR; ret = CAPI_NOERROR;
} else } else
ret = CAPI_REGNOTINSTALLED; ret = CAPI_REGNOTINSTALLED;

View File

@ -96,7 +96,7 @@ struct mISDNclock
printk(KERN_ERR "%s: No memory for clock entry.\n", __func__); printk(KERN_ERR "%s: No memory for clock entry.\n", __func__);
return NULL; return NULL;
} }
strncpy(iclock->name, name, sizeof(iclock->name) - 1); strscpy(iclock->name, name, sizeof(iclock->name));
iclock->pri = pri; iclock->pri = pri;
iclock->priv = priv; iclock->priv = priv;
iclock->ctl = ctl; iclock->ctl = ctl;

View File

@ -108,7 +108,7 @@ struct zynqmp_ipi_pdata {
unsigned int method; unsigned int method;
u32 local_id; u32 local_id;
int num_mboxes; int num_mboxes;
struct zynqmp_ipi_mbox ipi_mboxes[]; struct zynqmp_ipi_mbox ipi_mboxes[] __counted_by(num_mboxes);
}; };
static struct device_driver zynqmp_ipi_mbox_driver = { static struct device_driver zynqmp_ipi_mbox_driver = {

View File

@ -26,7 +26,7 @@ struct prison_region {
struct dm_bio_prison { struct dm_bio_prison {
mempool_t cell_pool; mempool_t cell_pool;
unsigned int num_locks; unsigned int num_locks;
struct prison_region regions[]; struct prison_region regions[] __counted_by(num_locks);
}; };
static struct kmem_cache *_cell_cache; static struct kmem_cache *_cell_cache;

View File

@ -224,7 +224,7 @@ struct crypt_config {
struct mutex bio_alloc_lock; struct mutex bio_alloc_lock;
u8 *authenc_key; /* space for keys in authenc() format (if used) */ u8 *authenc_key; /* space for keys in authenc() format (if used) */
u8 key[]; u8 key[] __counted_by(key_size);
}; };
#define MIN_IOS 64 #define MIN_IOS 64

View File

@ -254,7 +254,7 @@ struct raid_set {
int mode; int mode;
} journal_dev; } journal_dev;
struct raid_dev dev[]; struct raid_dev dev[] __counted_by(raid_disks);
}; };
static void rs_config_backup(struct raid_set *rs, struct rs_layout *l) static void rs_config_backup(struct raid_set *rs, struct rs_layout *l)

View File

@ -56,7 +56,7 @@ struct dm_stat {
size_t percpu_alloc_size; size_t percpu_alloc_size;
size_t histogram_alloc_size; size_t histogram_alloc_size;
struct dm_stat_percpu *stat_percpu[NR_CPUS]; struct dm_stat_percpu *stat_percpu[NR_CPUS];
struct dm_stat_shared stat_shared[]; struct dm_stat_shared stat_shared[] __counted_by(n_entries);
}; };
#define STAT_PRECISE_TIMESTAMPS 1 #define STAT_PRECISE_TIMESTAMPS 1

View File

@ -44,7 +44,7 @@ struct stripe_c {
/* Work struct used for triggering events*/ /* Work struct used for triggering events*/
struct work_struct trigger_event; struct work_struct trigger_event;
struct stripe stripe[]; struct stripe stripe[] __counted_by(stripes);
}; };
/* /*

View File

@ -6,12 +6,14 @@
* test source files. * test source files.
*/ */
#include "lkdtm.h" #include "lkdtm.h"
#include <linux/cpu.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/sched/signal.h> #include <linux/sched/signal.h>
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
#include <linux/uaccess.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/stop_machine.h>
#include <linux/uaccess.h>
#if IS_ENABLED(CONFIG_X86_32) && !IS_ENABLED(CONFIG_UML) #if IS_ENABLED(CONFIG_X86_32) && !IS_ENABLED(CONFIG_UML)
#include <asm/desc.h> #include <asm/desc.h>
@ -73,6 +75,31 @@ static void lkdtm_PANIC(void)
panic("dumptest"); panic("dumptest");
} }
static int panic_stop_irqoff_fn(void *arg)
{
atomic_t *v = arg;
/*
* As stop_machine() disables interrupts, all CPUs within this function
* have interrupts disabled and cannot take a regular IPI.
*
* The last CPU which enters here will trigger a panic, and as all CPUs
* cannot take a regular IPI, we'll only be able to stop secondaries if
* smp_send_stop() or crash_smp_send_stop() uses an NMI.
*/
if (atomic_inc_return(v) == num_online_cpus())
panic("panic stop irqoff test");
for (;;)
cpu_relax();
}
static void lkdtm_PANIC_STOP_IRQOFF(void)
{
atomic_t v = ATOMIC_INIT(0);
stop_machine(panic_stop_irqoff_fn, &v, cpu_online_mask);
}
static void lkdtm_BUG(void) static void lkdtm_BUG(void)
{ {
BUG(); BUG();
@ -638,6 +665,7 @@ static noinline void lkdtm_CORRUPT_PAC(void)
static struct crashtype crashtypes[] = { static struct crashtype crashtypes[] = {
CRASHTYPE(PANIC), CRASHTYPE(PANIC),
CRASHTYPE(PANIC_STOP_IRQOFF),
CRASHTYPE(BUG), CRASHTYPE(BUG),
CRASHTYPE(WARNING), CRASHTYPE(WARNING),
CRASHTYPE(WARNING_MESSAGE), CRASHTYPE(WARNING_MESSAGE),

View File

@ -60,7 +60,7 @@ struct reset_control {
struct reset_control_array { struct reset_control_array {
struct reset_control base; struct reset_control base;
unsigned int num_rstcs; unsigned int num_rstcs;
struct reset_control *rstc[]; struct reset_control *rstc[] __counted_by(num_rstcs);
}; };
static const char *rcdev_name(struct reset_controller_dev *rcdev) 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,
resets = kzalloc(struct_size(resets, rstc, num), GFP_KERNEL); resets = kzalloc(struct_size(resets, rstc, num), GFP_KERNEL);
if (!resets) if (!resets)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
resets->num_rstcs = num;
for (i = 0; i < num; i++) { for (i = 0; i < num; i++) {
rstc = __of_reset_control_get(np, NULL, i, shared, optional, 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,
goto err_rst; goto err_rst;
resets->rstc[i] = rstc; resets->rstc[i] = rstc;
} }
resets->num_rstcs = num;
resets->base.array = true; resets->base.array = true;
return &resets->base; return &resets->base;

View File

@ -585,7 +585,7 @@ struct tsens_priv {
struct dentry *debug_root; struct dentry *debug_root;
struct dentry *debug; struct dentry *debug;
struct tsens_sensor sensor[]; struct tsens_sensor sensor[] __counted_by(num_sensors);
}; };
/** /**

View File

@ -1018,7 +1018,8 @@ int usbatm_usb_probe(struct usb_interface *intf, const struct usb_device_id *id,
size_t size; size_t size;
/* instance init */ /* instance init */
size = struct_size(instance, urbs, num_rcv_urbs + num_snd_urbs); size = struct_size(instance, urbs,
size_add(num_rcv_urbs, num_snd_urbs));
instance = kzalloc(size, GFP_KERNEL); instance = kzalloc(size, GFP_KERNEL);
if (!instance) if (!instance)
return -ENOMEM; return -ENOMEM;

View File

@ -202,7 +202,7 @@ struct ffs_epfile {
struct ffs_buffer { struct ffs_buffer {
size_t length; size_t length;
char *data; char *data;
char storage[]; char storage[] __counted_by(length);
}; };
/* ffs_io_data structure ***************************************************/ /* ffs_io_data structure ***************************************************/

View File

@ -99,7 +99,7 @@ struct f_midi {
unsigned int in_last_port; unsigned int in_last_port;
unsigned char free_ref; unsigned char free_ref;
struct gmidi_in_port in_ports_array[/* in_ports */]; struct gmidi_in_port in_ports_array[] __counted_by(in_ports);
}; };
static inline struct f_midi *func_to_midi(struct usb_function *f) 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)
status = -ENOMEM; status = -ENOMEM;
goto setup_fail; goto setup_fail;
} }
midi->in_ports = opts->in_ports;
for (i = 0; i < opts->in_ports; i++) for (i = 0; i < opts->in_ports; i++)
midi->in_ports_array[i].cable = i; midi->in_ports_array[i].cable = i;
@ -1359,7 +1360,6 @@ static struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
status = -ENOMEM; status = -ENOMEM;
goto midi_free; goto midi_free;
} }
midi->in_ports = opts->in_ports;
midi->out_ports = opts->out_ports; midi->out_ports = opts->out_ports;
midi->index = opts->index; midi->index = opts->index;
midi->buflen = opts->buflen; midi->buflen = opts->buflen;

View File

@ -337,7 +337,7 @@ typedef struct urb_priv {
u16 length; // # tds in this request u16 length; // # tds in this request
u16 td_cnt; // tds already serviced u16 td_cnt; // tds already serviced
struct list_head pending; struct list_head pending;
struct td *td[]; // all TDs in this request struct td *td[] __counted_by(length); // all TDs in this request
} urb_priv_t; } urb_priv_t;

View File

@ -1666,7 +1666,7 @@ struct xhci_scratchpad {
struct urb_priv { struct urb_priv {
int num_tds; int num_tds;
int num_tds_done; int num_tds_done;
struct xhci_td td[]; struct xhci_td td[] __counted_by(num_tds);
}; };
/* /*

View File

@ -60,7 +60,7 @@ struct vm_memory_region_batch {
u16 reserved[3]; u16 reserved[3];
u32 regions_num; u32 regions_num;
u64 regions_gpa; u64 regions_gpa;
struct vm_memory_region_op regions_op[]; struct vm_memory_region_op regions_op[] __counted_by(regions_num);
}; };
/** /**

View File

@ -250,11 +250,11 @@ int acrn_vm_ram_map(struct acrn_vm *vm, struct acrn_vm_memmap *memmap)
ret = -ENOMEM; ret = -ENOMEM;
goto unmap_kernel_map; goto unmap_kernel_map;
} }
regions_info->regions_num = nr_regions;
/* Fill each vm_memory_region_op */ /* Fill each vm_memory_region_op */
vm_region = regions_info->regions_op; vm_region = regions_info->regions_op;
regions_info->vmid = vm->vmid; regions_info->vmid = vm->vmid;
regions_info->regions_num = nr_regions;
regions_info->regions_gpa = virt_to_phys(vm_region); regions_info->regions_gpa = virt_to_phys(vm_region);
user_vm_pa = memmap->user_vm_pa; user_vm_pa = memmap->user_vm_pa;
i = 0; i = 0;

View File

@ -87,7 +87,7 @@ struct afs_addr_list {
enum dns_lookup_status status:8; enum dns_lookup_status status:8;
unsigned long failed; /* Mask of addrs that failed locally/ICMP */ unsigned long failed; /* Mask of addrs that failed locally/ICMP */
unsigned long responded; /* Mask of addrs that responded */ unsigned long responded; /* Mask of addrs that responded */
struct sockaddr_rxrpc addrs[]; struct sockaddr_rxrpc addrs[] __counted_by(max_addrs);
#define AFS_MAX_ADDRESSES ((unsigned int)(sizeof(unsigned long) * 8)) #define AFS_MAX_ADDRESSES ((unsigned int)(sizeof(unsigned long) * 8))
}; };
@ -705,7 +705,7 @@ struct afs_permits {
refcount_t usage; refcount_t usage;
unsigned short nr_permits; /* Number of records */ unsigned short nr_permits; /* Number of records */
bool invalidated; /* Invalidated due to key change */ bool invalidated; /* Invalidated due to key change */
struct afs_permit permits[]; /* List of permits sorted by key pointer */ struct afs_permit permits[] __counted_by(nr_permits); /* List of permits sorted by key pointer */
}; };
/* /*

View File

@ -51,7 +51,7 @@ struct nfs4_file_layout_dsaddr {
u32 stripe_count; u32 stripe_count;
u8 *stripe_indices; u8 *stripe_indices;
u32 ds_num; u32 ds_num;
struct nfs4_pnfs_ds *ds_list[]; struct nfs4_pnfs_ds *ds_list[] __counted_by(ds_num);
}; };
struct nfs4_filelayout_segment { struct nfs4_filelayout_segment {

View File

@ -99,7 +99,7 @@ struct nfs4_ff_layout_segment {
u64 stripe_unit; u64 stripe_unit;
u32 flags; u32 flags;
u32 mirror_array_cnt; u32 mirror_array_cnt;
struct nfs4_ff_layout_mirror *mirror_array[]; struct nfs4_ff_layout_mirror *mirror_array[] __counted_by(mirror_array_cnt);
}; };
struct nfs4_flexfile_layout { struct nfs4_flexfile_layout {

View File

@ -37,7 +37,7 @@ struct ocfs2_slot_info {
unsigned int si_blocks; unsigned int si_blocks;
struct buffer_head **si_bh; struct buffer_head **si_bh;
unsigned int si_num_slots; unsigned int si_num_slots;
struct ocfs2_slot si_slots[]; struct ocfs2_slot si_slots[] __counted_by(si_num_slots);
}; };

View File

@ -278,7 +278,7 @@ struct ceph_osd_request {
int r_attempts; int r_attempts;
u32 r_map_dne_bound; u32 r_map_dne_bound;
struct ceph_osd_req_op r_ops[]; struct ceph_osd_req_op r_ops[] __counted_by(r_num_ops);
}; };
struct ceph_request_redirect { struct ceph_request_redirect {

View File

@ -92,7 +92,7 @@ int parse_crashkernel_low(char *cmdline, unsigned long long system_ram,
struct crash_mem { struct crash_mem {
unsigned int max_nr_ranges; unsigned int max_nr_ranges;
unsigned int nr_ranges; unsigned int nr_ranges;
struct range ranges[]; struct range ranges[] __counted_by(max_nr_ranges);
}; };
extern int crash_exclude_mem_range(struct crash_mem *mem, extern int crash_exclude_mem_range(struct crash_mem *mem,

View File

@ -12,6 +12,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/key.h> #include <linux/key.h>
#include <linux/atomic.h> #include <linux/atomic.h>
#include <linux/refcount.h>
#include <linux/uidgid.h> #include <linux/uidgid.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/sched/user.h> #include <linux/sched/user.h>
@ -23,7 +24,7 @@ struct inode;
* COW Supplementary groups list * COW Supplementary groups list
*/ */
struct group_info { struct group_info {
atomic_t usage; refcount_t usage;
int ngroups; int ngroups;
kgid_t gid[]; kgid_t gid[];
} __randomize_layout; } __randomize_layout;
@ -39,7 +40,7 @@ struct group_info {
*/ */
static inline struct group_info *get_group_info(struct group_info *gi) static inline struct group_info *get_group_info(struct group_info *gi)
{ {
atomic_inc(&gi->usage); refcount_inc(&gi->usage);
return gi; return gi;
} }
@ -49,7 +50,7 @@ static inline struct group_info *get_group_info(struct group_info *gi)
*/ */
#define put_group_info(group_info) \ #define put_group_info(group_info) \
do { \ do { \
if (atomic_dec_and_test(&(group_info)->usage)) \ if (refcount_dec_and_test(&(group_info)->usage)) \
groups_free(group_info); \ groups_free(group_info); \
} while (0) } while (0)

View File

@ -664,7 +664,7 @@ struct kvm_irq_routing_table {
* Array indexed by gsi. Each entry contains list of irq chips * Array indexed by gsi. Each entry contains list of irq chips
* the gsi is connected to. * the gsi is connected to.
*/ */
struct hlist_head map[]; struct hlist_head map[] __counted_by(nr_rt_entries);
}; };
#endif #endif

View File

@ -40,6 +40,6 @@ struct gsc_hwmon_platform_data {
unsigned int resolution; unsigned int resolution;
unsigned int vreference; unsigned int vreference;
unsigned int fan_base; unsigned int fan_base;
struct gsc_hwmon_channel channels[]; struct gsc_hwmon_channel channels[] __counted_by(nchannels);
}; };
#endif #endif

View File

@ -277,10 +277,12 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
*/ */
#define strtomem_pad(dest, src, pad) do { \ #define strtomem_pad(dest, src, pad) do { \
const size_t _dest_len = __builtin_object_size(dest, 1); \ const size_t _dest_len = __builtin_object_size(dest, 1); \
const size_t _src_len = __builtin_object_size(src, 1); \
\ \
BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \
_dest_len == (size_t)-1); \ _dest_len == (size_t)-1); \
memcpy_and_pad(dest, _dest_len, src, strnlen(src, _dest_len), pad); \ memcpy_and_pad(dest, _dest_len, src, \
strnlen(src, min(_src_len, _dest_len)), pad); \
} while (0) } while (0)
/** /**
@ -298,10 +300,11 @@ void memcpy_and_pad(void *dest, size_t dest_len, const void *src, size_t count,
*/ */
#define strtomem(dest, src) do { \ #define strtomem(dest, src) do { \
const size_t _dest_len = __builtin_object_size(dest, 1); \ const size_t _dest_len = __builtin_object_size(dest, 1); \
const size_t _src_len = __builtin_object_size(src, 1); \
\ \
BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \ BUILD_BUG_ON(!__builtin_constant_p(_dest_len) || \
_dest_len == (size_t)-1); \ _dest_len == (size_t)-1); \
memcpy(dest, src, min(_dest_len, strnlen(src, _dest_len))); \ memcpy(dest, src, strnlen(src, min(_src_len, _dest_len))); \
} while (0) } while (0)
/** /**

View File

@ -21,10 +21,10 @@ static int __init early_hostname(char *arg)
{ {
size_t bufsize = sizeof(init_uts_ns.name.nodename); size_t bufsize = sizeof(init_uts_ns.name.nodename);
size_t maxlen = bufsize - 1; size_t maxlen = bufsize - 1;
size_t arglen; ssize_t arglen;
arglen = strlcpy(init_uts_ns.name.nodename, arg, bufsize); arglen = strscpy(init_uts_ns.name.nodename, arg, bufsize);
if (arglen > maxlen) { if (arglen < 0) {
pr_warn("hostname parameter exceeds %zd characters and will be truncated", pr_warn("hostname parameter exceeds %zd characters and will be truncated",
maxlen); maxlen);
} }

View File

@ -0,0 +1,98 @@
# Help: Basic kernel hardening options
#
# These are considered the basic kernel hardening, self-protection, and
# attack surface reduction options. They are expected to have low (or
# no) performance impact on most workloads, and have a reasonable level
# of legacy API removals.
# Make sure reporting of various hardening actions is possible.
CONFIG_BUG=y
# Basic kernel memory permission enforcement.
CONFIG_STRICT_KERNEL_RWX=y
CONFIG_STRICT_MODULE_RWX=y
CONFIG_VMAP_STACK=y
# Kernel image and memory ASLR.
CONFIG_RANDOMIZE_BASE=y
CONFIG_RANDOMIZE_MEMORY=y
# Randomize allocator freelists, harden metadata.
CONFIG_SLAB_FREELIST_RANDOM=y
CONFIG_SLAB_FREELIST_HARDENED=y
CONFIG_SHUFFLE_PAGE_ALLOCATOR=y
CONFIG_RANDOM_KMALLOC_CACHES=y
# Randomize kernel stack offset on syscall entry.
CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT=y
# Basic stack frame overflow protection.
CONFIG_STACKPROTECTOR=y
CONFIG_STACKPROTECTOR_STRONG=y
# Basic buffer length bounds checking.
CONFIG_HARDENED_USERCOPY=y
CONFIG_FORTIFY_SOURCE=y
# Basic array index bounds checking.
CONFIG_UBSAN=y
CONFIG_UBSAN_TRAP=y
CONFIG_UBSAN_BOUNDS=y
# CONFIG_UBSAN_SHIFT is not set
# CONFIG_UBSAN_DIV_ZERO
# CONFIG_UBSAN_UNREACHABLE
# CONFIG_UBSAN_BOOL
# CONFIG_UBSAN_ENUM
# CONFIG_UBSAN_ALIGNMENT
CONFIG_UBSAN_SANITIZE_ALL=y
# Linked list integrity checking.
CONFIG_LIST_HARDENED=y
# Initialize all heap variables to zero on allocation.
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
# Initialize all stack variables to zero on function entry.
CONFIG_INIT_STACK_ALL_ZERO=y
# Wipe RAM at reboot via EFI. For more details, see:
# https://trustedcomputinggroup.org/resource/pc-client-work-group-platform-reset-attack-mitigation-specification/
# https://bugzilla.redhat.com/show_bug.cgi?id=1532058
CONFIG_RESET_ATTACK_MITIGATION=y
# Disable DMA between EFI hand-off and the kernel's IOMMU setup.
CONFIG_EFI_DISABLE_PCI_DMA=y
# Force IOMMU TLB invalidation so devices will never be able to access stale
# data content.
CONFIG_IOMMU_SUPPORT=y
CONFIG_IOMMU_DEFAULT_DMA_STRICT=y
# Do not allow direct physical memory access to non-device memory.
CONFIG_STRICT_DEVMEM=y
CONFIG_IO_STRICT_DEVMEM=y
# Provide userspace with seccomp BPF API for syscall attack surface reduction.
CONFIG_SECCOMP=y
CONFIG_SECCOMP_FILTER=y
# Provides some protections against SYN flooding.
CONFIG_SYN_COOKIES=y
# Attack surface reduction: do not autoload TTY line disciplines.
# CONFIG_LDISC_AUTOLOAD is not set
# Dangerous; enabling this disables userspace brk ASLR.
# CONFIG_COMPAT_BRK is not set
# Dangerous; exposes kernel text image layout.
# CONFIG_PROC_KCORE is not set
# Dangerous; enabling this disables userspace VDSO ASLR.
# CONFIG_COMPAT_VDSO is not set
# Attack surface reduction: Use the modern PTY interface (devpts) only.
# CONFIG_LEGACY_PTYS is not set
# Attack surface reduction: Use only modesetting video drivers.
# CONFIG_DRM_LEGACY is not set

View File

@ -36,7 +36,7 @@ do { \
static struct kmem_cache *cred_jar; static struct kmem_cache *cred_jar;
/* init to 2 - one for init_task, one to ensure it is never freed */ /* init to 2 - one for init_task, one to ensure it is never freed */
static struct group_info init_groups = { .usage = ATOMIC_INIT(2) }; static struct group_info init_groups = { .usage = REFCOUNT_INIT(2) };
/* /*
* The initial credentials for the initial task * The initial credentials for the initial task

View File

@ -19,7 +19,7 @@ struct group_info *groups_alloc(int gidsetsize)
if (!gi) if (!gi)
return NULL; return NULL;
atomic_set(&gi->usage, 1); refcount_set(&gi->usage, 1);
gi->ngroups = gidsetsize; gi->ngroups = gidsetsize;
return gi; return gi;
} }

View File

@ -254,10 +254,10 @@ static int init_uevent_argv(struct kobj_uevent_env *env, const char *subsystem)
int buffer_size = sizeof(env->buf) - env->buflen; int buffer_size = sizeof(env->buf) - env->buflen;
int len; int len;
len = strlcpy(&env->buf[env->buflen], subsystem, buffer_size); len = strscpy(&env->buf[env->buflen], subsystem, buffer_size);
if (len >= buffer_size) { if (len < 0) {
pr_warn("init_uevent_argv: buffer size of %d too small, needed %d\n", pr_warn("%s: insufficient buffer space (%u left) for %s\n",
buffer_size, len); __func__, buffer_size, subsystem);
return -ENOMEM; return -ENOMEM;
} }

View File

@ -191,12 +191,14 @@ static void partition_struct(tree *fields, unsigned long length, struct partitio
static void performance_shuffle(tree *newtree, unsigned long length, ranctx *prng_state) static void performance_shuffle(tree *newtree, unsigned long length, ranctx *prng_state)
{ {
unsigned long i, x; unsigned long i, x, index;
struct partition_group size_group[length]; struct partition_group size_group[length];
unsigned long num_groups = 0; unsigned long num_groups = 0;
unsigned long randnum; unsigned long randnum;
partition_struct(newtree, length, (struct partition_group *)&size_group, &num_groups); partition_struct(newtree, length, (struct partition_group *)&size_group, &num_groups);
/* FIXME: this group shuffle is currently a no-op. */
for (i = num_groups - 1; i > 0; i--) { for (i = num_groups - 1; i > 0; i--) {
struct partition_group tmp; struct partition_group tmp;
randnum = ranval(prng_state) % (i + 1); randnum = ranval(prng_state) % (i + 1);
@ -206,11 +208,14 @@ static void performance_shuffle(tree *newtree, unsigned long length, ranctx *prn
} }
for (x = 0; x < num_groups; x++) { for (x = 0; x < num_groups; x++) {
for (i = size_group[x].start + size_group[x].length - 1; i > size_group[x].start; i--) { for (index = size_group[x].length - 1; index > 0; index--) {
tree tmp; tree tmp;
i = size_group[x].start + index;
if (DECL_BIT_FIELD_TYPE(newtree[i])) if (DECL_BIT_FIELD_TYPE(newtree[i]))
continue; continue;
randnum = ranval(prng_state) % (i + 1); randnum = ranval(prng_state) % (index + 1);
randnum += size_group[x].start;
// we could handle this case differently if desired // we could handle this case differently if desired
if (DECL_BIT_FIELD_TYPE(newtree[randnum])) if (DECL_BIT_FIELD_TYPE(newtree[randnum]))
continue; continue;

View File

@ -29,7 +29,7 @@ struct modsig {
* storing the signature. * storing the signature.
*/ */
int raw_pkcs7_len; int raw_pkcs7_len;
u8 raw_pkcs7[]; u8 raw_pkcs7[] __counted_by(raw_pkcs7_len);
}; };
/* /*
@ -65,10 +65,11 @@ int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len,
buf_len -= sig_len + sizeof(*sig); buf_len -= sig_len + sizeof(*sig);
/* Allocate sig_len additional bytes to hold the raw PKCS#7 data. */ /* Allocate sig_len additional bytes to hold the raw PKCS#7 data. */
hdr = kzalloc(sizeof(*hdr) + sig_len, GFP_KERNEL); hdr = kzalloc(struct_size(hdr, raw_pkcs7, sig_len), GFP_KERNEL);
if (!hdr) if (!hdr)
return -ENOMEM; return -ENOMEM;
hdr->raw_pkcs7_len = sig_len;
hdr->pkcs7_msg = pkcs7_parse_message(buf + buf_len, sig_len); hdr->pkcs7_msg = pkcs7_parse_message(buf + buf_len, sig_len);
if (IS_ERR(hdr->pkcs7_msg)) { if (IS_ERR(hdr->pkcs7_msg)) {
rc = PTR_ERR(hdr->pkcs7_msg); 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,
} }
memcpy(hdr->raw_pkcs7, buf + buf_len, sig_len); memcpy(hdr->raw_pkcs7, buf + buf_len, sig_len);
hdr->raw_pkcs7_len = sig_len;
/* We don't know the hash algorithm yet. */ /* We don't know the hash algorithm yet. */
hdr->hash_algo = HASH_ALGO__LAST; hdr->hash_algo = HASH_ALGO__LAST;

View File

@ -9,7 +9,6 @@ CONFIG_INIT_ON_FREE_DEFAULT_ON=y
CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y CONFIG_INIT_ON_ALLOC_DEFAULT_ON=y
CONFIG_UBSAN=y CONFIG_UBSAN=y
CONFIG_UBSAN_BOUNDS=y CONFIG_UBSAN_BOUNDS=y
CONFIG_UBSAN_TRAP=y
CONFIG_STACKPROTECTOR_STRONG=y CONFIG_STACKPROTECTOR_STRONG=y
CONFIG_SLUB_DEBUG=y CONFIG_SLUB_DEBUG=y
CONFIG_SLUB_DEBUG_ON=y CONFIG_SLUB_DEBUG_ON=y

View File

@ -1,4 +1,5 @@
#PANIC #PANIC
#PANIC_STOP_IRQOFF Crashes entire system
BUG kernel BUG at BUG kernel BUG at
WARNING WARNING: WARNING WARNING:
WARNING_MESSAGE message trigger WARNING_MESSAGE message trigger
@ -7,7 +8,7 @@ EXCEPTION
#EXHAUST_STACK Corrupts memory on failure #EXHAUST_STACK Corrupts memory on failure
#CORRUPT_STACK Crashes entire system on success #CORRUPT_STACK Crashes entire system on success
#CORRUPT_STACK_STRONG Crashes entire system on success #CORRUPT_STACK_STRONG Crashes entire system on success
ARRAY_BOUNDS ARRAY_BOUNDS call trace:|UBSAN: array-index-out-of-bounds
CORRUPT_LIST_ADD list_add corruption CORRUPT_LIST_ADD list_add corruption
CORRUPT_LIST_DEL list_del corruption CORRUPT_LIST_DEL list_del corruption
STACK_GUARD_PAGE_LEADING STACK_GUARD_PAGE_LEADING