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
60 changed files with 280 additions and 90 deletions

View File

@@ -8649,6 +8649,8 @@ L: linux-hardening@vger.kernel.org
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux.git for-next/hardening
F: Documentation/kbuild/gcc-plugins.rst
F: include/linux/stackleak.h
F: kernel/stackleak.c
F: scripts/Makefile.gcc-plugins
F: scripts/gcc-plugins/
@@ -11415,16 +11417,20 @@ F: usr/
KERNEL HARDENING (not covered by other areas)
M: Kees Cook <keescook@chromium.org>
R: Gustavo A. R. Silva <gustavoars@kernel.org>
L: linux-hardening@vger.kernel.org
S: Supported
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-warn_count
F: arch/*/configs/hardening.config
F: include/linux/overflow.h
F: include/linux/randomize_kstack.h
F: kernel/configs/hardening.config
F: mm/usercopy.c
K: \b(add|choose)_random_kstack_offset\b
K: \b__check_(object_size|heap_object)\b
K: \b__counted_by\b
KERNEL JANITORS
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 */
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(version_buf, "%d", UML_NET_VERSION);
if (gate != NULL) {
strncpy(gate_buf, gate, 15);
strscpy(gate_buf, gate, sizeof(gate_buf));
args = setup_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 engine_idx;
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);

View File

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

View File

@@ -555,7 +555,7 @@ struct fifo_buffer {
unsigned int head_index;
unsigned int size;
int total; /* sum of all values */
int values[];
int values[] __counted_by(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_minor = le16_to_cpu(rsp_params->version_minor);
obj_desc->flags = le16_to_cpu(rsp_params->flags);
strncpy(obj_desc->type, rsp_params->type, 16);
obj_desc->type[15] = '\0';
strncpy(obj_desc->label, rsp_params->label, 16);
obj_desc->label[15] = '\0';
strscpy_pad(obj_desc->type, rsp_params->type, 16);
strscpy_pad(obj_desc->label, rsp_params->label, 16);
return 0;
}
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_num = cpu_to_le32(irq_cfg->irq_num);
cmd_params->obj_id = cpu_to_le32(obj_id);
strncpy(cmd_params->obj_type, obj_type, 16);
cmd_params->obj_type[15] = '\0';
strscpy_pad(cmd_params->obj_type, obj_type, 16);
/* send command to mc*/
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->obj_id = cpu_to_le32(obj_id);
cmd_params->region_index = region_index;
strncpy(cmd_params->obj_type, obj_type, 16);
cmd_params->obj_type[15] = '\0';
strscpy_pad(cmd_params->obj_type, obj_type, 16);
/* send command to mc*/
err = mc_send_command(mc_io, &cmd);

View File

@@ -106,7 +106,7 @@ struct port_buffer {
unsigned int sgpages;
/* 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())
strncpy(policy->last_governor, policy->governor->name,
strscpy(policy->last_governor, policy->governor->name,
CPUFREQ_NAME_LEN);
else
policy->last_policy = policy->policy;
@@ -2996,7 +2996,7 @@ static int __init cpufreq_core_init(void)
BUG_ON(!cpufreq_global_kobject);
if (!strlen(default_governor))
strncpy(default_governor, gov->name, CPUFREQ_NAME_LEN);
strscpy(default_governor, gov->name, CPUFREQ_NAME_LEN);
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
* and desc become string pointers
*/
strncpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN - 1);
strncpy(idle_state->desc, desc, CPUIDLE_DESC_LEN - 1);
strscpy(idle_state->name, state_node->name, CPUIDLE_NAME_LEN);
strscpy(idle_state->desc, desc, CPUIDLE_DESC_LEN);
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))
return -EINVAL;
strncpy(rank->dimm->label, data, copy_count);
memcpy(rank->dimm->label, data, copy_count);
rank->dimm->label[copy_count] = '\0';
return count;
@@ -535,7 +535,7 @@ static ssize_t dimmdev_label_store(struct device *dev,
if (copy_count == 0 || copy_count >= sizeof(dimm->label))
return -EINVAL;
strncpy(dimm->label, data, copy_count);
memcpy(dimm->label, data, copy_count);
dimm->label[copy_count] = '\0';
return count;

View File

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

View File

@@ -503,7 +503,7 @@ int gud_pipe_check(struct drm_simple_display_pipe *pipe,
return -ENOENT;
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);
if (!req)
return -ENOMEM;

View File

@@ -67,7 +67,7 @@ struct nouveau_svm {
struct nouveau_svmm *svmm;
} **fault;
int fault_nr;
} buffer[1];
} buffer[];
};
#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)
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;
drm->svm->drm = drm;

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More