diff options
-rw-r--r-- | drivers/fpga/dfl-afu-dma-region.c | 2 | ||||
-rw-r--r-- | drivers/fpga/dfl.c | 22 | ||||
-rw-r--r-- | drivers/fpga/stratix10-soc.c | 6 | ||||
-rw-r--r-- | drivers/fpga/zynqmp-fpga.c | 4 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_dev.c | 2 | ||||
-rw-r--r-- | drivers/misc/genwqe/card_utils.c | 4 | ||||
-rw-r--r-- | drivers/misc/lkdtm/bugs.c | 23 | ||||
-rw-r--r-- | drivers/misc/lkdtm/core.c | 6 | ||||
-rw-r--r-- | drivers/misc/lkdtm/lkdtm.h | 2 | ||||
-rw-r--r-- | drivers/misc/lkdtm/usercopy.c | 10 | ||||
-rw-r--r-- | drivers/parport/share.c | 2 | ||||
-rw-r--r-- | drivers/w1/slaves/w1_ds2408.c | 2 | ||||
-rw-r--r-- | init/Kconfig | 17 | ||||
-rw-r--r-- | kernel/Makefile | 4 | ||||
-rwxr-xr-x | kernel/gen_kheaders.sh (renamed from kernel/gen_ikh_data.sh) | 17 | ||||
-rw-r--r-- | kernel/kheaders.c | 40 | ||||
-rw-r--r-- | lib/test_firmware.c | 14 |
17 files changed, 107 insertions, 70 deletions
diff --git a/drivers/fpga/dfl-afu-dma-region.c b/drivers/fpga/dfl-afu-dma-region.c index c438722bf4e1..dcd80b088c7b 100644 --- a/drivers/fpga/dfl-afu-dma-region.c +++ b/drivers/fpga/dfl-afu-dma-region.c @@ -399,7 +399,7 @@ int afu_dma_map_region(struct dfl_feature_platform_data *pdata, region->pages[0], 0, region->length, DMA_BIDIRECTIONAL); - if (dma_mapping_error(&pdata->dev->dev, region->iova)) { + if (dma_mapping_error(dfl_fpga_pdata_to_parent(pdata), region->iova)) { dev_err(&pdata->dev->dev, "failed to map for dma\n"); ret = -EFAULT; goto unpin_pages; diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index 2c09e502e721..4b66aaa32b5a 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -40,6 +40,13 @@ enum dfl_fpga_devt_type { DFL_FPGA_DEVT_MAX, }; +static struct lock_class_key dfl_pdata_keys[DFL_ID_MAX]; + +static const char *dfl_pdata_key_strings[DFL_ID_MAX] = { + "dfl-fme-pdata", + "dfl-port-pdata", +}; + /** * dfl_dev_info - dfl feature device information. * @name: name string of the feature platform device. @@ -315,7 +322,7 @@ static void dfl_chardev_uinit(void) for (i = 0; i < DFL_FPGA_DEVT_MAX; i++) if (MAJOR(dfl_chrdevs[i].devt)) { unregister_chrdev_region(dfl_chrdevs[i].devt, - MINORMASK); + MINORMASK + 1); dfl_chrdevs[i].devt = MKDEV(0, 0); } } @@ -325,8 +332,8 @@ static int dfl_chardev_init(void) int i, ret; for (i = 0; i < DFL_FPGA_DEVT_MAX; i++) { - ret = alloc_chrdev_region(&dfl_chrdevs[i].devt, 0, MINORMASK, - dfl_chrdevs[i].name); + ret = alloc_chrdev_region(&dfl_chrdevs[i].devt, 0, + MINORMASK + 1, dfl_chrdevs[i].name); if (ret) goto exit; } @@ -443,11 +450,16 @@ static int build_info_commit_dev(struct build_feature_devs_info *binfo) struct platform_device *fdev = binfo->feature_dev; struct dfl_feature_platform_data *pdata; struct dfl_feature_info *finfo, *p; + enum dfl_id_type type; int ret, index = 0; if (!fdev) return 0; + type = feature_dev_id_type(fdev); + if (WARN_ON_ONCE(type >= DFL_ID_MAX)) + return -EINVAL; + /* * we do not need to care for the memory which is associated with * the platform device. After calling platform_device_unregister(), @@ -463,6 +475,8 @@ static int build_info_commit_dev(struct build_feature_devs_info *binfo) pdata->num = binfo->feature_num; pdata->dfl_cdev = binfo->cdev; mutex_init(&pdata->lock); + lockdep_set_class_and_name(&pdata->lock, &dfl_pdata_keys[type], + dfl_pdata_key_strings[type]); /* * the count should be initialized to 0 to make sure @@ -497,7 +511,7 @@ static int build_info_commit_dev(struct build_feature_devs_info *binfo) ret = platform_device_add(binfo->feature_dev); if (!ret) { - if (feature_dev_id_type(binfo->feature_dev) == PORT_ID) + if (type == PORT_ID) dfl_fpga_cdev_add_port_dev(binfo->cdev, binfo->feature_dev); else diff --git a/drivers/fpga/stratix10-soc.c b/drivers/fpga/stratix10-soc.c index 13851b3d1c56..215d33789c74 100644 --- a/drivers/fpga/stratix10-soc.c +++ b/drivers/fpga/stratix10-soc.c @@ -507,12 +507,16 @@ static int __init s10_init(void) if (!fw_np) return -ENODEV; + of_node_get(fw_np); np = of_find_matching_node(fw_np, s10_of_match); - if (!np) + if (!np) { + of_node_put(fw_np); return -ENODEV; + } of_node_put(np); ret = of_platform_populate(fw_np, s10_of_match, NULL, NULL); + of_node_put(fw_np); if (ret) return ret; diff --git a/drivers/fpga/zynqmp-fpga.c b/drivers/fpga/zynqmp-fpga.c index f7cbaadf49ab..b8a88d21d038 100644 --- a/drivers/fpga/zynqmp-fpga.c +++ b/drivers/fpga/zynqmp-fpga.c @@ -47,7 +47,7 @@ static int zynqmp_fpga_ops_write(struct fpga_manager *mgr, char *kbuf; int ret; - if (!eemi_ops || !eemi_ops->fpga_load) + if (IS_ERR_OR_NULL(eemi_ops) || !eemi_ops->fpga_load) return -ENXIO; priv = mgr->priv; @@ -81,7 +81,7 @@ static enum fpga_mgr_states zynqmp_fpga_ops_state(struct fpga_manager *mgr) const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops(); u32 status; - if (!eemi_ops || !eemi_ops->fpga_get_status) + if (IS_ERR_OR_NULL(eemi_ops) || !eemi_ops->fpga_get_status) return FPGA_MGR_STATE_UNKNOWN; eemi_ops->fpga_get_status(&status); diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c index 8c1b63a4337b..d2098b4d2945 100644 --- a/drivers/misc/genwqe/card_dev.c +++ b/drivers/misc/genwqe/card_dev.c @@ -780,6 +780,8 @@ static int genwqe_pin_mem(struct genwqe_file *cfile, struct genwqe_mem *m) if ((m->addr == 0x0) || (m->size == 0)) return -EINVAL; + if (m->size > ULONG_MAX - PAGE_SIZE - (m->addr & ~PAGE_MASK)) + return -EINVAL; map_addr = (m->addr & PAGE_MASK); map_size = round_up(m->size + (m->addr & ~PAGE_MASK), PAGE_SIZE); diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c index 89cff9d1012b..7571700abc6e 100644 --- a/drivers/misc/genwqe/card_utils.c +++ b/drivers/misc/genwqe/card_utils.c @@ -586,6 +586,10 @@ int genwqe_user_vmap(struct genwqe_dev *cd, struct dma_mapping *m, void *uaddr, /* determine space needed for page_list. */ data = (unsigned long)uaddr; offs = offset_in_page(data); + if (size > ULONG_MAX - PAGE_SIZE - offs) { + m->size = 0; /* mark unused and not added */ + return -EINVAL; + } m->nr_pages = DIV_ROUND_UP(offs + size, PAGE_SIZE); m->page_list = kcalloc(m->nr_pages, diff --git a/drivers/misc/lkdtm/bugs.c b/drivers/misc/lkdtm/bugs.c index 7eebbdfbcacd..17f839dee976 100644 --- a/drivers/misc/lkdtm/bugs.c +++ b/drivers/misc/lkdtm/bugs.c @@ -32,12 +32,20 @@ static int recur_count = REC_NUM_DEFAULT; static DEFINE_SPINLOCK(lock_me_up); -static int recursive_loop(int remaining) +/* + * Make sure compiler does not optimize this function or stack frame away: + * - function marked noinline + * - stack variables are marked volatile + * - stack variables are written (memset()) and read (pr_info()) + * - function has external effects (pr_info()) + * */ +static int noinline recursive_loop(int remaining) { - char buf[REC_STACK_SIZE]; + volatile char buf[REC_STACK_SIZE]; - /* Make sure compiler does not optimize this away. */ - memset(buf, (remaining & 0xff) | 0x1, REC_STACK_SIZE); + memset((void *)buf, remaining & 0xFF, sizeof(buf)); + pr_info("loop %d/%d ...\n", (int)buf[remaining % sizeof(buf)], + recur_count); if (!remaining) return 0; else @@ -81,9 +89,12 @@ void lkdtm_LOOP(void) ; } -void lkdtm_OVERFLOW(void) +void lkdtm_EXHAUST_STACK(void) { - (void) recursive_loop(recur_count); + pr_info("Calling function with %d frame size to depth %d ...\n", + REC_STACK_SIZE, recur_count); + recursive_loop(recur_count); + pr_info("FAIL: survived without exhausting stack?!\n"); } static noinline void __lkdtm_CORRUPT_STACK(void *stack) diff --git a/drivers/misc/lkdtm/core.c b/drivers/misc/lkdtm/core.c index b51cf182b031..4f3a6e1cd331 100644 --- a/drivers/misc/lkdtm/core.c +++ b/drivers/misc/lkdtm/core.c @@ -119,12 +119,12 @@ static const struct crashtype crashtypes[] = { CRASHTYPE(WARNING), CRASHTYPE(EXCEPTION), CRASHTYPE(LOOP), - CRASHTYPE(OVERFLOW), + CRASHTYPE(EXHAUST_STACK), + CRASHTYPE(CORRUPT_STACK), + CRASHTYPE(CORRUPT_STACK_STRONG), CRASHTYPE(CORRUPT_LIST_ADD), CRASHTYPE(CORRUPT_LIST_DEL), CRASHTYPE(CORRUPT_USER_DS), - CRASHTYPE(CORRUPT_STACK), - CRASHTYPE(CORRUPT_STACK_STRONG), CRASHTYPE(STACK_GUARD_PAGE_LEADING), CRASHTYPE(STACK_GUARD_PAGE_TRAILING), CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE), diff --git a/drivers/misc/lkdtm/lkdtm.h b/drivers/misc/lkdtm/lkdtm.h index b69ee004a3f7..23dc565b4307 100644 --- a/drivers/misc/lkdtm/lkdtm.h +++ b/drivers/misc/lkdtm/lkdtm.h @@ -13,7 +13,7 @@ void lkdtm_BUG(void); void lkdtm_WARNING(void); void lkdtm_EXCEPTION(void); void lkdtm_LOOP(void); -void lkdtm_OVERFLOW(void); +void lkdtm_EXHAUST_STACK(void); void lkdtm_CORRUPT_STACK(void); void lkdtm_CORRUPT_STACK_STRONG(void); void lkdtm_UNALIGNED_LOAD_STORE_WRITE(void); diff --git a/drivers/misc/lkdtm/usercopy.c b/drivers/misc/lkdtm/usercopy.c index d5a0e7f1813b..e172719dd86d 100644 --- a/drivers/misc/lkdtm/usercopy.c +++ b/drivers/misc/lkdtm/usercopy.c @@ -324,14 +324,16 @@ free_user: void lkdtm_USERCOPY_KERNEL_DS(void) { - char __user *user_ptr = (char __user *)ERR_PTR(-EINVAL); + char __user *user_ptr = + (char __user *)(0xFUL << (sizeof(unsigned long) * 8 - 4)); mm_segment_t old_fs = get_fs(); char buf[10] = {0}; - pr_info("attempting copy_to_user on unmapped kernel address\n"); + pr_info("attempting copy_to_user() to noncanonical address: %px\n", + user_ptr); set_fs(KERNEL_DS); - if (copy_to_user(user_ptr, buf, sizeof(buf))) - pr_info("copy_to_user un unmapped kernel address failed\n"); + if (copy_to_user(user_ptr, buf, sizeof(buf)) == 0) + pr_err("copy_to_user() to noncanonical address succeeded!?\n"); set_fs(old_fs); } diff --git a/drivers/parport/share.c b/drivers/parport/share.c index 5dc53d420ca8..7b4ee33c1935 100644 --- a/drivers/parport/share.c +++ b/drivers/parport/share.c @@ -895,6 +895,7 @@ parport_register_dev_model(struct parport *port, const char *name, par_dev->devmodel = true; ret = device_register(&par_dev->dev); if (ret) { + kfree(par_dev->state); put_device(&par_dev->dev); goto err_put_port; } @@ -912,6 +913,7 @@ parport_register_dev_model(struct parport *port, const char *name, spin_unlock(&port->physport->pardevice_lock); pr_debug("%s: cannot grant exclusive access for device %s\n", port->name, name); + kfree(par_dev->state); device_unregister(&par_dev->dev); goto err_put_port; } diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c index 92e8f0755b9a..edf0bc98012c 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c @@ -138,7 +138,7 @@ static ssize_t status_control_read(struct file *filp, struct kobject *kobj, W1_F29_REG_CONTROL_AND_STATUS, buf); } -#ifdef fCONFIG_W1_SLAVE_DS2408_READBACK +#ifdef CONFIG_W1_SLAVE_DS2408_READBACK static bool optional_read_back_valid(struct w1_slave *sl, u8 expected) { u8 w1_buf[3]; diff --git a/init/Kconfig b/init/Kconfig index 8b9ffe236e4f..16a7540d60c8 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -579,15 +579,14 @@ config IKCONFIG_PROC This option enables access to the kernel configuration file through /proc/config.gz. -config IKHEADERS_PROC - tristate "Enable kernel header artifacts through /proc/kheaders.tar.xz" - depends on PROC_FS - help - This option enables access to the kernel header and other artifacts that - are generated during the build process. These can be used to build eBPF - tracing programs, or similar programs. If you build the headers as a - module, a module called kheaders.ko is built which can be loaded on-demand - to get access to the headers. +config IKHEADERS + tristate "Enable kernel headers through /sys/kernel/kheaders.tar.xz" + depends on SYSFS + help + This option enables access to the in-kernel headers that are generated during + the build process. These can be used to build eBPF tracing programs, + or similar programs. If you build the headers as a module, a module called + kheaders.ko is built which can be loaded on-demand to get access to headers. config LOG_BUF_SHIFT int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" diff --git a/kernel/Makefile b/kernel/Makefile index 33824f0385b3..a8d923b5481b 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -71,7 +71,7 @@ obj-$(CONFIG_UTS_NS) += utsname.o obj-$(CONFIG_USER_NS) += user_namespace.o obj-$(CONFIG_PID_NS) += pid_namespace.o obj-$(CONFIG_IKCONFIG) += configs.o -obj-$(CONFIG_IKHEADERS_PROC) += kheaders.o +obj-$(CONFIG_IKHEADERS) += kheaders.o obj-$(CONFIG_SMP) += stop_machine.o obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o obj-$(CONFIG_AUDIT) += audit.o auditfilter.o @@ -127,7 +127,7 @@ $(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE $(obj)/kheaders.o: $(obj)/kheaders_data.tar.xz quiet_cmd_genikh = CHK $(obj)/kheaders_data.tar.xz -cmd_genikh = $(CONFIG_SHELL) $(srctree)/kernel/gen_ikh_data.sh $@ +cmd_genikh = $(CONFIG_SHELL) $(srctree)/kernel/gen_kheaders.sh $@ $(obj)/kheaders_data.tar.xz: FORCE $(call cmd,genikh) diff --git a/kernel/gen_ikh_data.sh b/kernel/gen_kheaders.sh index 591a94f7b387..9a34e1d9bd7f 100755 --- a/kernel/gen_ikh_data.sh +++ b/kernel/gen_kheaders.sh @@ -2,7 +2,7 @@ # SPDX-License-Identifier: GPL-2.0 # This script generates an archive consisting of kernel headers -# for CONFIG_IKHEADERS_PROC. +# for CONFIG_IKHEADERS. set -e spath="$(dirname "$(readlink -f "$0")")" kroot="$spath/.." @@ -31,9 +31,8 @@ arch/$SRCARCH/include/ # This block is useful for debugging the incremental builds. # Uncomment it for debugging. -# iter=1 -# if [ ! -f /tmp/iter ]; then echo 1 > /tmp/iter; -# else; iter=$(($(cat /tmp/iter) + 1)); fi +# if [ ! -f /tmp/iter ]; then iter=1; echo 1 > /tmp/iter; +# else iter=$(($(cat /tmp/iter) + 1)); echo $iter > /tmp/iter; fi # find $src_file_list -type f | xargs ls -lR > /tmp/src-ls-$iter # find $obj_file_list -type f | xargs ls -lR > /tmp/obj-ls-$iter @@ -43,10 +42,18 @@ arch/$SRCARCH/include/ pushd $kroot > /dev/null src_files_md5="$(find $src_file_list -type f | grep -v "include/generated/compile.h" | + grep -v "include/generated/autoconf.h" | + grep -v "include/config/auto.conf" | + grep -v "include/config/auto.conf.cmd" | + grep -v "include/config/tristate.conf" | xargs ls -lR | md5sum | cut -d ' ' -f1)" popd > /dev/null obj_files_md5="$(find $obj_file_list -type f | grep -v "include/generated/compile.h" | + grep -v "include/generated/autoconf.h" | + grep -v "include/config/auto.conf" | + grep -v "include/config/auto.conf.cmd" | + grep -v "include/config/tristate.conf" | xargs ls -lR | md5sum | cut -d ' ' -f1)" if [ -f $tarfile ]; then tarfile_md5="$(md5sum $tarfile | cut -d ' ' -f1)"; fi @@ -82,7 +89,7 @@ find $cpio_dir -type f -print0 | tar -Jcf $tarfile -C $cpio_dir/ . > /dev/null -echo "$src_files_md5" > kernel/kheaders.md5 +echo "$src_files_md5" > kernel/kheaders.md5 echo "$obj_files_md5" >> kernel/kheaders.md5 echo "$(md5sum $tarfile | cut -d ' ' -f1)" >> kernel/kheaders.md5 diff --git a/kernel/kheaders.c b/kernel/kheaders.c index 70ae6052920d..8f69772af77b 100644 --- a/kernel/kheaders.c +++ b/kernel/kheaders.c @@ -8,9 +8,8 @@ #include <linux/kernel.h> #include <linux/module.h> -#include <linux/proc_fs.h> +#include <linux/kobject.h> #include <linux/init.h> -#include <linux/uaccess.h> /* * Define kernel_headers_data and kernel_headers_data_end, within which the @@ -31,39 +30,32 @@ extern char kernel_headers_data; extern char kernel_headers_data_end; static ssize_t -ikheaders_read_current(struct file *file, char __user *buf, - size_t len, loff_t *offset) +ikheaders_read(struct file *file, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t len) { - return simple_read_from_buffer(buf, len, offset, - &kernel_headers_data, - &kernel_headers_data_end - - &kernel_headers_data); + memcpy(buf, &kernel_headers_data + off, len); + return len; } -static const struct file_operations ikheaders_file_ops = { - .read = ikheaders_read_current, - .llseek = default_llseek, +static struct bin_attribute kheaders_attr __ro_after_init = { + .attr = { + .name = "kheaders.tar.xz", + .mode = 0444, + }, + .read = &ikheaders_read, }; static int __init ikheaders_init(void) { - struct proc_dir_entry *entry; - - /* create the current headers file */ - entry = proc_create("kheaders.tar.xz", S_IRUGO, NULL, - &ikheaders_file_ops); - if (!entry) - return -ENOMEM; - - proc_set_size(entry, - &kernel_headers_data_end - - &kernel_headers_data); - return 0; + kheaders_attr.size = (&kernel_headers_data_end - + &kernel_headers_data); + return sysfs_create_bin_file(kernel_kobj, &kheaders_attr); } static void __exit ikheaders_cleanup(void) { - remove_proc_entry("kheaders.tar.xz", NULL); + sysfs_remove_bin_file(kernel_kobj, &kheaders_attr); } module_init(ikheaders_init); diff --git a/lib/test_firmware.c b/lib/test_firmware.c index 7222093ee00b..b5487ed829d7 100644 --- a/lib/test_firmware.c +++ b/lib/test_firmware.c @@ -223,30 +223,30 @@ static ssize_t config_show(struct device *dev, mutex_lock(&test_fw_mutex); - len += snprintf(buf, PAGE_SIZE, + len += scnprintf(buf, PAGE_SIZE - len, "Custom trigger configuration for: %s\n", dev_name(dev)); if (test_fw_config->name) - len += snprintf(buf+len, PAGE_SIZE, + len += scnprintf(buf+len, PAGE_SIZE - len, "name:\t%s\n", test_fw_config->name); else - len += snprintf(buf+len, PAGE_SIZE, + len += scnprintf(buf+len, PAGE_SIZE - len, "name:\tEMTPY\n"); - len += snprintf(buf+len, PAGE_SIZE, + len += scnprintf(buf+len, PAGE_SIZE - len, "num_requests:\t%u\n", test_fw_config->num_requests); - len += snprintf(buf+len, PAGE_SIZE, + len += scnprintf(buf+len, PAGE_SIZE - len, "send_uevent:\t\t%s\n", test_fw_config->send_uevent ? "FW_ACTION_HOTPLUG" : "FW_ACTION_NOHOTPLUG"); - len += snprintf(buf+len, PAGE_SIZE, + len += scnprintf(buf+len, PAGE_SIZE - len, "sync_direct:\t\t%s\n", test_fw_config->sync_direct ? "true" : "false"); - len += snprintf(buf+len, PAGE_SIZE, + len += scnprintf(buf+len, PAGE_SIZE - len, "read_fw_idx:\t%u\n", test_fw_config->read_fw_idx); mutex_unlock(&test_fw_mutex); |