From: Sasha Levin Date: Sun, 4 Dec 2022 02:26:51 +0000 (-0500) Subject: Fixes for 4.19 X-Git-Tag: v4.9.335~54 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8d22a16d492f10e18a79e682fdcc2764a3bc9a91;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.19 Signed-off-by: Sasha Levin --- diff --git a/queue-4.19/asoc-ops-fix-bounds-check-for-_sx-controls.patch b/queue-4.19/asoc-ops-fix-bounds-check-for-_sx-controls.patch new file mode 100644 index 00000000000..849d5b39b2d --- /dev/null +++ b/queue-4.19/asoc-ops-fix-bounds-check-for-_sx-controls.patch @@ -0,0 +1,39 @@ +From 1c50c284144bd0c01233ea51577bea2adca928a9 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 May 2022 14:41:36 +0100 +Subject: ASoC: ops: Fix bounds check for _sx controls + +From: Mark Brown + +[ Upstream commit 698813ba8c580efb356ace8dbf55f61dac6063a8 ] + +For _sx controls the semantics of the max field is not the usual one, max +is the number of steps rather than the maximum value. This means that our +check in snd_soc_put_volsw_sx() needs to just check against the maximum +value. + +Fixes: 4f1e50d6a9cf9c1b ("ASoC: ops: Reject out of bounds values in snd_soc_put_volsw_sx()") +Signed-off-by: Mark Brown +Link: https://lore.kernel.org/r/20220511134137.169575-1-broonie@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/soc-ops.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c +index 453b61b42dd9..2faf95d4bb75 100644 +--- a/sound/soc/soc-ops.c ++++ b/sound/soc/soc-ops.c +@@ -445,7 +445,7 @@ int snd_soc_put_volsw_sx(struct snd_kcontrol *kcontrol, + val = ucontrol->value.integer.value[0]; + if (mc->platform_max && val > mc->platform_max) + return -EINVAL; +- if (val > max - min) ++ if (val > max) + return -EINVAL; + if (val < 0) + return -EINVAL; +-- +2.35.1 + diff --git a/queue-4.19/iommu-vt-d-fix-pci-device-refcount-leak-in-dmar_dev_.patch b/queue-4.19/iommu-vt-d-fix-pci-device-refcount-leak-in-dmar_dev_.patch new file mode 100644 index 00000000000..374e5f6b97d --- /dev/null +++ b/queue-4.19/iommu-vt-d-fix-pci-device-refcount-leak-in-dmar_dev_.patch @@ -0,0 +1,43 @@ +From 7de72d78d0e7a31d9c8adbd88e5b79061e3e00b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 1 Dec 2022 12:01:27 +0800 +Subject: iommu/vt-d: Fix PCI device refcount leak in dmar_dev_scope_init() + +From: Xiongfeng Wang + +[ Upstream commit 4bedbbd782ebbe7287231fea862c158d4f08a9e3 ] + +for_each_pci_dev() is implemented by pci_get_device(). The comment of +pci_get_device() says that it will increase the reference count for the +returned pci_dev and also decrease the reference count for the input +pci_dev @from if it is not NULL. + +If we break for_each_pci_dev() loop with pdev not NULL, we need to call +pci_dev_put() to decrease the reference count. Add the missing +pci_dev_put() for the error path to avoid reference count leak. + +Fixes: 2e4552893038 ("iommu/vt-d: Unify the way to process DMAR device scope array") +Signed-off-by: Xiongfeng Wang +Link: https://lore.kernel.org/r/20221121113649.190393-3-wangxiongfeng2@huawei.com +Signed-off-by: Lu Baolu +Signed-off-by: Joerg Roedel +Signed-off-by: Sasha Levin +--- + drivers/iommu/dmar.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c +index 017786d62f47..3ea851583724 100644 +--- a/drivers/iommu/dmar.c ++++ b/drivers/iommu/dmar.c +@@ -804,6 +804,7 @@ int __init dmar_dev_scope_init(void) + info = dmar_alloc_pci_notify_info(dev, + BUS_NOTIFY_ADD_DEVICE); + if (!info) { ++ pci_dev_put(dev); + return dmar_dev_scope_status; + } else { + dmar_pci_bus_add_dev(info); +-- +2.35.1 + diff --git a/queue-4.19/kconfig.debug-provide-a-little-extra-frame_warn-leew.patch b/queue-4.19/kconfig.debug-provide-a-little-extra-frame_warn-leew.patch new file mode 100644 index 00000000000..992e752f7cc --- /dev/null +++ b/queue-4.19/kconfig.debug-provide-a-little-extra-frame_warn-leew.patch @@ -0,0 +1,56 @@ +From 6be658b187b921db51cbf0f738f04b04271ff65e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 25 Nov 2022 12:07:50 +0000 +Subject: Kconfig.debug: provide a little extra FRAME_WARN leeway when KASAN is + enabled +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Lee Jones + +[ Upstream commit 152fe65f300e1819d59b80477d3e0999b4d5d7d2 ] + +When enabled, KASAN enlarges function's stack-frames. Pushing quite a few +over the current threshold. This can mainly be seen on 32-bit +architectures where the present limit (when !GCC) is a lowly 1024-Bytes. + +Link: https://lkml.kernel.org/r/20221125120750.3537134-3-lee@kernel.org +Signed-off-by: Lee Jones +Acked-by: Arnd Bergmann +Cc: Alex Deucher +Cc: "Christian König" +Cc: Daniel Vetter +Cc: David Airlie +Cc: Harry Wentland +Cc: Leo Li +Cc: Maarten Lankhorst +Cc: Maxime Ripard +Cc: Nathan Chancellor +Cc: Nick Desaulniers +Cc: "Pan, Xinhui" +Cc: Rodrigo Siqueira +Cc: Thomas Zimmermann +Cc: Tom Rix +Cc: +Signed-off-by: Andrew Morton +Signed-off-by: Sasha Levin +--- + lib/Kconfig.debug | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index 67c98f664a61..d03fe7780184 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -226,6 +226,7 @@ config FRAME_WARN + default 2048 if GCC_PLUGIN_LATENT_ENTROPY + default 2048 if PARISC + default 1536 if (!64BIT && XTENSA) ++ default 1280 if KASAN && !64BIT + default 1024 if !64BIT + default 2048 if 64BIT + help +-- +2.35.1 + diff --git a/queue-4.19/parisc-increase-frame_warn-to-2048-bytes-on-parisc.patch b/queue-4.19/parisc-increase-frame_warn-to-2048-bytes-on-parisc.patch new file mode 100644 index 00000000000..8f0d76438bc --- /dev/null +++ b/queue-4.19/parisc-increase-frame_warn-to-2048-bytes-on-parisc.patch @@ -0,0 +1,40 @@ +From a2a95dca8c14cf1a91d47fee7fb7c0cf80c590d1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 19 Nov 2021 22:31:03 +0100 +Subject: parisc: Increase FRAME_WARN to 2048 bytes on parisc + +From: Helge Deller + +[ Upstream commit 8d192bec534bd5b778135769a12e5f04580771f7 ] + +PA-RISC uses a much bigger frame size for functions than other +architectures. So increase it to 2048 for 32- and 64-bit kernels. +This fixes e.g. a warning in lib/xxhash.c. + +Reported-by: kernel test robot +Signed-off-by: Helge Deller +Stable-dep-of: 152fe65f300e ("Kconfig.debug: provide a little extra FRAME_WARN leeway when KASAN is enabled") +Signed-off-by: Sasha Levin +--- + lib/Kconfig.debug | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index 12fc801811d3..67c98f664a61 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -224,8 +224,9 @@ config FRAME_WARN + range 0 8192 + default 3072 if KASAN_EXTRA + default 2048 if GCC_PLUGIN_LATENT_ENTROPY +- default 1536 if (!64BIT && (PARISC || XTENSA)) +- default 1024 if (!64BIT && !PARISC) ++ default 2048 if PARISC ++ default 1536 if (!64BIT && XTENSA) ++ default 1024 if !64BIT + default 2048 if 64BIT + help + Tell gcc to warn at build time for stack frames larger than this. +-- +2.35.1 + diff --git a/queue-4.19/parisc-increase-size-of-gcc-stack-frame-check.patch b/queue-4.19/parisc-increase-size-of-gcc-stack-frame-check.patch new file mode 100644 index 00000000000..70b343fe9ad --- /dev/null +++ b/queue-4.19/parisc-increase-size-of-gcc-stack-frame-check.patch @@ -0,0 +1,38 @@ +From 598105401d0ccf2d3644a4f6011e3798322a6448 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 7 Jul 2021 15:38:08 +0200 +Subject: parisc: Increase size of gcc stack frame check + +From: Helge Deller + +[ Upstream commit 55b70eed81cba1331773d4aaf5cba2bb07475cd8 ] + +parisc uses much bigger frames than other architectures, so increase the +stack frame check value to avoid compiler warnings. + +Cc: Arnd Bergmann +Cc: Abd-Alrhman Masalkhi +Cc: Christoph Hellwig +Signed-off-by: Helge Deller +Stable-dep-of: 152fe65f300e ("Kconfig.debug: provide a little extra FRAME_WARN leeway when KASAN is enabled") +Signed-off-by: Sasha Levin +--- + lib/Kconfig.debug | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index 9ded3c1f68eb..556aae95d69b 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -224,7 +224,7 @@ config FRAME_WARN + range 0 8192 + default 3072 if KASAN_EXTRA + default 2048 if GCC_PLUGIN_LATENT_ENTROPY +- default 1280 if (!64BIT && PARISC) ++ default 1536 if (!64BIT && PARISC) + default 1024 if (!64BIT && !PARISC) + default 2048 if 64BIT + help +-- +2.35.1 + diff --git a/queue-4.19/pinctrl-single-fix-potential-division-by-zero.patch b/queue-4.19/pinctrl-single-fix-potential-division-by-zero.patch new file mode 100644 index 00000000000..0bc77fb09a9 --- /dev/null +++ b/queue-4.19/pinctrl-single-fix-potential-division-by-zero.patch @@ -0,0 +1,43 @@ +From ac465f2ba283b513ecb136290b117051a8141e43 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 17 Nov 2022 15:30:34 +0300 +Subject: pinctrl: single: Fix potential division by zero + +From: Maxim Korotkov + +[ Upstream commit 64c150339e7f6c5cbbe8c17a56ef2b3902612798 ] + +There is a possibility of dividing by zero due to the pcs->bits_per_pin +if pcs->fmask() also has a value of zero and called fls +from asm-generic/bitops/builtin-fls.h or arch/x86/include/asm/bitops.h. +The function pcs_probe() has the branch that assigned to fmask 0 before +pcs_allocate_pin_table() was called + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Fixes: 4e7e8017a80e ("pinctrl: pinctrl-single: enhance to configure multiple pins of different modules") +Signed-off-by: Maxim Korotkov +Reviewed-by: Tony Lindgren +Link: https://lore.kernel.org/r/20221117123034.27383-1-korotkov.maxim.s@gmail.com +Signed-off-by: Linus Walleij +Signed-off-by: Sasha Levin +--- + drivers/pinctrl/pinctrl-single.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index c2f807bf3489..2b50030ad97e 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -703,7 +703,7 @@ static int pcs_allocate_pin_table(struct pcs_device *pcs) + + mux_bytes = pcs->width / BITS_PER_BYTE; + +- if (pcs->bits_per_mux) { ++ if (pcs->bits_per_mux && pcs->fmask) { + pcs->bits_per_pin = fls(pcs->fmask); + nr_pins = (pcs->size * BITS_PER_BYTE) / pcs->bits_per_pin; + num_pins_in_register = pcs->width / pcs->bits_per_pin; +-- +2.35.1 + diff --git a/queue-4.19/series b/queue-4.19/series index eb83f60898f..4c3770b5145 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -96,3 +96,12 @@ pinctrl-intel-save-and-restore-pins-in-direct-irq-mode.patch arm64-fix-panic-when-spectre-v2-causes-spectre-bhb-to-re-allocate-kvm-vectors.patch arm64-errata-fix-kvm-spectre-v2-mitigation-selection-for-cortex-a57-a72.patch mm-fix-.data.once-orphan-section-warning.patch +asoc-ops-fix-bounds-check-for-_sx-controls.patch +pinctrl-single-fix-potential-division-by-zero.patch +iommu-vt-d-fix-pci-device-refcount-leak-in-dmar_dev_.patch +parisc-increase-size-of-gcc-stack-frame-check.patch +xtensa-increase-size-of-gcc-stack-frame-check.patch +parisc-increase-frame_warn-to-2048-bytes-on-parisc.patch +kconfig.debug-provide-a-little-extra-frame_warn-leew.patch +tracing-add-unified-dynamic-event-framework.patch +tracing-free-buffers-when-a-used-dynamic-event-is-re.patch diff --git a/queue-4.19/tracing-add-unified-dynamic-event-framework.patch b/queue-4.19/tracing-add-unified-dynamic-event-framework.patch new file mode 100644 index 00000000000..14e1272c455 --- /dev/null +++ b/queue-4.19/tracing-add-unified-dynamic-event-framework.patch @@ -0,0 +1,419 @@ +From 58954e6bb1b1066e34c6678826c6155aa17ec01f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Nov 2018 18:02:08 +0900 +Subject: tracing: Add unified dynamic event framework + +From: Masami Hiramatsu + +[ Upstream commit 5448d44c38557fc15d1c53b608a9c9f0e1ca8f86 ] + +Add unified dynamic event framework for ftrace kprobes, uprobes +and synthetic events. Those dynamic events can be co-exist on +same file because those syntax doesn't overlap. + +This introduces a framework part which provides a unified tracefs +interface and operations. + +Link: http://lkml.kernel.org/r/154140852824.17322.12250362185969352095.stgit@devbox + +Reviewed-by: Tom Zanussi +Tested-by: Tom Zanussi +Signed-off-by: Masami Hiramatsu +Signed-off-by: Steven Rostedt (VMware) +Stable-dep-of: 4313e5a61304 ("tracing: Free buffers when a used dynamic event is removed") +Signed-off-by: Sasha Levin +--- + kernel/trace/Kconfig | 3 + + kernel/trace/Makefile | 1 + + kernel/trace/trace.c | 4 + + kernel/trace/trace_dynevent.c | 210 ++++++++++++++++++++++++++++++++++ + kernel/trace/trace_dynevent.h | 119 +++++++++++++++++++ + 5 files changed, 337 insertions(+) + create mode 100644 kernel/trace/trace_dynevent.c + create mode 100644 kernel/trace/trace_dynevent.h + +diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig +index e656d1e232da..7d7edc56eb5e 100644 +--- a/kernel/trace/Kconfig ++++ b/kernel/trace/Kconfig +@@ -518,6 +518,9 @@ config BPF_EVENTS + help + This allows the user to attach BPF programs to kprobe events. + ++config DYNAMIC_EVENTS ++ def_bool n ++ + config PROBE_EVENTS + def_bool n + +diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile +index f81dadbc7c4a..9ff3c4fa91b6 100644 +--- a/kernel/trace/Makefile ++++ b/kernel/trace/Makefile +@@ -78,6 +78,7 @@ endif + ifeq ($(CONFIG_TRACING),y) + obj-$(CONFIG_KGDB_KDB) += trace_kdb.o + endif ++obj-$(CONFIG_DYNAMIC_EVENTS) += trace_dynevent.o + obj-$(CONFIG_PROBE_EVENTS) += trace_probe.o + obj-$(CONFIG_UPROBE_EVENTS) += trace_uprobe.o + +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index 5b7a6e9b0ab6..44a0bc16a859 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -4655,6 +4655,10 @@ static const char readme_msg[] = + "\t\t\t traces\n" + #endif + #endif /* CONFIG_STACK_TRACER */ ++#ifdef CONFIG_DYNAMIC_EVENTS ++ " dynamic_events\t\t- Add/remove/show the generic dynamic events\n" ++ "\t\t\t Write into this file to define/undefine new trace events.\n" ++#endif + #ifdef CONFIG_KPROBE_EVENTS + " kprobe_events\t\t- Add/remove/show the kernel dynamic events\n" + "\t\t\t Write into this file to define/undefine new trace events.\n" +diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c +new file mode 100644 +index 000000000000..f17a887abb66 +--- /dev/null ++++ b/kernel/trace/trace_dynevent.c +@@ -0,0 +1,210 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Generic dynamic event control interface ++ * ++ * Copyright (C) 2018 Masami Hiramatsu ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "trace.h" ++#include "trace_dynevent.h" ++ ++static DEFINE_MUTEX(dyn_event_ops_mutex); ++static LIST_HEAD(dyn_event_ops_list); ++ ++int dyn_event_register(struct dyn_event_operations *ops) ++{ ++ if (!ops || !ops->create || !ops->show || !ops->is_busy || ++ !ops->free || !ops->match) ++ return -EINVAL; ++ ++ INIT_LIST_HEAD(&ops->list); ++ mutex_lock(&dyn_event_ops_mutex); ++ list_add_tail(&ops->list, &dyn_event_ops_list); ++ mutex_unlock(&dyn_event_ops_mutex); ++ return 0; ++} ++ ++int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type) ++{ ++ struct dyn_event *pos, *n; ++ char *system = NULL, *event, *p; ++ int ret = -ENOENT; ++ ++ if (argv[0][1] != ':') ++ return -EINVAL; ++ ++ event = &argv[0][2]; ++ p = strchr(event, '/'); ++ if (p) { ++ system = event; ++ event = p + 1; ++ *p = '\0'; ++ } ++ if (event[0] == '\0') ++ return -EINVAL; ++ ++ mutex_lock(&event_mutex); ++ for_each_dyn_event_safe(pos, n) { ++ if (type && type != pos->ops) ++ continue; ++ if (pos->ops->match(system, event, pos)) { ++ ret = pos->ops->free(pos); ++ break; ++ } ++ } ++ mutex_unlock(&event_mutex); ++ ++ return ret; ++} ++ ++static int create_dyn_event(int argc, char **argv) ++{ ++ struct dyn_event_operations *ops; ++ int ret; ++ ++ if (argv[0][0] == '-') ++ return dyn_event_release(argc, argv, NULL); ++ ++ mutex_lock(&dyn_event_ops_mutex); ++ list_for_each_entry(ops, &dyn_event_ops_list, list) { ++ ret = ops->create(argc, (const char **)argv); ++ if (!ret || ret != -ECANCELED) ++ break; ++ } ++ mutex_unlock(&dyn_event_ops_mutex); ++ if (ret == -ECANCELED) ++ ret = -EINVAL; ++ ++ return ret; ++} ++ ++/* Protected by event_mutex */ ++LIST_HEAD(dyn_event_list); ++ ++void *dyn_event_seq_start(struct seq_file *m, loff_t *pos) ++{ ++ mutex_lock(&event_mutex); ++ return seq_list_start(&dyn_event_list, *pos); ++} ++ ++void *dyn_event_seq_next(struct seq_file *m, void *v, loff_t *pos) ++{ ++ return seq_list_next(v, &dyn_event_list, pos); ++} ++ ++void dyn_event_seq_stop(struct seq_file *m, void *v) ++{ ++ mutex_unlock(&event_mutex); ++} ++ ++static int dyn_event_seq_show(struct seq_file *m, void *v) ++{ ++ struct dyn_event *ev = v; ++ ++ if (ev && ev->ops) ++ return ev->ops->show(m, ev); ++ ++ return 0; ++} ++ ++static const struct seq_operations dyn_event_seq_op = { ++ .start = dyn_event_seq_start, ++ .next = dyn_event_seq_next, ++ .stop = dyn_event_seq_stop, ++ .show = dyn_event_seq_show ++}; ++ ++/* ++ * dyn_events_release_all - Release all specific events ++ * @type: the dyn_event_operations * which filters releasing events ++ * ++ * This releases all events which ->ops matches @type. If @type is NULL, ++ * all events are released. ++ * Return -EBUSY if any of them are in use, and return other errors when ++ * it failed to free the given event. Except for -EBUSY, event releasing ++ * process will be aborted at that point and there may be some other ++ * releasable events on the list. ++ */ ++int dyn_events_release_all(struct dyn_event_operations *type) ++{ ++ struct dyn_event *ev, *tmp; ++ int ret = 0; ++ ++ mutex_lock(&event_mutex); ++ for_each_dyn_event(ev) { ++ if (type && ev->ops != type) ++ continue; ++ if (ev->ops->is_busy(ev)) { ++ ret = -EBUSY; ++ goto out; ++ } ++ } ++ for_each_dyn_event_safe(ev, tmp) { ++ if (type && ev->ops != type) ++ continue; ++ ret = ev->ops->free(ev); ++ if (ret) ++ break; ++ } ++out: ++ mutex_unlock(&event_mutex); ++ ++ return ret; ++} ++ ++static int dyn_event_open(struct inode *inode, struct file *file) ++{ ++ int ret; ++ ++ if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) { ++ ret = dyn_events_release_all(NULL); ++ if (ret < 0) ++ return ret; ++ } ++ ++ return seq_open(file, &dyn_event_seq_op); ++} ++ ++static ssize_t dyn_event_write(struct file *file, const char __user *buffer, ++ size_t count, loff_t *ppos) ++{ ++ return trace_parse_run_command(file, buffer, count, ppos, ++ create_dyn_event); ++} ++ ++static const struct file_operations dynamic_events_ops = { ++ .owner = THIS_MODULE, ++ .open = dyn_event_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = seq_release, ++ .write = dyn_event_write, ++}; ++ ++/* Make a tracefs interface for controlling dynamic events */ ++static __init int init_dynamic_event(void) ++{ ++ struct dentry *d_tracer; ++ struct dentry *entry; ++ ++ d_tracer = tracing_init_dentry(); ++ if (IS_ERR(d_tracer)) ++ return 0; ++ ++ entry = tracefs_create_file("dynamic_events", 0644, d_tracer, ++ NULL, &dynamic_events_ops); ++ ++ /* Event list interface */ ++ if (!entry) ++ pr_warn("Could not create tracefs 'dynamic_events' entry\n"); ++ ++ return 0; ++} ++fs_initcall(init_dynamic_event); +diff --git a/kernel/trace/trace_dynevent.h b/kernel/trace/trace_dynevent.h +new file mode 100644 +index 000000000000..8c334064e4d6 +--- /dev/null ++++ b/kernel/trace/trace_dynevent.h +@@ -0,0 +1,119 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++/* ++ * Common header file for generic dynamic events. ++ */ ++ ++#ifndef _TRACE_DYNEVENT_H ++#define _TRACE_DYNEVENT_H ++ ++#include ++#include ++#include ++#include ++ ++#include "trace.h" ++ ++struct dyn_event; ++ ++/** ++ * struct dyn_event_operations - Methods for each type of dynamic events ++ * ++ * These methods must be set for each type, since there is no default method. ++ * Before using this for dyn_event_init(), it must be registered by ++ * dyn_event_register(). ++ * ++ * @create: Parse and create event method. This is invoked when user passes ++ * a event definition to dynamic_events interface. This must not destruct ++ * the arguments and return -ECANCELED if given arguments doesn't match its ++ * command prefix. ++ * @show: Showing method. This is invoked when user reads the event definitions ++ * via dynamic_events interface. ++ * @is_busy: Check whether given event is busy so that it can not be deleted. ++ * Return true if it is busy, otherwides false. ++ * @free: Delete the given event. Return 0 if success, otherwides error. ++ * @match: Check whether given event and system name match this event. ++ * Return true if it matches, otherwides false. ++ * ++ * Except for @create, these methods are called under holding event_mutex. ++ */ ++struct dyn_event_operations { ++ struct list_head list; ++ int (*create)(int argc, const char *argv[]); ++ int (*show)(struct seq_file *m, struct dyn_event *ev); ++ bool (*is_busy)(struct dyn_event *ev); ++ int (*free)(struct dyn_event *ev); ++ bool (*match)(const char *system, const char *event, ++ struct dyn_event *ev); ++}; ++ ++/* Register new dyn_event type -- must be called at first */ ++int dyn_event_register(struct dyn_event_operations *ops); ++ ++/** ++ * struct dyn_event - Dynamic event list header ++ * ++ * The dyn_event structure encapsulates a list and a pointer to the operators ++ * for making a global list of dynamic events. ++ * User must includes this in each event structure, so that those events can ++ * be added/removed via dynamic_events interface. ++ */ ++struct dyn_event { ++ struct list_head list; ++ struct dyn_event_operations *ops; ++}; ++ ++extern struct list_head dyn_event_list; ++ ++static inline ++int dyn_event_init(struct dyn_event *ev, struct dyn_event_operations *ops) ++{ ++ if (!ev || !ops) ++ return -EINVAL; ++ ++ INIT_LIST_HEAD(&ev->list); ++ ev->ops = ops; ++ return 0; ++} ++ ++static inline int dyn_event_add(struct dyn_event *ev) ++{ ++ lockdep_assert_held(&event_mutex); ++ ++ if (!ev || !ev->ops) ++ return -EINVAL; ++ ++ list_add_tail(&ev->list, &dyn_event_list); ++ return 0; ++} ++ ++static inline void dyn_event_remove(struct dyn_event *ev) ++{ ++ lockdep_assert_held(&event_mutex); ++ list_del_init(&ev->list); ++} ++ ++void *dyn_event_seq_start(struct seq_file *m, loff_t *pos); ++void *dyn_event_seq_next(struct seq_file *m, void *v, loff_t *pos); ++void dyn_event_seq_stop(struct seq_file *m, void *v); ++int dyn_events_release_all(struct dyn_event_operations *type); ++int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type); ++ ++/* ++ * for_each_dyn_event - iterate over the dyn_event list ++ * @pos: the struct dyn_event * to use as a loop cursor ++ * ++ * This is just a basement of for_each macro. Wrap this for ++ * each actual event structure with ops filtering. ++ */ ++#define for_each_dyn_event(pos) \ ++ list_for_each_entry(pos, &dyn_event_list, list) ++ ++/* ++ * for_each_dyn_event - iterate over the dyn_event list safely ++ * @pos: the struct dyn_event * to use as a loop cursor ++ * @n: the struct dyn_event * to use as temporary storage ++ */ ++#define for_each_dyn_event_safe(pos, n) \ ++ list_for_each_entry_safe(pos, n, &dyn_event_list, list) ++ ++#endif +-- +2.35.1 + diff --git a/queue-4.19/tracing-free-buffers-when-a-used-dynamic-event-is-re.patch b/queue-4.19/tracing-free-buffers-when-a-used-dynamic-event-is-re.patch new file mode 100644 index 00000000000..9631f614a26 --- /dev/null +++ b/queue-4.19/tracing-free-buffers-when-a-used-dynamic-event-is-re.patch @@ -0,0 +1,211 @@ +From 85ebec2d5dd5264e83a4dc009833f390ce61be4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 23 Nov 2022 17:14:34 -0500 +Subject: tracing: Free buffers when a used dynamic event is removed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Steven Rostedt (Google) + +[ Upstream commit 4313e5a613049dfc1819a6dfb5f94cf2caff9452 ] + +After 65536 dynamic events have been added and removed, the "type" field +of the event then uses the first type number that is available (not +currently used by other events). A type number is the identifier of the +binary blobs in the tracing ring buffer (known as events) to map them to +logic that can parse the binary blob. + +The issue is that if a dynamic event (like a kprobe event) is traced and +is in the ring buffer, and then that event is removed (because it is +dynamic, which means it can be created and destroyed), if another dynamic +event is created that has the same number that new event's logic on +parsing the binary blob will be used. + +To show how this can be an issue, the following can crash the kernel: + + # cd /sys/kernel/tracing + # for i in `seq 65536`; do + echo 'p:kprobes/foo do_sys_openat2 $arg1:u32' > kprobe_events + # done + +For every iteration of the above, the writing to the kprobe_events will +remove the old event and create a new one (with the same format) and +increase the type number to the next available on until the type number +reaches over 65535 which is the max number for the 16 bit type. After it +reaches that number, the logic to allocate a new number simply looks for +the next available number. When an dynamic event is removed, that number +is then available to be reused by the next dynamic event created. That is, +once the above reaches the max number, the number assigned to the event in +that loop will remain the same. + +Now that means deleting one dynamic event and created another will reuse +the previous events type number. This is where bad things can happen. +After the above loop finishes, the kprobes/foo event which reads the +do_sys_openat2 function call's first parameter as an integer. + + # echo 1 > kprobes/foo/enable + # cat /etc/passwd > /dev/null + # cat trace + cat-2211 [005] .... 2007.849603: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196 + cat-2211 [005] .... 2007.849620: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196 + cat-2211 [005] .... 2007.849838: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196 + cat-2211 [005] .... 2007.849880: foo: (do_sys_openat2+0x0/0x130) arg1=4294967196 + # echo 0 > kprobes/foo/enable + +Now if we delete the kprobe and create a new one that reads a string: + + # echo 'p:kprobes/foo do_sys_openat2 +0($arg2):string' > kprobe_events + +And now we can the trace: + + # cat trace + sendmail-1942 [002] ..... 530.136320: foo: (do_sys_openat2+0x0/0x240) arg1= cat-2046 [004] ..... 530.930817: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������" + cat-2046 [004] ..... 530.930961: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������" + cat-2046 [004] ..... 530.934278: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������" + cat-2046 [004] ..... 530.934563: foo: (do_sys_openat2+0x0/0x240) arg1="������������������������������������������������������������������������������������������������" + bash-1515 [007] ..... 534.299093: foo: (do_sys_openat2+0x0/0x240) arg1="kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk���������@��4Z����;Y�����U + +And dmesg has: + +================================================================== +BUG: KASAN: use-after-free in string+0xd4/0x1c0 +Read of size 1 at addr ffff88805fdbbfa0 by task cat/2049 + + CPU: 0 PID: 2049 Comm: cat Not tainted 6.1.0-rc6-test+ #641 + Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v03.03 07/14/2016 + Call Trace: + + dump_stack_lvl+0x5b/0x77 + print_report+0x17f/0x47b + kasan_report+0xad/0x130 + string+0xd4/0x1c0 + vsnprintf+0x500/0x840 + seq_buf_vprintf+0x62/0xc0 + trace_seq_printf+0x10e/0x1e0 + print_type_string+0x90/0xa0 + print_kprobe_event+0x16b/0x290 + print_trace_line+0x451/0x8e0 + s_show+0x72/0x1f0 + seq_read_iter+0x58e/0x750 + seq_read+0x115/0x160 + vfs_read+0x11d/0x460 + ksys_read+0xa9/0x130 + do_syscall_64+0x3a/0x90 + entry_SYSCALL_64_after_hwframe+0x63/0xcd + RIP: 0033:0x7fc2e972ade2 + Code: c0 e9 b2 fe ff ff 50 48 8d 3d b2 3f 0a 00 e8 05 f0 01 00 0f 1f 44 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 <48> 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 ec 28 48 89 54 24 + RSP: 002b:00007ffc64e687c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000 + RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007fc2e972ade2 + RDX: 0000000000020000 RSI: 00007fc2e980d000 RDI: 0000000000000003 + RBP: 00007fc2e980d000 R08: 00007fc2e980c010 R09: 0000000000000000 + R10: 0000000000000022 R11: 0000000000000246 R12: 0000000000020f00 + R13: 0000000000000003 R14: 0000000000020000 R15: 0000000000020000 + + + The buggy address belongs to the physical page: + page:ffffea00017f6ec0 refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x5fdbb + flags: 0xfffffc0000000(node=0|zone=1|lastcpupid=0x1fffff) + raw: 000fffffc0000000 0000000000000000 ffffea00017f6ec8 0000000000000000 + raw: 0000000000000000 0000000000000000 00000000ffffffff 0000000000000000 + page dumped because: kasan: bad access detected + + Memory state around the buggy address: + ffff88805fdbbe80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ffff88805fdbbf00: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + >ffff88805fdbbf80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ^ + ffff88805fdbc000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ffff88805fdbc080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff + ================================================================== + +This was found when Zheng Yejian sent a patch to convert the event type +number assignment to use IDA, which gives the next available number, and +this bug showed up in the fuzz testing by Yujie Liu and the kernel test +robot. But after further analysis, I found that this behavior is the same +as when the event type numbers go past the 16bit max (and the above shows +that). + +As modules have a similar issue, but is dealt with by setting a +"WAS_ENABLED" flag when a module event is enabled, and when the module is +freed, if any of its events were enabled, the ring buffer that holds that +event is also cleared, to prevent reading stale events. The same can be +done for dynamic events. + +If any dynamic event that is being removed was enabled, then make sure the +buffers they were enabled in are now cleared. + +Link: https://lkml.kernel.org/r/20221123171434.545706e3@gandalf.local.home +Link: https://lore.kernel.org/all/20221110020319.1259291-1-zhengyejian1@huawei.com/ + +Cc: stable@vger.kernel.org +Cc: Andrew Morton +Depends-on: e18eb8783ec49 ("tracing: Add tracing_reset_all_online_cpus_unlocked() function") +Depends-on: 5448d44c38557 ("tracing: Add unified dynamic event framework") +Depends-on: 6212dd29683ee ("tracing/kprobes: Use dyn_event framework for kprobe events") +Depends-on: 065e63f951432 ("tracing: Only have rmmod clear buffers that its events were active in") +Depends-on: 575380da8b469 ("tracing: Only clear trace buffer on module unload if event was traced") +Fixes: 77b44d1b7c283 ("tracing/kprobes: Rename Kprobe-tracer to kprobe-event") +Reported-by: Zheng Yejian +Reported-by: Yujie Liu +Reported-by: kernel test robot +Acked-by: Masami Hiramatsu (Google) +Signed-off-by: Steven Rostedt (Google) +Signed-off-by: Sasha Levin +--- + kernel/trace/trace_dynevent.c | 2 ++ + kernel/trace/trace_events.c | 11 ++++++++++- + 2 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c +index f17a887abb66..303067d38619 100644 +--- a/kernel/trace/trace_dynevent.c ++++ b/kernel/trace/trace_dynevent.c +@@ -59,6 +59,7 @@ int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type) + break; + } + } ++ tracing_reset_all_online_cpus(); + mutex_unlock(&event_mutex); + + return ret; +@@ -154,6 +155,7 @@ int dyn_events_release_all(struct dyn_event_operations *type) + break; + } + out: ++ tracing_reset_all_online_cpus(); + mutex_unlock(&event_mutex); + + return ret; +diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c +index d2f9146d1ad7..c9aa7b4a4235 100644 +--- a/kernel/trace/trace_events.c ++++ b/kernel/trace/trace_events.c +@@ -2369,7 +2369,10 @@ static int probe_remove_event_call(struct trace_event_call *call) + * TRACE_REG_UNREGISTER. + */ + if (file->flags & EVENT_FILE_FL_ENABLED) +- return -EBUSY; ++ goto busy; ++ ++ if (file->flags & EVENT_FILE_FL_WAS_ENABLED) ++ tr->clear_trace = true; + /* + * The do_for_each_event_file_safe() is + * a double loop. After finding the call for this +@@ -2382,6 +2385,12 @@ static int probe_remove_event_call(struct trace_event_call *call) + __trace_remove_event_call(call); + + return 0; ++ busy: ++ /* No need to clear the trace now */ ++ list_for_each_entry(tr, &ftrace_trace_arrays, list) { ++ tr->clear_trace = false; ++ } ++ return -EBUSY; + } + + /* no event_mutex version */ +-- +2.35.1 + diff --git a/queue-4.19/xtensa-increase-size-of-gcc-stack-frame-check.patch b/queue-4.19/xtensa-increase-size-of-gcc-stack-frame-check.patch new file mode 100644 index 00000000000..9b219741f4d --- /dev/null +++ b/queue-4.19/xtensa-increase-size-of-gcc-stack-frame-check.patch @@ -0,0 +1,46 @@ +From d87b1f197eda3b516bae4ba1efc561e1ac48760e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 24 Sep 2021 15:43:29 -0700 +Subject: xtensa: increase size of gcc stack frame check + +From: Guenter Roeck + +[ Upstream commit 867050247e295cf20fce046a92a7e6491fcfe066 ] + +xtensa frame size is larger than the frame size for almost all other +architectures. This results in more than 50 "the frame size of is +larger than 1024 bytes" errors when trying to build xtensa:allmodconfig. + +Increase frame size for xtensa to 1536 bytes to avoid compile errors due +to frame size limits. + +Link: https://lkml.kernel.org/r/20210912025235.3514761-1-linux@roeck-us.net +Signed-off-by: Guenter Roeck +Reviewed-by: Max Filippov +Cc: Chris Zankel +Cc: David Laight +Cc: Masahiro Yamada +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Stable-dep-of: 152fe65f300e ("Kconfig.debug: provide a little extra FRAME_WARN leeway when KASAN is enabled") +Signed-off-by: Sasha Levin +--- + lib/Kconfig.debug | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug +index 556aae95d69b..12fc801811d3 100644 +--- a/lib/Kconfig.debug ++++ b/lib/Kconfig.debug +@@ -224,7 +224,7 @@ config FRAME_WARN + range 0 8192 + default 3072 if KASAN_EXTRA + default 2048 if GCC_PLUGIN_LATENT_ENTROPY +- default 1536 if (!64BIT && PARISC) ++ default 1536 if (!64BIT && (PARISC || XTENSA)) + default 1024 if (!64BIT && !PARISC) + default 2048 if 64BIT + help +-- +2.35.1 +