From: Greg Kroah-Hartman Date: Tue, 14 Jul 2026 14:55:31 +0000 (+0200) Subject: 6.18-stable patches X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=005d21545272eadff3a39109b8e5d9eb0190a74a;p=thirdparty%2Fkernel%2Fstable-queue.git 6.18-stable patches added patches: clocksource-drivers-timer-tegra186-fix-support-for-multiple-watchdog-instances.patch cpufreq-fix-hotplug-suspend-race-during-reboot.patch cpufreq-intel_pstate-sync-policy-cur-during-cpu-offline.patch cpufreq-pcc-fix-use-after-free-and-double-free-in-_osc-evaluation.patch cpufreq-qcom-cpufreq-hw-fix-possible-double-free.patch firmware_loader-fix-device-reference-leak-in-firmware_upload_register.patch hid-appleir-fix-uaf-on-pending-key_up_timer-in-remove.patch hid-hid-goodix-spi-validate-report-size-to-prevent-stack-buffer-overflow.patch hid-letsketch-fix-uaf-on-inrange_timer-at-driver-unbind.patch hid-lg-g15-cancel-pending-work-on-remove-to-fix-a-use-after-free.patch hid-multitouch-fix-out-of-bounds-bit-access-on-mt_io_flags.patch hid-pidff-use-correct-effect-type-in-effect-update.patch hid-sensor-hub-add-sensor_hub_input_attr_read_values-for-multi-byte-reads.patch hid-uhid-convert-to-hid_safe_input_report.patch hid-wacom-fix-slab-out-of-bounds-write-in-wacom_wac_queue_insert.patch hid-wacom-stop-hardware-after-post-start-probe-failures.patch hid-wacom-use-gfp_atomic-in-wacom_wac_queue_flush.patch libfs-set-sb_i_noexec-and-sb_i_nodev-by-default-in-init_pseudo.patch mm-slab-do-not-limit-zeroing-to-orig_size-when-only-red-zoning-is-enabled.patch opp-of-fix-potential-memory-leak-in-opp_parse_supplies.patch perf-arm-cmn-fix-dvm-node-events.patch perf-x86-intel-uncore-defer-adl-global-pmon-enable-to-enable_box.patch posix-cpu-timers-fix-pid-refcount-leak-in-do_cpu_nanosleep-error-path.patch s390-revert-support-for-dcache_word_access.patch sched-rt-have-rt_push_ipi-be-default-off-for-non-preempt_rt.patch time-jiffies-register-jiffies-clocksource-before-usage.patch tools-mm-slabinfo-fix-total_objects-attribute-name.patch tools-mm-slabinfo-fix-trace-disable-logic-inversion.patch writeback-fix-race-between-cgroup_writeback_umount-and-inode_switch_wbs.patch x.509-fix-validation-of-asn.1-certificate-header.patch --- diff --git a/queue-6.18/clocksource-drivers-timer-tegra186-fix-support-for-multiple-watchdog-instances.patch b/queue-6.18/clocksource-drivers-timer-tegra186-fix-support-for-multiple-watchdog-instances.patch new file mode 100644 index 0000000000..c3b1425100 --- /dev/null +++ b/queue-6.18/clocksource-drivers-timer-tegra186-fix-support-for-multiple-watchdog-instances.patch @@ -0,0 +1,41 @@ +From ca57bf46e7a94f8c53d05c376df9fcfdcb482100 Mon Sep 17 00:00:00 2001 +From: Kartik Rajput +Date: Thu, 7 May 2026 21:15:54 +0530 +Subject: clocksource/drivers/timer-tegra186: Fix support for multiple watchdog instances + +From: Kartik Rajput + +commit ca57bf46e7a94f8c53d05c376df9fcfdcb482100 upstream. + +Tegra SoCs support multiple watchdogs; currently only one (WDT0) is +used. When multiple watchdogs are registered, tegra186_wdt_enable() +overwrites the TKEIE(x) register, discarding any existing watchdog +interrupt enable bits. As a result, enabling one watchdog inadvertently +disables interrupts for the others. + +Fix this by preserving the existing TKEIE(x) value and updating it +using a read-modify-write sequence. + +Fixes: 42cee19a9f83 ("clocksource: Add Tegra186 timers support") +Cc: stable@vger.kernel.org +Signed-off-by: Kartik Rajput +Signed-off-by: Daniel Lezcano +Reviewed-by: Jon Hunter +Link: https://patch.msgid.link/20260507154557.2082697-2-kkartik@nvidia.com +Signed-off-by: Greg Kroah-Hartman +--- + drivers/clocksource/timer-tegra186.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/clocksource/timer-tegra186.c ++++ b/drivers/clocksource/timer-tegra186.c +@@ -149,7 +149,8 @@ static void tegra186_wdt_enable(struct t + u32 value; + + /* unmask hardware IRQ, this may have been lost across powergate */ +- value = TKEIE_WDT_MASK(wdt->index, 1); ++ value = readl(tegra->regs + TKEIE(wdt->tmr->hwirq)); ++ value |= TKEIE_WDT_MASK(wdt->index, 1); + writel(value, tegra->regs + TKEIE(wdt->tmr->hwirq)); + + /* clear interrupt */ diff --git a/queue-6.18/cpufreq-fix-hotplug-suspend-race-during-reboot.patch b/queue-6.18/cpufreq-fix-hotplug-suspend-race-during-reboot.patch new file mode 100644 index 0000000000..7e780814e7 --- /dev/null +++ b/queue-6.18/cpufreq-fix-hotplug-suspend-race-during-reboot.patch @@ -0,0 +1,62 @@ +From a9029dd55696c651ee46912afa2a166fa456bb3e Mon Sep 17 00:00:00 2001 +From: Tianxiang Chen +Date: Wed, 8 Apr 2026 22:19:14 +0800 +Subject: cpufreq: Fix hotplug-suspend race during reboot + +From: Tianxiang Chen + +commit a9029dd55696c651ee46912afa2a166fa456bb3e upstream. + +During system reboot, cpufreq_suspend() is called via the +kernel_restart() -> device_shutdown() path. Unlike the normal system +suspend path, the reboot path does not call freeze_processes(), so +userspace processes and kernel threads remain active. + +This allows CPU hotplug operations to run concurrently with +cpufreq_suspend(). The original code has no synchronization with CPU +hotplug, leading to a race condition where governor_data can be freed +by the hotplug path while cpufreq_suspend() is still accessing it, +resulting in a null pointer dereference: + + Unable to handle kernel NULL pointer dereference + Call Trace: + do_kernel_fault+0x28/0x3c + cpufreq_suspend+0xdc/0x160 + device_shutdown+0x18/0x200 + kernel_restart+0x40/0x80 + arm64_sys_reboot+0x1b0/0x200 + +Fix this by adding cpus_read_lock()/cpus_read_unlock() to +cpufreq_suspend() to block CPU hotplug operations while suspend is in +progress. + +Fixes: 65650b35133f ("cpufreq: Avoid cpufreq_suspend() deadlock on system shutdown") +Signed-off-by: Tianxiang Chen +Reviewed-by: Zhongqiu Han +Cc: All applicable +[ rjw: Changelog edits ] +Link: https://patch.msgid.link/20260408141914.35281-1-nanmu@xiaomi.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cpufreq/cpufreq.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/cpufreq/cpufreq.c ++++ b/drivers/cpufreq/cpufreq.c +@@ -1973,6 +1973,7 @@ void cpufreq_suspend(void) + if (!cpufreq_driver) + return; + ++ cpus_read_lock(); + if (!has_target() && !cpufreq_driver->suspend) + goto suspend; + +@@ -1992,6 +1993,7 @@ void cpufreq_suspend(void) + + suspend: + cpufreq_suspended = true; ++ cpus_read_unlock(); + } + + /** diff --git a/queue-6.18/cpufreq-intel_pstate-sync-policy-cur-during-cpu-offline.patch b/queue-6.18/cpufreq-intel_pstate-sync-policy-cur-during-cpu-offline.patch new file mode 100644 index 0000000000..20bc9a7c09 --- /dev/null +++ b/queue-6.18/cpufreq-intel_pstate-sync-policy-cur-during-cpu-offline.patch @@ -0,0 +1,51 @@ +From bcbdaa1086c25a8a5d48e04e1b82fdfb0682b681 Mon Sep 17 00:00:00 2001 +From: Fushuai Wang +Date: Wed, 20 May 2026 11:21:19 +0800 +Subject: cpufreq: intel_pstate: Sync policy->cur during CPU offline + +From: Fushuai Wang + +commit bcbdaa1086c25a8a5d48e04e1b82fdfb0682b681 upstream. + +When a CPU goes offline with HWP disabled, intel_pstate_set_min_pstate() +sets the MSR_IA32_PERF_CTL to minimum frequency to prevent SMT siblings +from being restricted. However, the policy->cur value was not updated, +leaving it at the previous value. + +When the CPU comes back online, governor->limits() checks if target_freq +equals policy->cur and skips the frequency adjustment if they match. Since +policy->cur still holds the previous value, the governor does not call +cpufreq_driver->target to update MSR_IA32_PERF_CTL. + +Fix this by synchronizing policy->cur with the hardware state when setting +minimum pstate during CPU offline. + +Fixes: bb18008f8086 ("intel_pstate: Set core to min P state during core offline") +Cc: stable@vger.kernel.org # 3.15+ +Suggested-by: Srinivas Pandruvada +Signed-off-by: Fushuai Wang +[ rjw: Subject refinement ] +Link: https://patch.msgid.link/20260520032119.30615-1-fushuai.wang@linux.dev +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cpufreq/intel_pstate.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/cpufreq/intel_pstate.c ++++ b/drivers/cpufreq/intel_pstate.c +@@ -3016,10 +3016,12 @@ static int intel_cpufreq_cpu_offline(str + * from getting to lower performance levels, so force the minimum + * performance on CPU offline to prevent that from happening. + */ +- if (hwp_active) ++ if (hwp_active) { + intel_pstate_hwp_offline(cpu); +- else ++ } else { + intel_pstate_set_min_pstate(cpu); ++ policy->cur = cpu->pstate.min_freq; ++ } + + intel_pstate_exit_perf_limits(policy); + diff --git a/queue-6.18/cpufreq-pcc-fix-use-after-free-and-double-free-in-_osc-evaluation.patch b/queue-6.18/cpufreq-pcc-fix-use-after-free-and-double-free-in-_osc-evaluation.patch new file mode 100644 index 0000000000..4b4df0cb99 --- /dev/null +++ b/queue-6.18/cpufreq-pcc-fix-use-after-free-and-double-free-in-_osc-evaluation.patch @@ -0,0 +1,43 @@ +From 266d3dd8b757b48a576e90f018b51f7b7563cc32 Mon Sep 17 00:00:00 2001 +From: Yuho Choi +Date: Thu, 16 Apr 2026 10:46:21 -0400 +Subject: cpufreq: pcc: fix use-after-free and double free in _OSC evaluation + +From: Yuho Choi + +commit 266d3dd8b757b48a576e90f018b51f7b7563cc32 upstream. + +pcc_cpufreq_do_osc() calls acpi_evaluate_object() twice for the +two-phase _OSC negotiation. Between the two calls it freed +output.pointer but left output.length unchanged. Since +acpi_evaluate_object() treats a non-zero length with a non-NULL +pointer as an existing buffer to write into, the second call wrote +into freed memory (use-after-free). The subsequent kfree(output.pointer) +at out_free then freed the same pointer a second time (double free). + +Reset output.pointer to NULL and output.length to ACPI_ALLOCATE_BUFFER +after freeing the first result, so ACPICA allocates a fresh buffer for +each phase independently. + +Fixes: 0f1d683fb35d ("[CPUFREQ] Processor Clocking Control interface driver") +Signed-off-by: Yuho Choi +Reviewed-by: Zhongqiu Han +Cc: All applicable +Link: https://patch.msgid.link/20260416144621.93964-1-dbgh9129@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cpufreq/pcc-cpufreq.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/cpufreq/pcc-cpufreq.c ++++ b/drivers/cpufreq/pcc-cpufreq.c +@@ -352,6 +352,8 @@ static int __init pcc_cpufreq_do_osc(acp + } + + kfree(output.pointer); ++ output.pointer = NULL; ++ output.length = ACPI_ALLOCATE_BUFFER; + capabilities[0] = 0x0; + capabilities[1] = 0x1; + diff --git a/queue-6.18/cpufreq-qcom-cpufreq-hw-fix-possible-double-free.patch b/queue-6.18/cpufreq-qcom-cpufreq-hw-fix-possible-double-free.patch new file mode 100644 index 0000000000..5f28bf9bf9 --- /dev/null +++ b/queue-6.18/cpufreq-qcom-cpufreq-hw-fix-possible-double-free.patch @@ -0,0 +1,44 @@ +From bcb8889c4981fdde42d4fd2c29a77d510fe21da2 Mon Sep 17 00:00:00 2001 +From: Guangshuo Li +Date: Sat, 2 May 2026 03:00:05 +0800 +Subject: cpufreq: qcom-cpufreq-hw: Fix possible double free + +From: Guangshuo Li + +commit bcb8889c4981fdde42d4fd2c29a77d510fe21da2 upstream. + +qcom_cpufreq.data is allocated with devm_kzalloc() in probe() as an +array of per-domain data. qcom_cpufreq_hw_cpu_init() stores a pointer to +one element of this array in policy->driver_data. + +qcom_cpufreq_hw_cpu_exit() currently calls kfree() on policy->driver_data. +This is not valid because the memory is devm-managed. For the first +domain, this can free the devm-managed allocation while the devres entry +is still active, leading to a possible double free when the platform +device is later detached. For other domains, the pointer may refer to an +element inside the array rather than the allocation base. + +Remove the kfree(data) call and let devres release qcom_cpufreq.data. + +This issue was found by a static analysis tool I am developing. + +Fixes: 054a3ef683a1 ("cpufreq: qcom-hw: Allocate qcom_cpufreq_data during probe") +Cc: stable@vger.kernel.org +Signed-off-by: Guangshuo Li +Reviewed-by: Zhongqiu Han +Signed-off-by: Viresh Kumar +Signed-off-by: Greg Kroah-Hartman +--- + drivers/cpufreq/qcom-cpufreq-hw.c | 1 - + 1 file changed, 1 deletion(-) + +--- a/drivers/cpufreq/qcom-cpufreq-hw.c ++++ b/drivers/cpufreq/qcom-cpufreq-hw.c +@@ -578,7 +578,6 @@ static void qcom_cpufreq_hw_cpu_exit(str + dev_pm_opp_of_cpumask_remove_table(policy->related_cpus); + qcom_cpufreq_hw_lmh_exit(data); + kfree(policy->freq_table); +- kfree(data); + } + + static void qcom_cpufreq_ready(struct cpufreq_policy *policy) diff --git a/queue-6.18/firmware_loader-fix-device-reference-leak-in-firmware_upload_register.patch b/queue-6.18/firmware_loader-fix-device-reference-leak-in-firmware_upload_register.patch new file mode 100644 index 0000000000..ae9ee22c5a --- /dev/null +++ b/queue-6.18/firmware_loader-fix-device-reference-leak-in-firmware_upload_register.patch @@ -0,0 +1,73 @@ +From 896df22ee57648b0c505bd76ddbc6b2341834696 Mon Sep 17 00:00:00 2001 +From: Guangshuo Li +Date: Tue, 5 May 2026 17:12:31 +0800 +Subject: firmware_loader: fix device reference leak in firmware_upload_register() + +From: Guangshuo Li + +commit 896df22ee57648b0c505bd76ddbc6b2341834696 upstream. + +firmware_upload_register() + -> fw_create_instance() + -> device_initialize() + +After fw_create_instance() succeeds, the lifetime of the embedded struct +device is expected to be managed through the device core reference +counting, since fw_create_instance() has already called +device_initialize(). + +In firmware_upload_register(), if alloc_lookup_fw_priv() fails after +fw_create_instance() succeeds, the code reaches free_fw_sysfs and frees +fw_sysfs directly instead of releasing the device reference with +put_device(). This may leave the reference count of the embedded struct +device unbalanced, resulting in a refcount leak. + +The issue was identified by a static analysis tool I developed and +confirmed by manual review. Fix this by using put_device(fw_dev) in the +failure path and letting fw_dev_release() handle the final cleanup, +instead of freeing the instance directly from the error path. + +Fixes: 97730bbb242c ("firmware_loader: Add firmware-upload support") +Cc: stable@vger.kernel.org +Signed-off-by: Guangshuo Li +Link: https://patch.msgid.link/20260505091231.607089-1-lgs201920130244@gmail.com +Signed-off-by: Danilo Krummrich +Signed-off-by: Greg Kroah-Hartman +--- + drivers/base/firmware_loader/sysfs_upload.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/base/firmware_loader/sysfs_upload.c ++++ b/drivers/base/firmware_loader/sysfs_upload.c +@@ -341,7 +341,6 @@ firmware_upload_register(struct module * + goto free_fw_upload_priv; + } + fw_upload->priv = fw_sysfs; +- fw_sysfs->fw_upload_priv = fw_upload_priv; + fw_dev = &fw_sysfs->dev; + + ret = alloc_lookup_fw_priv(name, &fw_cache, &fw_priv, NULL, 0, 0, +@@ -349,10 +348,12 @@ firmware_upload_register(struct module * + if (ret != 0) { + if (ret > 0) + ret = -EINVAL; +- goto free_fw_sysfs; ++ put_device(fw_dev); ++ goto free_fw_upload_priv; + } + fw_priv->is_paged_buf = true; + fw_sysfs->fw_priv = fw_priv; ++ fw_sysfs->fw_upload_priv = fw_upload_priv; + + ret = device_add(fw_dev); + if (ret) { +@@ -363,9 +364,6 @@ firmware_upload_register(struct module * + + return fw_upload; + +-free_fw_sysfs: +- kfree(fw_sysfs); +- + free_fw_upload_priv: + kfree(fw_upload_priv); + diff --git a/queue-6.18/hid-appleir-fix-uaf-on-pending-key_up_timer-in-remove.patch b/queue-6.18/hid-appleir-fix-uaf-on-pending-key_up_timer-in-remove.patch new file mode 100644 index 0000000000..5b9effd36a --- /dev/null +++ b/queue-6.18/hid-appleir-fix-uaf-on-pending-key_up_timer-in-remove.patch @@ -0,0 +1,146 @@ +From 75fe87e19d8aff81eb2c64d15d244ab8da4de945 Mon Sep 17 00:00:00 2001 +From: Manish Khadka +Date: Fri, 15 May 2026 23:17:52 +0545 +Subject: HID: appleir: fix UAF on pending key_up_timer in remove() + +From: Manish Khadka + +commit 75fe87e19d8aff81eb2c64d15d244ab8da4de945 upstream. + +appleir_remove() runs hid_hw_stop() before timer_delete_sync(). +hid_hw_stop() synchronously unregisters the HID input device via +hid_disconnect() -> hidinput_disconnect() -> input_unregister_device(), +which drops the last reference and frees the underlying input_dev when +no userspace handle holds it open. + +key_up_tick() reads appleir->input_dev and calls input_report_key() / +input_sync() on it. The timer is armed from appleir_raw_event() with +a HZ/8 (~125 ms) timeout on every keydown and key-repeat report. If a +key was pressed shortly before the device is disconnected, the timer +can fire after hid_hw_stop() has freed input_dev but before the +teardown drains it. + +A simple reorder is not sufficient. Putting the timer drain first +still leaves a window where a USB URB completion (raw_event) running +during hid_hw_stop() can call mod_timer() and re-arm the timer, which +then fires after hidinput_disconnect() has freed input_dev. The same +URB-completion window also lets raw_event() reach key_up(), key_down() +and battery_flat() directly, all of which dereference +appleir->input_dev. + +Introduce a 'removing' flag on struct appleir, gated by the existing +spinlock. appleir_remove() sets the flag under the lock and then +shuts down the timer with timer_shutdown_sync(), which both drains any +in-flight callback and permanently disables further mod_timer() calls. +appleir_raw_event() and key_up_tick() bail out early if the flag is +set, so no path can arm or run the timer, or dereference +appleir->input_dev, after remove() has started tearing down. + +The keyrepeat and flatbattery branches of appleir_raw_event() +previously called into the input layer without holding the spinlock; +take it now so the flag check is well-defined. This incidentally +closes a pre-existing read-side race on appleir->current_key in the +keyrepeat branch. + +This bug is structurally a sibling of commit 4db2af929279 ("HID: +appletb-kbd: fix UAF in inactivity-timer cleanup path") and has been +present since the driver was introduced. + +Fixes: 9a4a5574ce42 ("HID: appleir: add support for Apple ir devices") +Cc: stable@vger.kernel.org +Signed-off-by: Manish Khadka +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-appleir.c | 45 +++++++++++++++++++++++++++++++++++---------- + 1 file changed, 35 insertions(+), 10 deletions(-) + +--- a/drivers/hid/hid-appleir.c ++++ b/drivers/hid/hid-appleir.c +@@ -109,9 +109,10 @@ struct appleir { + struct hid_device *hid; + unsigned short keymap[ARRAY_SIZE(appleir_key_table)]; + struct timer_list key_up_timer; /* timer for key up */ +- spinlock_t lock; /* protects .current_key */ ++ spinlock_t lock; /* protects .current_key, .removing */ + int current_key; /* the currently pressed key */ + int prev_key_idx; /* key index in a 2 packets message */ ++ bool removing; /* set during teardown; gates input_dev access */ + }; + + static int get_key(int data) +@@ -172,7 +173,7 @@ static void key_up_tick(struct timer_lis + unsigned long flags; + + spin_lock_irqsave(&appleir->lock, flags); +- if (appleir->current_key) { ++ if (!appleir->removing && appleir->current_key) { + key_up(hid, appleir, appleir->current_key); + appleir->current_key = 0; + } +@@ -195,6 +196,10 @@ static int appleir_raw_event(struct hid_ + int index; + + spin_lock_irqsave(&appleir->lock, flags); ++ if (appleir->removing) { ++ spin_unlock_irqrestore(&appleir->lock, flags); ++ goto out; ++ } + /* + * If we already have a key down, take it up before marking + * this one down +@@ -229,17 +234,25 @@ static int appleir_raw_event(struct hid_ + appleir->prev_key_idx = 0; + + if (!memcmp(data, keyrepeat, sizeof(keyrepeat))) { +- key_down(hid, appleir, appleir->current_key); +- /* +- * Remote doesn't do key up, either pull them up, in the test +- * above, or here set a timer which pulls them up after 1/8 s +- */ +- mod_timer(&appleir->key_up_timer, jiffies + HZ / 8); ++ spin_lock_irqsave(&appleir->lock, flags); ++ if (!appleir->removing) { ++ key_down(hid, appleir, appleir->current_key); ++ /* ++ * Remote doesn't do key up, either pull them up, in ++ * the test above, or here set a timer which pulls them ++ * up after 1/8 s ++ */ ++ mod_timer(&appleir->key_up_timer, jiffies + HZ / 8); ++ } ++ spin_unlock_irqrestore(&appleir->lock, flags); + goto out; + } + + if (!memcmp(data, flatbattery, sizeof(flatbattery))) { +- battery_flat(appleir); ++ spin_lock_irqsave(&appleir->lock, flags); ++ if (!appleir->removing) ++ battery_flat(appleir); ++ spin_unlock_irqrestore(&appleir->lock, flags); + /* Fall through */ + } + +@@ -318,8 +331,20 @@ fail: + static void appleir_remove(struct hid_device *hid) + { + struct appleir *appleir = hid_get_drvdata(hid); ++ unsigned long flags; ++ ++ /* ++ * Mark the driver as tearing down so that any concurrent raw_event ++ * (e.g. from a USB URB completion that hid_hw_stop() has not yet ++ * killed) and the key_up_timer softirq stop touching input_dev ++ * before hid_hw_stop() frees it via hidinput_disconnect(). ++ */ ++ spin_lock_irqsave(&appleir->lock, flags); ++ appleir->removing = true; ++ spin_unlock_irqrestore(&appleir->lock, flags); ++ ++ timer_shutdown_sync(&appleir->key_up_timer); + hid_hw_stop(hid); +- timer_delete_sync(&appleir->key_up_timer); + } + + static const struct hid_device_id appleir_devices[] = { diff --git a/queue-6.18/hid-hid-goodix-spi-validate-report-size-to-prevent-stack-buffer-overflow.patch b/queue-6.18/hid-hid-goodix-spi-validate-report-size-to-prevent-stack-buffer-overflow.patch new file mode 100644 index 0000000000..fa2f93b3e9 --- /dev/null +++ b/queue-6.18/hid-hid-goodix-spi-validate-report-size-to-prevent-stack-buffer-overflow.patch @@ -0,0 +1,48 @@ +From db0a0768d09273aadadeb76730cd658d720333a4 Mon Sep 17 00:00:00 2001 +From: Tianchu Chen +Date: Fri, 29 May 2026 13:42:47 +0000 +Subject: HID: hid-goodix-spi: validate report size to prevent stack buffer overflow + +From: Tianchu Chen + +commit db0a0768d09273aadadeb76730cd658d720333a4 upstream. + +goodix_hid_set_raw_report() builds a protocol frame in a 128-byte stack +buffer (tmp_buf), writing an 11-12 byte header followed by the +caller-supplied report data. The HID core caps report size at +HID_MAX_BUFFER_SIZE (16384) by default, while the driver does not set +hid_ll_driver.max_buffer_size and performs no bounds checking before +copying the payload: + + memcpy(tmp_buf + tx_len, buf, len); + +A hidraw SET_REPORT ioctl with a report larger than ~116 bytes +overflows the stack buffer. + +Add a size check after constructing the header, rejecting reports that +would exceed the buffer capacity. + +Discovered by Atuin - Automated Vulnerability Discovery Engine. + +Fixes: 75e16c8ce283 ("HID: hid-goodix: Add Goodix HID-over-SPI driver") +Cc: stable@vger.kernel.org +Signed-off-by: Tianchu Chen +Reviewed-by: Dmitry Torokhov +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-goodix-spi.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/hid/hid-goodix-spi.c ++++ b/drivers/hid/hid-goodix-spi.c +@@ -520,6 +520,9 @@ static int goodix_hid_set_raw_report(str + memcpy(tmp_buf + tx_len, args, args_len); + tx_len += args_len; + ++ if (tx_len + len > sizeof(tmp_buf)) ++ return -EINVAL; ++ + memcpy(tmp_buf + tx_len, buf, len); + tx_len += len; + diff --git a/queue-6.18/hid-letsketch-fix-uaf-on-inrange_timer-at-driver-unbind.patch b/queue-6.18/hid-letsketch-fix-uaf-on-inrange_timer-at-driver-unbind.patch new file mode 100644 index 0000000000..ce443c3a95 --- /dev/null +++ b/queue-6.18/hid-letsketch-fix-uaf-on-inrange_timer-at-driver-unbind.patch @@ -0,0 +1,105 @@ +From 46c8beeccd8ab2c863827254a85ea877654a3534 Mon Sep 17 00:00:00 2001 +From: Manish Khadka +Date: Fri, 15 May 2026 22:27:00 +0545 +Subject: HID: letsketch: fix UAF on inrange_timer at driver unbind + +From: Manish Khadka + +commit 46c8beeccd8ab2c863827254a85ea877654a3534 upstream. + +letsketch_driver does not provide a .remove callback, but +letsketch_probe() arms a per-device timer: + + timer_setup(&data->inrange_timer, letsketch_inrange_timeout, 0); + +The timer is re-armed from letsketch_raw_event() with a 100 ms +timeout on every pen-in-range report, and its callback dereferences +data->input_tablet to deliver a synthetic BTN_TOOL_PEN release. + +letsketch_data is allocated with devm_kzalloc(), and its input_dev +fields are devm-allocated via letsketch_setup_input_tablet(). On +device unbind (USB unplug or rmmod), the HID core runs its default +teardown and devm cleanup frees both letsketch_data and the input +devices. Because no .remove callback exists, nothing drains the +timer first: if raw_event armed it within ~100 ms of the unbind, +the pending timer fires on freed memory. This is a UAF read of +data and of data->input_tablet, followed by input_report_key() / +input_sync() into the freed input_dev. + +The same problem can occur on the probe error path: if +hid_hw_start() enabled I/O on an always-poll-quirk device and then +failed, raw_event may have armed the timer before devm releases +data. + +Fix by adding a .remove callback that calls hid_hw_stop() first. +hid_hw_stop() synchronously kills the URBs that deliver raw_event(), +so once it returns no path can re-arm the timer. timer_shutdown_sync() +then drains any in-flight callback and permanently disables further +mod_timer() calls. Apply the same timer_shutdown_sync() in the probe +error path so the timer is guaranteed not to outlive data. + +Fixes: 33a5c2793451 ("HID: Add new Letsketch tablet driver") +Cc: stable@vger.kernel.org +Signed-off-by: Manish Khadka +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-letsketch.c | 36 +++++++++++++++++++++++++++++++++--- + 1 file changed, 33 insertions(+), 3 deletions(-) + +--- a/drivers/hid/hid-letsketch.c ++++ b/drivers/hid/hid-letsketch.c +@@ -296,13 +296,42 @@ static int letsketch_probe(struct hid_de + + ret = letsketch_setup_input_tablet(data); + if (ret) +- return ret; ++ goto err_shutdown_timer; + + ret = letsketch_setup_input_tablet_pad(data); + if (ret) +- return ret; ++ goto err_shutdown_timer; + +- return hid_hw_start(hdev, HID_CONNECT_HIDRAW); ++ ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); ++ if (ret) ++ goto err_shutdown_timer; ++ ++ return 0; ++ ++err_shutdown_timer: ++ /* ++ * Drain any pending callback and permanently disable the timer ++ * before devm releases data: if hid_hw_start() enabled I/O on an ++ * always-poll-quirk device and then failed, raw_event may have ++ * armed the timer already. ++ */ ++ timer_shutdown_sync(&data->inrange_timer); ++ return ret; ++} ++ ++static void letsketch_remove(struct hid_device *hdev) ++{ ++ struct letsketch_data *data = hid_get_drvdata(hdev); ++ ++ /* ++ * hid_hw_stop() synchronously kills the URBs that deliver ++ * raw_event(), so once it returns no path can re-arm ++ * inrange_timer. timer_shutdown_sync() then drains any ++ * in-flight callback and permanently disables further ++ * mod_timer() calls before devm releases data. ++ */ ++ hid_hw_stop(hdev); ++ timer_shutdown_sync(&data->inrange_timer); + } + + static const struct hid_device_id letsketch_devices[] = { +@@ -315,6 +344,7 @@ static struct hid_driver letsketch_drive + .name = "letsketch", + .id_table = letsketch_devices, + .probe = letsketch_probe, ++ .remove = letsketch_remove, + .raw_event = letsketch_raw_event, + }; + module_hid_driver(letsketch_driver); diff --git a/queue-6.18/hid-lg-g15-cancel-pending-work-on-remove-to-fix-a-use-after-free.patch b/queue-6.18/hid-lg-g15-cancel-pending-work-on-remove-to-fix-a-use-after-free.patch new file mode 100644 index 0000000000..13173f16d2 --- /dev/null +++ b/queue-6.18/hid-lg-g15-cancel-pending-work-on-remove-to-fix-a-use-after-free.patch @@ -0,0 +1,68 @@ +From 7705b4140d188ce22656f6e541ae7ef834c7e11a Mon Sep 17 00:00:00 2001 +From: Maoyi Xie +Date: Thu, 18 Jun 2026 15:06:35 +0800 +Subject: HID: lg-g15: cancel pending work on remove to fix a use-after-free + +From: Maoyi Xie + +commit 7705b4140d188ce22656f6e541ae7ef834c7e11a upstream. + +lg_g15_data is allocated with devm and holds a work item. The report +handlers schedule that work straight from device input. +lg_g15_event() and lg_g15_v2_event() do it on the backlight cycle key, +and lg_g510_leds_event() does it too. The worker dereferences the +lg_g15_data back through container_of. + +The driver had no remove callback and never cancelled the work. So if a +report scheduled the work and the keyboard was then unplugged, devres +freed lg_g15_data while the work was still pending or running, and the +worker touched freed memory. This is a use-after-free. It is reachable +as a race on device unplug. + +Add a remove callback that cancels the work before devres frees the +state. g15->work is only initialized for the models that schedule it +(G15, G15 v2, G510). The G13 and Z-10 leave it zeroed, so guard the +cancel on g15->work.func to avoid cancelling a work that was never set +up. The g15 NULL test mirrors the one already in lg_g15_raw_event(). + +Fixes: 97b741aba918 ("HID: lg-g15: Add keyboard and LCD backlight control") +Cc: stable@vger.kernel.org +Suggested-by: Hans de Goede +Signed-off-by: Maoyi Xie +Reviewed-by: Hans de Goede +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-lg-g15.c | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +--- a/drivers/hid/hid-lg-g15.c ++++ b/drivers/hid/hid-lg-g15.c +@@ -929,11 +929,27 @@ static const struct hid_device_id lg_g15 + }; + MODULE_DEVICE_TABLE(hid, lg_g15_devices); + ++static void lg_g15_remove(struct hid_device *hdev) ++{ ++ struct lg_g15_data *g15 = hid_get_drvdata(hdev); ++ ++ /* ++ * g15->work is only initialized for the models that schedule it ++ * (G15, G15 v2, G510). The G13 and Z-10 leave it zeroed, so only ++ * cancel it when it was set up. ++ */ ++ if (g15 && g15->work.func) ++ cancel_work_sync(&g15->work); ++ ++ hid_hw_stop(hdev); ++} ++ + static struct hid_driver lg_g15_driver = { + .name = "lg-g15", + .id_table = lg_g15_devices, + .raw_event = lg_g15_raw_event, + .probe = lg_g15_probe, ++ .remove = lg_g15_remove, + }; + module_hid_driver(lg_g15_driver); + diff --git a/queue-6.18/hid-multitouch-fix-out-of-bounds-bit-access-on-mt_io_flags.patch b/queue-6.18/hid-multitouch-fix-out-of-bounds-bit-access-on-mt_io_flags.patch new file mode 100644 index 0000000000..a319a4470a --- /dev/null +++ b/queue-6.18/hid-multitouch-fix-out-of-bounds-bit-access-on-mt_io_flags.patch @@ -0,0 +1,154 @@ +From 8813b0612275cc61fe9e6603d0ee019247ade6be Mon Sep 17 00:00:00 2001 +From: Trung Nguyen +Date: Thu, 2 Jul 2026 00:13:19 +0700 +Subject: HID: multitouch: fix out-of-bounds bit access on mt_io_flags + +From: Trung Nguyen + +commit 8813b0612275cc61fe9e6603d0ee019247ade6be upstream. + +mt_io_flags is a single unsigned long, but mt_process_slot(), +mt_release_pending_palms() and mt_release_contacts() use it as a +per-slot bitmap indexed by the slot number. That slot number is only +bounded by td->maxcontacts, which is taken from the device's +ContactCountMaximum feature report and can be up to 255, not by +BITS_PER_LONG. + +As a result, a multitouch device that advertises a large contact count +makes set_bit()/clear_bit() operate past the mt_io_flags word and +corrupt the adjacent members of struct mt_device. The sticky-fingers +release timer is the easiest way to reach this. mt_release_contacts() +runs + + for (i = 0; i < mt->num_slots; i++) + clear_bit(i, &td->mt_io_flags); + +with num_slots == maxcontacts. For maxcontacts around 250 the loop +clears the bits that overlap td->applications.next, zeroing that list +head, and the list_for_each_entry() that immediately follows then +dereferences NULL. The kernel panics from timer (softirq) context. On a +KASAN build this shows up as a general protection fault in +mt_release_contacts() with a null-ptr-deref at offset 0x58, which is +offsetof(struct mt_application, num_received). + +The state is reachable from an untrusted USB or Bluetooth HID +multitouch device; no local privileges are required. + +Store the per-slot active state in a separately allocated bitmap sized +for maxcontacts, the same pattern already used for pending_palm_slots, +and keep only MT_IO_FLAGS_RUNNING in mt_io_flags. The two +"mt_io_flags & MT_IO_SLOTS_MASK" arming checks become +bitmap_empty(td->active_slots, td->maxcontacts). + +Move MT_IO_FLAGS_RUNNING back to bit 0. It was bumped to bit 32 by the +same commit to leave the low byte for the slot bits; with the slot bits +gone it fits in bit 0 again, which also keeps it within the unsigned +long on 32-bit. + +Fixes: 46f781e0d151 ("HID: multitouch: fix sticky fingers") +Cc: stable@vger.kernel.org +Signed-off-by: Trung Nguyen +Signed-off-by: Benjamin Tissoires +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-multitouch.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +--- a/drivers/hid/hid-multitouch.c ++++ b/drivers/hid/hid-multitouch.c +@@ -31,6 +31,7 @@ + * [1] https://gitlab.freedesktop.org/libevdev/hid-tools + */ + ++#include + #include + #include + #include +@@ -96,8 +97,7 @@ enum report_mode { + TOUCHPAD_REPORT_ALL = TOUCHPAD_REPORT_BUTTONS | TOUCHPAD_REPORT_CONTACTS, + }; + +-#define MT_IO_SLOTS_MASK GENMASK(7, 0) /* reserve first 8 bits for slot tracking */ +-#define MT_IO_FLAGS_RUNNING 32 ++#define MT_IO_FLAGS_RUNNING 0 + + static const bool mtrue = true; /* default for true */ + static const bool mfalse; /* default for false */ +@@ -173,10 +173,9 @@ struct mt_device { + struct timer_list release_timer; /* to release sticky fingers */ + struct hid_haptic_device *haptic; /* haptic related configuration */ + struct hid_device *hdev; /* hid_device we're attached to */ +- unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_RUNNING) +- * first 8 bits are reserved for keeping the slot +- * states, this is fine because we only support up +- * to 250 slots (MT_MAX_MAXCONTACT) ++ unsigned long mt_io_flags; /* mt flags (MT_IO_FLAGS_RUNNING) */ ++ unsigned long *active_slots; /* bitmap of slots with an active ++ * contact, sized for maxcontacts + */ + __u8 inputmode_value; /* InputMode HID feature value */ + __u8 maxcontacts; +@@ -1025,7 +1024,7 @@ static void mt_release_pending_palms(str + + for_each_set_bit(slotnum, app->pending_palm_slots, td->maxcontacts) { + clear_bit(slotnum, app->pending_palm_slots); +- clear_bit(slotnum, &td->mt_io_flags); ++ clear_bit(slotnum, td->active_slots); + + input_mt_slot(input, slotnum); + input_mt_report_slot_inactive(input); +@@ -1236,9 +1235,9 @@ static int mt_process_slot(struct mt_dev + input_event(input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); + input_event(input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); + +- set_bit(slotnum, &td->mt_io_flags); ++ set_bit(slotnum, td->active_slots); + } else { +- clear_bit(slotnum, &td->mt_io_flags); ++ clear_bit(slotnum, td->active_slots); + } + + return 0; +@@ -1373,7 +1372,7 @@ static void mt_touch_report(struct hid_d + * defect. + */ + if (app->quirks & MT_QUIRK_STICKY_FINGERS) { +- if (td->mt_io_flags & MT_IO_SLOTS_MASK) ++ if (!bitmap_empty(td->active_slots, td->maxcontacts)) + mod_timer(&td->release_timer, + jiffies + msecs_to_jiffies(100)); + else +@@ -1430,6 +1429,15 @@ static int mt_touch_input_configured(str + if (td->is_buttonpad) + __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); + ++ if (!td->active_slots) { ++ td->active_slots = devm_kcalloc(&td->hdev->dev, ++ BITS_TO_LONGS(td->maxcontacts), ++ sizeof(long), ++ GFP_KERNEL); ++ if (!td->active_slots) ++ return -ENOMEM; ++ } ++ + app->pending_palm_slots = devm_kcalloc(&hi->input->dev, + BITS_TO_LONGS(td->maxcontacts), + sizeof(long), +@@ -1907,7 +1915,7 @@ static void mt_release_contacts(struct h + for (i = 0; i < mt->num_slots; i++) { + input_mt_slot(input_dev, i); + input_mt_report_slot_inactive(input_dev); +- clear_bit(i, &td->mt_io_flags); ++ clear_bit(i, td->active_slots); + } + input_mt_sync_frame(input_dev); + input_sync(input_dev); +@@ -1930,7 +1938,7 @@ static void mt_expired_timeout(struct ti + */ + if (test_and_set_bit_lock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags)) + return; +- if (td->mt_io_flags & MT_IO_SLOTS_MASK) ++ if (!bitmap_empty(td->active_slots, td->maxcontacts)) + mt_release_contacts(hdev); + clear_bit_unlock(MT_IO_FLAGS_RUNNING, &td->mt_io_flags); + } diff --git a/queue-6.18/hid-pidff-use-correct-effect-type-in-effect-update.patch b/queue-6.18/hid-pidff-use-correct-effect-type-in-effect-update.patch new file mode 100644 index 0000000000..5fdc7b445b --- /dev/null +++ b/queue-6.18/hid-pidff-use-correct-effect-type-in-effect-update.patch @@ -0,0 +1,43 @@ +From b251598b8bf37300510868f739a79e07800d41ce Mon Sep 17 00:00:00 2001 +From: Oleg Makarenko +Date: Tue, 9 Jun 2026 19:00:27 +0300 +Subject: HID: pidff: Use correct effect type in effect update +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Oleg Makarenko + +commit b251598b8bf37300510868f739a79e07800d41ce upstream. + +When updating an existing effect, the effect type from the last created +effect was sent to the device instead of the updated one. +This caused incorrect reports when a game creates multiple different +effects and updates only one that is not the last created. + +Fixes FFB in multiple games that create multiple simultaneous effects +(Forza Horizon 5/6). + +Fixes: 224ee88fe395 ("Input: add force feedback driver for PID devices") +Cc: stable@vger.kernel.org +Tested-by: Oliver Roundtree +Co-developed-by: Ryno Kotzé +Signed-off-by: Ryno Kotzé +Signed-off-by: Oleg Makarenko +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/usbhid/hid-pidff.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hid/usbhid/hid-pidff.c ++++ b/drivers/hid/usbhid/hid-pidff.c +@@ -521,7 +521,7 @@ static void pidff_set_effect_report(stru + pidff->set_effect[PID_EFFECT_BLOCK_INDEX].value[0] = + pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]; + pidff->set_effect_type->value[0] = +- pidff->create_new_effect_type->value[0]; ++ pidff_get_effect_type_id(pidff, effect); + + pidff_set_duration(&pidff->set_effect[PID_DURATION], + effect->replay.length); diff --git a/queue-6.18/hid-sensor-hub-add-sensor_hub_input_attr_read_values-for-multi-byte-reads.patch b/queue-6.18/hid-sensor-hub-add-sensor_hub_input_attr_read_values-for-multi-byte-reads.patch new file mode 100644 index 0000000000..7f780e5d55 --- /dev/null +++ b/queue-6.18/hid-sensor-hub-add-sensor_hub_input_attr_read_values-for-multi-byte-reads.patch @@ -0,0 +1,179 @@ +From f784fcea450617055d2d12eec5b2f6e0e38bf878 Mon Sep 17 00:00:00 2001 +From: Srinivas Pandruvada +Date: Wed, 10 Jun 2026 16:29:09 +0800 +Subject: HID: sensor-hub: Add sensor_hub_input_attr_read_values() for multi-byte reads + +From: Srinivas Pandruvada + +commit f784fcea450617055d2d12eec5b2f6e0e38bf878 upstream. + +sensor_hub_input_attr_get_raw_value() is limited to returning a single +32-bit value, which is insufficient for sensors that report data larger +than 32 bits, such as a quaternion with four s16 elements. + +Add sensor_hub_input_attr_read_values() that accepts a caller-provided +buffer and accumulates incoming data until the buffer is full. The two +paths are distinguished in sensor_hub_raw_event() by pending.max_raw_size +being non-zero, preserving backward compatibility. + +Signed-off-by: Srinivas Pandruvada +Co-developed-by: Zhang Lixu +Signed-off-by: Zhang Lixu +Acked-by: Jiri Kosina +Reviewed-by: Andy Shevchenko +Cc: +Signed-off-by: Jonathan Cameron +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-sensor-hub.c | 77 +++++++++++++++++++++++++++++++++++++---- + include/linux/hid-sensor-hub.h | 25 +++++++++++++ + 2 files changed, 96 insertions(+), 6 deletions(-) + +--- a/drivers/hid/hid-sensor-hub.c ++++ b/drivers/hid/hid-sensor-hub.c +@@ -286,6 +286,54 @@ done_proc: + } + EXPORT_SYMBOL_GPL(sensor_hub_get_feature); + ++int sensor_hub_input_attr_read_values(struct hid_sensor_hub_device *hsdev, ++ u32 usage_id, u32 attr_usage_id, ++ u32 report_id, ++ enum sensor_hub_read_flags flag, ++ u32 buffer_size, u8 *buffer) ++{ ++ struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); ++ struct hid_report *report; ++ unsigned long flags; ++ long cycles; ++ int ret; ++ ++ report = sensor_hub_report(report_id, hsdev->hdev, HID_INPUT_REPORT); ++ if (!report) ++ return -EINVAL; ++ ++ mutex_lock(hsdev->mutex_ptr); ++ if (flag == SENSOR_HUB_SYNC) { ++ memset(&hsdev->pending, 0, sizeof(hsdev->pending)); ++ init_completion(&hsdev->pending.ready); ++ hsdev->pending.usage_id = usage_id; ++ hsdev->pending.attr_usage_id = attr_usage_id; ++ hsdev->pending.max_raw_size = buffer_size; ++ hsdev->pending.raw_data = buffer; ++ ++ spin_lock_irqsave(&data->lock, flags); ++ hsdev->pending.status = true; ++ spin_unlock_irqrestore(&data->lock, flags); ++ } ++ mutex_lock(&data->mutex); ++ hid_hw_request(hsdev->hdev, report, HID_REQ_GET_REPORT); ++ mutex_unlock(&data->mutex); ++ ret = 0; ++ if (flag == SENSOR_HUB_SYNC) { ++ cycles = wait_for_completion_interruptible_timeout(&hsdev->pending.ready, ++ HZ * 5); ++ if (cycles == 0) ++ ret = -ETIMEDOUT; ++ else if (cycles < 0) ++ ret = cycles; ++ ++ hsdev->pending.status = false; ++ } ++ mutex_unlock(hsdev->mutex_ptr); ++ ++ return ret; ++} ++EXPORT_SYMBOL_GPL(sensor_hub_input_attr_read_values); + + int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, + u32 usage_id, +@@ -480,6 +528,8 @@ static int sensor_hub_raw_event(struct h + struct hid_collection *collection = NULL; + void *priv = NULL; + struct hid_sensor_hub_device *hsdev = NULL; ++ u32 copy_size; ++ u32 avail; + + hid_dbg(hdev, "sensor_hub_raw_event report id:0x%x size:%d type:%d\n", + report->id, size, report->type); +@@ -520,12 +570,27 @@ static int sensor_hub_raw_event(struct h + hsdev->pending.attr_usage_id == + report->field[i]->logical)) { + hid_dbg(hdev, "data was pending ...\n"); +- hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC); +- if (hsdev->pending.raw_data) +- hsdev->pending.raw_size = sz; +- else +- hsdev->pending.raw_size = 0; +- complete(&hsdev->pending.ready); ++ if (hsdev->pending.max_raw_size) { ++ if (hsdev->pending.index < hsdev->pending.max_raw_size) { ++ avail = hsdev->pending.max_raw_size - hsdev->pending.index; ++ copy_size = clamp(sz, 0U, avail); ++ ++ memcpy(hsdev->pending.raw_data + hsdev->pending.index, ++ ptr, copy_size); ++ hsdev->pending.index += copy_size; ++ if (hsdev->pending.index >= hsdev->pending.max_raw_size) { ++ hsdev->pending.raw_size = hsdev->pending.index; ++ complete(&hsdev->pending.ready); ++ } ++ } ++ } else { ++ hsdev->pending.raw_data = kmemdup(ptr, sz, GFP_ATOMIC); ++ if (hsdev->pending.raw_data) ++ hsdev->pending.raw_size = sz; ++ else ++ hsdev->pending.raw_size = 0; ++ complete(&hsdev->pending.ready); ++ } + } + if (callback->capture_sample) { + if (report->field[i]->logical) +--- a/include/linux/hid-sensor-hub.h ++++ b/include/linux/hid-sensor-hub.h +@@ -43,6 +43,8 @@ struct hid_sensor_hub_attribute_info { + * @attr_usage_id: Usage Id of a field, e.g. X-axis for a gyro. + * @raw_size: Response size for a read request. + * @raw_data: Place holder for received response. ++ * @index: Current write index into raw_data for multi-byte reads. ++ * @max_raw_size: Total buffer size for multi-byte reads; 0 for single-value reads. + */ + struct sensor_hub_pending { + bool status; +@@ -51,6 +53,8 @@ struct sensor_hub_pending { + u32 attr_usage_id; + int raw_size; + u8 *raw_data; ++ u32 index; ++ u32 max_raw_size; + }; + + /** +@@ -184,6 +188,27 @@ int sensor_hub_input_attr_get_raw_value( + ); + + /** ++ * sensor_hub_input_attr_read_values() - Synchronous multi-byte read request ++ * @hsdev: Hub device instance. ++ * @usage_id: Attribute usage id of parent physical device as per spec ++ * @attr_usage_id: Attribute usage id as per spec ++ * @report_id: Report id to look for ++ * @flag: Synchronous or asynchronous read ++ * @buffer_size: Size of the buffer in bytes ++ * @buffer: Buffer to store the read data ++ * ++ * Issues a synchronous or asynchronous read request for an input attribute, ++ * accumulating data into the provided buffer until it is full. ++ * Return: 0 on success, -ETIMEDOUT if the device did not respond, or a ++ * negative error code. ++ */ ++int sensor_hub_input_attr_read_values(struct hid_sensor_hub_device *hsdev, ++ u32 usage_id, u32 attr_usage_id, ++ u32 report_id, ++ enum sensor_hub_read_flags flag, ++ u32 buffer_size, u8 *buffer); ++ ++/** + * sensor_hub_set_feature() - Feature set request + * @hsdev: Hub device instance. + * @report_id: Report id to look for diff --git a/queue-6.18/hid-uhid-convert-to-hid_safe_input_report.patch b/queue-6.18/hid-uhid-convert-to-hid_safe_input_report.patch new file mode 100644 index 0000000000..e8108a440c --- /dev/null +++ b/queue-6.18/hid-uhid-convert-to-hid_safe_input_report.patch @@ -0,0 +1,69 @@ +From 63a694c51bf120a37550890b8e7736b4888985e9 Mon Sep 17 00:00:00 2001 +From: Carlos Llamas +Date: Sat, 6 Jun 2026 18:15:52 +0000 +Subject: HID: uhid: convert to hid_safe_input_report() + +From: Carlos Llamas + +commit 63a694c51bf120a37550890b8e7736b4888985e9 upstream. + +Commit 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing +bogus memset()"), added a check in hid_report_raw_event() to reject +reports if the received data size is smaller than expected. This was +intended to prevent OOB errors by no longer allowing zeroing-out of +shorter reports due to the lack of buffer size information. + +However, this leads to regressions in hid_report_raw_event(), where +shorter than expected reports are rejected, even though their buffers +are sufficiently large to be zero-padded. + +To solve this issue, Benjamin introduced a safer alternative in commit +206342541fc8 ("HID: core: introduce hid_safe_input_report()"), which +forwards the buffer size and allows hid_report_raw_event() to safely +zero-pad the data. + +Convert uhid to use hid_safe_input_report() and pass UHID_DATA_MAX as +the buffer size. This prevents the reported regressions [1], allowing +hid core to zero-pad the shorter reports safely as expected. + +Cc: stable@vger.kernel.org +Fixes: 0a3fe972a7cb ("HID: core: Mitigate potential OOB by removing bogus memset()") +Closes: https://lore.kernel.org/all/ahsh0UtTX6e0ZeHa@google.com/ [1] +Signed-off-by: Carlos Llamas +Reviewed-by: Lee Jones +Closes: https://lore.kernel.org/all/ahsh0UtTX6e0ZeHa@google.com/ +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/uhid.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c +index 524b53a3c87b..37b60c3aaf66 100644 +--- a/drivers/hid/uhid.c ++++ b/drivers/hid/uhid.c +@@ -595,8 +595,8 @@ static int uhid_dev_input(struct uhid_device *uhid, struct uhid_event *ev) + if (!READ_ONCE(uhid->running)) + return -EINVAL; + +- hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input.data, +- min_t(size_t, ev->u.input.size, UHID_DATA_MAX), 0); ++ hid_safe_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input.data, UHID_DATA_MAX, ++ min_t(size_t, ev->u.input.size, UHID_DATA_MAX), 0); + + return 0; + } +@@ -606,8 +606,8 @@ static int uhid_dev_input2(struct uhid_device *uhid, struct uhid_event *ev) + if (!READ_ONCE(uhid->running)) + return -EINVAL; + +- hid_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input2.data, +- min_t(size_t, ev->u.input2.size, UHID_DATA_MAX), 0); ++ hid_safe_input_report(uhid->hid, HID_INPUT_REPORT, ev->u.input2.data, UHID_DATA_MAX, ++ min_t(size_t, ev->u.input2.size, UHID_DATA_MAX), 0); + + return 0; + } +-- +2.55.0 + diff --git a/queue-6.18/hid-wacom-fix-slab-out-of-bounds-write-in-wacom_wac_queue_insert.patch b/queue-6.18/hid-wacom-fix-slab-out-of-bounds-write-in-wacom_wac_queue_insert.patch new file mode 100644 index 0000000000..219439f4aa --- /dev/null +++ b/queue-6.18/hid-wacom-fix-slab-out-of-bounds-write-in-wacom_wac_queue_insert.patch @@ -0,0 +1,60 @@ +From 6b3014ec0e9a390ca563030b2d7689921f0daef5 Mon Sep 17 00:00:00 2001 +From: Jinmo Yang +Date: Fri, 29 May 2026 02:59:45 +0900 +Subject: HID: wacom: fix slab-out-of-bounds write in wacom_wac_queue_insert + +From: Jinmo Yang + +commit 6b3014ec0e9a390ca563030b2d7689921f0daef5 upstream. + +wacom_wac_queue_insert() calls kfifo_skip() in a loop when the kfifo +doesn't have enough space for the incoming report. If the kfifo is +empty, kfifo_skip() reads stale data left in the kmalloc'd buffer +via __kfifo_peek_n() and interprets it as a record length, advancing +fifo->out by that garbage value. This corrupts the internal kfifo +state, causing kfifo_unused() to return a value much larger than the +actual buffer size, which bypasses __kfifo_in_r()'s guard: + + if (len + recsize > kfifo_unused(fifo)) + return 0; + +kfifo_copy_in() then performs an out-of-bounds memcpy, writing up to +3842 bytes past the 256-byte buffer. + +Add a !kfifo_is_empty() condition to the while loop so kfifo_skip() +is never called on an empty fifo, and check the return value of +kfifo_in() to reject reports that are too large for the fifo. + +Suggested-by: Dmitry Torokhov +Fixes: 5e013ad20689 ("HID: wacom: Remove static WACOM_PKGLEN_MAX limit") +Cc: stable@vger.kernel.org +Signed-off-by: Jinmo Yang +Reviewed-by: Dmitry Torokhov +Signed-off-by: Benjamin Tissoires +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/wacom_sys.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/hid/wacom_sys.c ++++ b/drivers/hid/wacom_sys.c +@@ -54,7 +54,7 @@ static void wacom_wac_queue_insert(struc + { + bool warned = false; + +- while (kfifo_avail(fifo) < size) { ++ while (kfifo_avail(fifo) < size && !kfifo_is_empty(fifo)) { + if (!warned) + hid_warn(hdev, "%s: kfifo has filled, starting to drop events\n", __func__); + warned = true; +@@ -62,7 +62,9 @@ static void wacom_wac_queue_insert(struc + kfifo_skip(fifo); + } + +- kfifo_in(fifo, raw_data, size); ++ if (!kfifo_in(fifo, raw_data, size)) ++ hid_warn_ratelimited(hdev, "%s: report is too large (%d)\n", ++ __func__, size); + } + + static void wacom_wac_queue_flush(struct hid_device *hdev, diff --git a/queue-6.18/hid-wacom-stop-hardware-after-post-start-probe-failures.patch b/queue-6.18/hid-wacom-stop-hardware-after-post-start-probe-failures.patch new file mode 100644 index 0000000000..0bf50bce87 --- /dev/null +++ b/queue-6.18/hid-wacom-stop-hardware-after-post-start-probe-failures.patch @@ -0,0 +1,80 @@ +From ec2612b8ad9e642596db011dd8b6568ef1edeaa1 Mon Sep 17 00:00:00 2001 +From: Myeonghun Pak +Date: Thu, 4 Jun 2026 13:56:58 +0900 +Subject: HID: wacom: stop hardware after post-start probe failures + +From: Myeonghun Pak + +commit ec2612b8ad9e642596db011dd8b6568ef1edeaa1 upstream. + +wacom_parse_and_register() starts HID hardware before registering inputs +and initializing pad LEDs/remotes. Those later steps can fail, but their +error paths currently release Wacom resources without stopping the HID +hardware. + +Route post-hid_hw_start() failures through hid_hw_stop() before +releasing driver resources. + +This issue was identified during our ongoing static-analysis research while +reviewing kernel code. + +Fixes: c1d6708bf0d3 ("HID: wacom: Do not register input devices until after hid_hw_start") +Cc: stable@vger.kernel.org +Co-developed-by: Ijae Kim +Signed-off-by: Ijae Kim +Signed-off-by: Myeonghun Pak +Reviewed-by: Dmitry Torokhov +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/wacom_sys.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/drivers/hid/wacom_sys.c ++++ b/drivers/hid/wacom_sys.c +@@ -2462,16 +2462,16 @@ static int wacom_parse_and_register(stru + + error = wacom_register_inputs(wacom); + if (error) +- goto fail; ++ goto fail_hw_stop; + + if (wacom->wacom_wac.features.device_type & WACOM_DEVICETYPE_PAD) { + error = wacom_initialize_leds(wacom); + if (error) +- goto fail; ++ goto fail_hw_stop; + + error = wacom_initialize_remotes(wacom); + if (error) +- goto fail; ++ goto fail_hw_stop; + } + + if (!wireless) { +@@ -2485,14 +2485,14 @@ static int wacom_parse_and_register(stru + cancel_delayed_work_sync(&wacom->init_work); + _wacom_query_tablet_data(wacom); + error = -ENODEV; +- goto fail_quirks; ++ goto fail_hw_stop; + } + + if (features->device_type & WACOM_DEVICETYPE_WL_MONITOR) { + error = hid_hw_open(hdev); + if (error) { + hid_err(hdev, "hw open failed\n"); +- goto fail_quirks; ++ goto fail_hw_stop; + } + } + +@@ -2501,7 +2501,7 @@ static int wacom_parse_and_register(stru + + return 0; + +-fail_quirks: ++fail_hw_stop: + hid_hw_stop(hdev); + fail: + wacom_release_resources(wacom); diff --git a/queue-6.18/hid-wacom-use-gfp_atomic-in-wacom_wac_queue_flush.patch b/queue-6.18/hid-wacom-use-gfp_atomic-in-wacom_wac_queue_flush.patch new file mode 100644 index 0000000000..d13c778e68 --- /dev/null +++ b/queue-6.18/hid-wacom-use-gfp_atomic-in-wacom_wac_queue_flush.patch @@ -0,0 +1,43 @@ +From 55f1ad573e34abf9a0443c34bc5a63d74edba7d7 Mon Sep 17 00:00:00 2001 +From: Jinmo Yang +Date: Mon, 1 Jun 2026 22:41:23 +0900 +Subject: HID: wacom: use GFP_ATOMIC in wacom_wac_queue_flush() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Jinmo Yang + +commit 55f1ad573e34abf9a0443c34bc5a63d74edba7d7 upstream. + +wacom_wac_queue_flush() is called via the .raw_event callback +(wacom_raw_event → wacom_wac_pen_serial_enforce → wacom_wac_queue_flush). +For USB HID devices, this callback is invoked from hid_irq_in(), which +is a URB completion handler running in atomic context. Using GFP_KERNEL +in this path can sleep, leading to a "scheduling while atomic" bug. + +Use GFP_ATOMIC instead. The existing code already handles allocation +failure by skipping the fifo entry and continuing. + +Reported-by: Sashiko-bot +Fixes: 5e013ad20689 ("HID: wacom: Remove static WACOM_PKGLEN_MAX limit") +Cc: stable@vger.kernel.org +Reviewed-by: Dmitry Torokhov +Signed-off-by: Jinmo Yang +Signed-off-by: Benjamin Tissoires +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/wacom_sys.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/hid/wacom_sys.c ++++ b/drivers/hid/wacom_sys.c +@@ -76,7 +76,7 @@ static void wacom_wac_queue_flush(struct + unsigned int count; + int err; + +- buf = kzalloc(size, GFP_KERNEL); ++ buf = kzalloc(size, GFP_ATOMIC); + if (!buf) { + kfifo_skip(fifo); + continue; diff --git a/queue-6.18/libfs-set-sb_i_noexec-and-sb_i_nodev-by-default-in-init_pseudo.patch b/queue-6.18/libfs-set-sb_i_noexec-and-sb_i_nodev-by-default-in-init_pseudo.patch new file mode 100644 index 0000000000..bb6671167e --- /dev/null +++ b/queue-6.18/libfs-set-sb_i_noexec-and-sb_i_nodev-by-default-in-init_pseudo.patch @@ -0,0 +1,56 @@ +From 6de2aeffabaafaeda819e60ec8d04f199711e11a Mon Sep 17 00:00:00 2001 +From: John Hubbard +Date: Wed, 3 Jun 2026 19:53:14 -0700 +Subject: libfs: set SB_I_NOEXEC and SB_I_NODEV by default in init_pseudo() + +From: John Hubbard + +commit 6de2aeffabaafaeda819e60ec8d04f199711e11a upstream. + +Since commit 1e7ab6f67824 ("anon_inode: rework assertions"), +path_noexec() warns when an anonymous-inode file is mmap'd from a +superblock that has not set SB_I_NOEXEC. dma-buf backs its files this +way and never set the flag, so mmap of any exported buffer trips the +warning on a CONFIG_DEBUG_VFS=y kernel: + + WARNING: CPU: 11 PID: 121813 at fs/exec.c:118 path_noexec+0x47/0x50 + do_mmap+0x2b5/0x680 + vm_mmap_pgoff+0x129/0x210 + ksys_mmap_pgoff+0x177/0x240 + __x64_sys_mmap+0x33/0x70 + +init_pseudo() sets up internal SB_NOUSER mounts that are never +path-reachable. Set both flags here so every pseudo filesystem gets +them by default instead of each caller setting them. + +SB_I_NODEV is inert for unreachable mounts. SB_I_NOEXEC has one +visible effect: an executable mapping of a pseudo-fs fd, such as a +dma-buf, now fails with -EPERM, which is the invariant the assertion +enforces. No in-tree caller maps these executable. + +Reproduce on CONFIG_DEBUG_VFS=y: + + make -C tools/testing/selftests/dmabuf-heaps + sudo ./tools/testing/selftests/dmabuf-heaps/dmabuf-heap -t system + +Fixes: 1e7ab6f67824 ("anon_inode: rework assertions") +Suggested-by: Christoph Hellwig +Cc: stable@vger.kernel.org +Signed-off-by: John Hubbard +Link: https://patch.msgid.link/20260604025315.245910-2-jhubbard@nvidia.com +Signed-off-by: Christian Brauner (Amutable) +Signed-off-by: Greg Kroah-Hartman +--- + fs/libfs.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/fs/libfs.c ++++ b/fs/libfs.c +@@ -721,6 +721,7 @@ struct pseudo_fs_context *init_pseudo(st + fc->fs_private = ctx; + fc->ops = &pseudo_fs_context_ops; + fc->sb_flags |= SB_NOUSER; ++ fc->s_iflags |= SB_I_NOEXEC | SB_I_NODEV; + fc->global = true; + } + return ctx; diff --git a/queue-6.18/mm-slab-do-not-limit-zeroing-to-orig_size-when-only-red-zoning-is-enabled.patch b/queue-6.18/mm-slab-do-not-limit-zeroing-to-orig_size-when-only-red-zoning-is-enabled.patch new file mode 100644 index 0000000000..7135d0d76a --- /dev/null +++ b/queue-6.18/mm-slab-do-not-limit-zeroing-to-orig_size-when-only-red-zoning-is-enabled.patch @@ -0,0 +1,67 @@ +From 648927ceb84021a25a0fbd5673740956f318d534 Mon Sep 17 00:00:00 2001 +From: "Vlastimil Babka (SUSE)" +Date: Wed, 10 Jun 2026 17:40:03 +0200 +Subject: mm/slab: do not limit zeroing to orig_size when only red zoning is enabled + +From: Vlastimil Babka (SUSE) + +commit 648927ceb84021a25a0fbd5673740956f318d534 upstream. + +When init (zeroing) on allocation is requested, for kmalloc() we +generally have to zero the full object size even if a smaller size is +requested, in order to provide krealloc()'s __GFP_ZERO guarantees. + +But if we track the requested size, krealloc() uses that information to +do the right thing, so we can zero only the requested size. With red +zoning also enabled, any extra size became part of the red zone, so it +must not be zeroed and thus we must zero only the requested size. + +However the current check is imprecise, and will trigger also when only +SLAB_RED_ZONE is enabled without SLAB_STORE_USER (which enables tracking +the requested size). This means enabling red zoning alone can compromise +krealloc()'s __GFP_ZERO contract. + +Fix this by using slub_debug_orig_size() instead, which is the exact +check for whether the requested size is tracked. We don't need to care +if red zoning is also enabled or not. Also update and expand the +comment accordingly. + +Fixes: 9ce67395f5a0 ("mm/slub: only zero requested size of buffer for kzalloc when debug enabled") +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260610-slab_alloc_flags-v2-1-7190909db118@kernel.org +Reviewed-by: Harry Yoo (Oracle) +Reviewed-by: Hao Li +Signed-off-by: Vlastimil Babka (SUSE) +Signed-off-by: Greg Kroah-Hartman +--- + mm/slub.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -5004,15 +5004,17 @@ bool slab_post_alloc_hook(struct kmem_ca + gfp_t init_flags = flags & gfp_allowed_mask; + + /* +- * For kmalloc object, the allocated memory size(object_size) is likely +- * larger than the requested size(orig_size). If redzone check is +- * enabled for the extra space, don't zero it, as it will be redzoned +- * soon. The redzone operation for this extra space could be seen as a +- * replacement of current poisoning under certain debug option, and +- * won't break other sanity checks. ++ * For kmalloc object, the allocated size (object_size) can be larger ++ * than the requested size (orig_size). We however need to zero the ++ * whole object_size to handle possible later krealloc() with ++ *__GFP_ZERO properly. ++ * ++ * But if we keep track of the requested size, krealloc() uses that ++ * information. Additionally if red zoning is enabled, the extra space ++ * is also red zone, so we should not overwrite it. So limit zeroing to ++ * orig_size if we track it. + */ +- if (kmem_cache_debug_flags(s, SLAB_STORE_USER | SLAB_RED_ZONE) && +- (s->flags & SLAB_KMALLOC)) ++ if (slub_debug_orig_size(s)) + zero_size = orig_size; + + /* diff --git a/queue-6.18/opp-of-fix-potential-memory-leak-in-opp_parse_supplies.patch b/queue-6.18/opp-of-fix-potential-memory-leak-in-opp_parse_supplies.patch new file mode 100644 index 0000000000..958ca45f85 --- /dev/null +++ b/queue-6.18/opp-of-fix-potential-memory-leak-in-opp_parse_supplies.patch @@ -0,0 +1,41 @@ +From 69f888381d2ecbe18ed9f112c096f8fd3623db98 Mon Sep 17 00:00:00 2001 +From: Abdun Nihaal +Date: Mon, 11 May 2026 12:12:11 +0530 +Subject: OPP: of: Fix potential memory leak in opp_parse_supplies() + +From: Abdun Nihaal + +commit 69f888381d2ecbe18ed9f112c096f8fd3623db98 upstream. + +The memory allocated for microvolt, microamp and microwatt is not freed +in one of the paths in opp_parse_supplies() which returns directly. +Fix that by adding a goto to the error unwind ladder. + +Fixes: 2eedf62e66c2 ("OPP: decouple dt properties in opp_parse_supplies()") +Cc: stable@vger.kernel.org +Signed-off-by: Abdun Nihaal +Signed-off-by: Viresh Kumar +Signed-off-by: Greg Kroah-Hartman +--- + drivers/opp/of.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/opp/of.c ++++ b/drivers/opp/of.c +@@ -669,7 +669,7 @@ static int opp_parse_supplies(struct dev + */ + if (unlikely(opp_table->regulator_count == -1)) { + opp_table->regulator_count = 0; +- return 0; ++ goto free_microwatt; + } + + for (i = 0, j = 0; i < opp_table->regulator_count; i++) { +@@ -692,6 +692,7 @@ static int opp_parse_supplies(struct dev + opp->supplies[i].u_watt = microwatt[i]; + } + ++free_microwatt: + kfree(microwatt); + free_microamp: + kfree(microamp); diff --git a/queue-6.18/perf-arm-cmn-fix-dvm-node-events.patch b/queue-6.18/perf-arm-cmn-fix-dvm-node-events.patch new file mode 100644 index 0000000000..de4df9532e --- /dev/null +++ b/queue-6.18/perf-arm-cmn-fix-dvm-node-events.patch @@ -0,0 +1,65 @@ +From 5936245125f78d896fdb1bbc2ae79213e28a6579 Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Fri, 29 May 2026 15:33:45 +0100 +Subject: perf/arm-cmn: Fix DVM node events + +From: Robin Murphy + +commit 5936245125f78d896fdb1bbc2ae79213e28a6579 upstream. + +The new DVM node events added in CMN-700 also apply to CMN S3; fix +the model encoding so that we can expose the aliases and handle +occupancy filtering on newer CMNs too. + +Cc: stable@vger.kernel.org +Fixes: 0dc2f4963f7e ("perf/arm-cmn: Support CMN S3") +Signed-off-by: Robin Murphy +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman +--- + drivers/perf/arm-cmn.c | 23 ++++++++++++----------- + 1 file changed, 12 insertions(+), 11 deletions(-) + +--- a/drivers/perf/arm-cmn.c ++++ b/drivers/perf/arm-cmn.c +@@ -197,13 +197,14 @@ + enum cmn_model { + CMN600 = 1, + CMN650 = 2, +- CMN700 = 4, +- CI700 = 8, ++ CI700 = 4, ++ CMN700 = 8, + CMNS3 = 16, + /* ...and then we can use bitmap tricks for commonality */ + CMN_ANY = -1, + NOT_CMN600 = -2, +- CMN_650ON = CMN650 | CMN700 | CMNS3, ++ CMN_700ON = ~(CMN700 - 1), ++ CMN_650ON = CMN_700ON | CMN650, + }; + + /* Actual part numbers and revision IDs defined by the hardware */ +@@ -919,14 +920,14 @@ static struct attribute *arm_cmn_event_a + CMN_EVENT_DVM(NOT_CMN600, txsnp_stall, 0x0a), + CMN_EVENT_DVM(NOT_CMN600, trkfull, 0x0b), + CMN_EVENT_DVM_OCC(NOT_CMN600, trk_occupancy, 0x0c), +- CMN_EVENT_DVM_OCC(CMN700, trk_occupancy_cxha, 0x0d), +- CMN_EVENT_DVM_OCC(CMN700, trk_occupancy_pdn, 0x0e), +- CMN_EVENT_DVM(CMN700, trk_alloc, 0x0f), +- CMN_EVENT_DVM(CMN700, trk_cxha_alloc, 0x10), +- CMN_EVENT_DVM(CMN700, trk_pdn_alloc, 0x11), +- CMN_EVENT_DVM(CMN700, txsnp_stall_limit, 0x12), +- CMN_EVENT_DVM(CMN700, rxsnp_stall_starv, 0x13), +- CMN_EVENT_DVM(CMN700, txsnp_sync_stall_op, 0x14), ++ CMN_EVENT_DVM_OCC(CMN_700ON, trk_occupancy_cxha, 0x0d), ++ CMN_EVENT_DVM_OCC(CMN_700ON, trk_occupancy_pdn, 0x0e), ++ CMN_EVENT_DVM(CMN_700ON, trk_alloc, 0x0f), ++ CMN_EVENT_DVM(CMN_700ON, trk_cxha_alloc, 0x10), ++ CMN_EVENT_DVM(CMN_700ON, trk_pdn_alloc, 0x11), ++ CMN_EVENT_DVM(CMN_700ON, txsnp_stall_limit, 0x12), ++ CMN_EVENT_DVM(CMN_700ON, rxsnp_stall_starv, 0x13), ++ CMN_EVENT_DVM(CMN_700ON, txsnp_sync_stall_op, 0x14), + + CMN_EVENT_HNF(CMN_ANY, cache_miss, 0x01), + CMN_EVENT_HNF(CMN_ANY, slc_sf_cache_access, 0x02), diff --git a/queue-6.18/perf-x86-intel-uncore-defer-adl-global-pmon-enable-to-enable_box.patch b/queue-6.18/perf-x86-intel-uncore-defer-adl-global-pmon-enable-to-enable_box.patch new file mode 100644 index 0000000000..4842691496 --- /dev/null +++ b/queue-6.18/perf-x86-intel-uncore-defer-adl-global-pmon-enable-to-enable_box.patch @@ -0,0 +1,52 @@ +From 9a0bb848a37150aeccc10088e141339917d995dc Mon Sep 17 00:00:00 2001 +From: Zide Chen +Date: Tue, 2 Jun 2026 07:49:05 -0700 +Subject: perf/x86/intel/uncore: Defer ADL global PMON enable to enable_box() + +From: Zide Chen + +commit 9a0bb848a37150aeccc10088e141339917d995dc upstream. + +On some Raptor Cove CPUs, enabling uncore PMON globally at driver init +may increase power consumption even when no perf events are in use. + +Drop adl_uncore_msr_init_box() and defer programming the global control +register to enable_box(), so it is only set when a box is actually used. + +IMC and IMC freerunning counters use a separate control path and are +unaffected. + +Fixes: 772ed05f3c5c ("perf/x86/intel/uncore: Add Alder Lake support") +Signed-off-by: Zide Chen +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Dapeng Mi +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260602144908.263680-5-zide.chen@intel.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/events/intel/uncore_snb.c | 7 ------- + 1 file changed, 7 deletions(-) + +--- a/arch/x86/events/intel/uncore_snb.c ++++ b/arch/x86/events/intel/uncore_snb.c +@@ -539,12 +539,6 @@ void tgl_uncore_cpu_init(void) + skl_uncore_msr_ops.init_box = rkl_uncore_msr_init_box; + } + +-static void adl_uncore_msr_init_box(struct intel_uncore_box *box) +-{ +- if (box->pmu->pmu_idx == 0) +- wrmsrq(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN); +-} +- + static void adl_uncore_msr_enable_box(struct intel_uncore_box *box) + { + wrmsrq(ADL_UNC_PERF_GLOBAL_CTL, SNB_UNC_GLOBAL_CTL_EN); +@@ -563,7 +557,6 @@ static void adl_uncore_msr_exit_box(stru + } + + static struct intel_uncore_ops adl_uncore_msr_ops = { +- .init_box = adl_uncore_msr_init_box, + .enable_box = adl_uncore_msr_enable_box, + .disable_box = adl_uncore_msr_disable_box, + .exit_box = adl_uncore_msr_exit_box, diff --git a/queue-6.18/posix-cpu-timers-fix-pid-refcount-leak-in-do_cpu_nanosleep-error-path.patch b/queue-6.18/posix-cpu-timers-fix-pid-refcount-leak-in-do_cpu_nanosleep-error-path.patch new file mode 100644 index 0000000000..9476d5a91d --- /dev/null +++ b/queue-6.18/posix-cpu-timers-fix-pid-refcount-leak-in-do_cpu_nanosleep-error-path.patch @@ -0,0 +1,40 @@ +From 87bd2ad568e15b90d5f7d4bcd70342d05dad649c Mon Sep 17 00:00:00 2001 +From: WenTao Liang +Date: Fri, 12 Jun 2026 00:17:38 +0800 +Subject: posix-cpu-timers: Fix pid refcount leak in do_cpu_nanosleep() error path + +From: WenTao Liang + +commit 87bd2ad568e15b90d5f7d4bcd70342d05dad649c upstream. + +In do_cpu_nanosleep(), posix_cpu_timer_create() takes a pid reference +via get_pid() and stores it in timer.it.cpu.pid. If the subsequent +posix_cpu_timer_set() call fails, the function returns immediately +without calling posix_cpu_timer_del() to release the pid reference, +causing a leak. + +Fix it by calling posix_cpu_timer_del() before the unlock-and-return +on the error path, consistent with the other exit paths in the same +function. + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Signed-off-by: WenTao Liang +Signed-off-by: Thomas Gleixner +Reviewed-by: Frederic Weisbecker +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260611161738.97043-1-vulab@iscas.ac.cn +Signed-off-by: Greg Kroah-Hartman +--- + kernel/time/posix-cpu-timers.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/kernel/time/posix-cpu-timers.c ++++ b/kernel/time/posix-cpu-timers.c +@@ -1504,6 +1504,7 @@ static int do_cpu_nanosleep(const clocki + spin_lock_irq(&timer.it_lock); + error = posix_cpu_timer_set(&timer, flags, &it, NULL); + if (error) { ++ posix_cpu_timer_del(&timer); + spin_unlock_irq(&timer.it_lock); + return error; + } diff --git a/queue-6.18/s390-revert-support-for-dcache_word_access.patch b/queue-6.18/s390-revert-support-for-dcache_word_access.patch new file mode 100644 index 0000000000..aede9153b5 --- /dev/null +++ b/queue-6.18/s390-revert-support-for-dcache_word_access.patch @@ -0,0 +1,141 @@ +From 37540b8c287fc817bdbd0c62bb75ad6eab0e5d03 Mon Sep 17 00:00:00 2001 +From: Heiko Carstens +Date: Thu, 11 Jun 2026 17:37:46 +0200 +Subject: s390: Revert support for DCACHE_WORD_ACCESS + +From: Heiko Carstens + +commit 37540b8c287fc817bdbd0c62bb75ad6eab0e5d03 upstream. + +load_unaligned_zeropad() reads eight bytes from unaligned addresses and may +cross page boundaries. It handles exceptions which may happen if reading +from the second page results in an exception. + +For pages which are donated to the Ultravisor for secure execution purposes +the do_secure_storage_access() exception handler however does not handle +such exceptions correctly. Such an exception may result in an endless +exception loop which will never be resolved. + +An attempt to fix this [1] turned out to be not sufficient. For now revert +load_unaligned_zeropad() until this problem has been resolved in a proper +way. + +Note that the implementation of load_unaligned_zeropad() itself is +correct. The revert is just a temporary workaround until there is complete +fix for secure storage access exceptions. + +[1] commit b00be77302d7 ("s390/mm: Add missing secure storage access fixups for donated memory") + +Fixes: 802ba53eefc5 ("s390: add support for DCACHE_WORD_ACCESS") +Cc: stable@vger.kernel.org +Acked-by: Christian Borntraeger +Signed-off-by: Heiko Carstens +Signed-off-by: Alexander Gordeev +Signed-off-by: Greg Kroah-Hartman +--- + arch/s390/Kconfig | 1 - + arch/s390/include/asm/asm-extable.h | 4 ---- + arch/s390/include/asm/word-at-a-time.h | 22 ---------------------- + arch/s390/mm/extable.c | 18 ------------------ + 4 files changed, 45 deletions(-) + +--- a/arch/s390/Kconfig ++++ b/arch/s390/Kconfig +@@ -161,7 +161,6 @@ config S390 + select ARCH_WANTS_THP_SWAP + select BUILDTIME_TABLE_SORT + select CLONE_BACKWARDS2 +- select DCACHE_WORD_ACCESS if !KMSAN + select DYNAMIC_FTRACE if FUNCTION_TRACER + select FUNCTION_ALIGNMENT_8B if CC_IS_GCC + select FUNCTION_ALIGNMENT_16B if !CC_IS_GCC +--- a/arch/s390/include/asm/asm-extable.h ++++ b/arch/s390/include/asm/asm-extable.h +@@ -12,7 +12,6 @@ + #define EX_TYPE_UA_FAULT 3 + #define EX_TYPE_UA_LOAD_REG 5 + #define EX_TYPE_UA_LOAD_REGPAIR 6 +-#define EX_TYPE_ZEROPAD 7 + #define EX_TYPE_FPC 8 + #define EX_TYPE_UA_MVCOS_TO 9 + #define EX_TYPE_UA_MVCOS_FROM 10 +@@ -80,9 +79,6 @@ + #define EX_TABLE_UA_LOAD_REGPAIR(_fault, _target, _regerr, _regzero) \ + __EX_TABLE(__ex_table, _fault, _target, EX_TYPE_UA_LOAD_REGPAIR, _regerr, _regzero, 0) + +-#define EX_TABLE_ZEROPAD(_fault, _target, _regdata, _regaddr) \ +- __EX_TABLE(__ex_table, _fault, _target, EX_TYPE_ZEROPAD, _regdata, _regaddr, 0) +- + #define EX_TABLE_FPC(_fault, _target) \ + __EX_TABLE(__ex_table, _fault, _target, EX_TYPE_FPC, __stringify(%%r0), __stringify(%%r0), 0) + +--- a/arch/s390/include/asm/word-at-a-time.h ++++ b/arch/s390/include/asm/word-at-a-time.h +@@ -4,7 +4,6 @@ + + #include + #include +-#include + #include + + struct word_at_a_time { +@@ -41,25 +40,4 @@ static inline unsigned long zero_bytemas + return ~1UL << data; + } + +-/* +- * Load an unaligned word from kernel space. +- * +- * In the (very unlikely) case of the word being a page-crosser +- * and the next page not being mapped, take the exception and +- * return zeroes in the non-existing part. +- */ +-static inline unsigned long load_unaligned_zeropad(const void *addr) +-{ +- unsigned long data; +- +- asm_inline volatile( +- "0: lg %[data],0(%[addr])\n" +- "1: nopr %%r7\n" +- EX_TABLE_ZEROPAD(0b, 1b, %[data], %[addr]) +- EX_TABLE_ZEROPAD(1b, 1b, %[data], %[addr]) +- : [data] "=d" (data) +- : [addr] "a" (addr), "m" (*(unsigned long *)addr)); +- return data; +-} +- + #endif /* _ASM_WORD_AT_A_TIME_H */ +--- a/arch/s390/mm/extable.c ++++ b/arch/s390/mm/extable.c +@@ -50,22 +50,6 @@ static bool ex_handler_ua_load_reg(const + return true; + } + +-static bool ex_handler_zeropad(const struct exception_table_entry *ex, struct pt_regs *regs) +-{ +- unsigned int reg_addr = FIELD_GET(EX_DATA_REG_ADDR, ex->data); +- unsigned int reg_data = FIELD_GET(EX_DATA_REG_ERR, ex->data); +- unsigned long data, addr, offset; +- +- addr = regs->gprs[reg_addr]; +- offset = addr & (sizeof(unsigned long) - 1); +- addr &= ~(sizeof(unsigned long) - 1); +- data = *(unsigned long *)addr; +- data <<= BITS_PER_BYTE * offset; +- regs->gprs[reg_data] = data; +- regs->psw.addr = extable_fixup(ex); +- return true; +-} +- + static bool ex_handler_fpc(const struct exception_table_entry *ex, struct pt_regs *regs) + { + fpu_sfpc(0); +@@ -134,8 +118,6 @@ bool fixup_exception(struct pt_regs *reg + return ex_handler_ua_load_reg(ex, false, regs); + case EX_TYPE_UA_LOAD_REGPAIR: + return ex_handler_ua_load_reg(ex, true, regs); +- case EX_TYPE_ZEROPAD: +- return ex_handler_zeropad(ex, regs); + case EX_TYPE_FPC: + return ex_handler_fpc(ex, regs); + case EX_TYPE_UA_MVCOS_TO: diff --git a/queue-6.18/sched-rt-have-rt_push_ipi-be-default-off-for-non-preempt_rt.patch b/queue-6.18/sched-rt-have-rt_push_ipi-be-default-off-for-non-preempt_rt.patch new file mode 100644 index 0000000000..57433f7dd0 --- /dev/null +++ b/queue-6.18/sched-rt-have-rt_push_ipi-be-default-off-for-non-preempt_rt.patch @@ -0,0 +1,100 @@ +From dd29c017aed628076e915fe4cdfb5392fd4c5cab Mon Sep 17 00:00:00 2001 +From: Steven Rostedt +Date: Fri, 15 May 2026 10:37:40 -0400 +Subject: sched/rt: Have RT_PUSH_IPI be default off for non PREEMPT_RT + +From: Steven Rostedt + +commit dd29c017aed628076e915fe4cdfb5392fd4c5cab upstream. + +RT migration is done aggressively. When a CPU schedules out a high +priority RT task for a lower priority task, it will look to see if there's +any RT tasks that are waiting to run on another CPU that is of higher +priority than the task this CPU is about to run. If it finds one, it will +pull that task over to the CPU and allow it to run there instead. + +Normally, this pulling is done by looking at the RT overloaded mask (rto) +which contains all the CPUs in the scheduler domain with RT tasks that are +waiting to run due to a higher priority RT task currently running on their +CPU. The CPU that is about to schedule a lower priority task will grab the +rq lock of the overloaded CPU and move the RT task from that CPU's runqueue +to the local one and schedule the higher priority RT task. + +This caused issues when a lot of CPUs would schedule a lower priority task +at the same time. They would all try to grab the same runqueue lock of +the CPU with the overloaded RT tasks. Only the first CPU that got in will +get that task. All the others would wait until they got the runqueue lock +and see there's nothing to pull and do nothing. On systems with lots of +CPUs, this caused a large latency (up to 500us) which is beyond what +PREEMPT_RT is to allow. + +The solution to that was to create an RT_PUSH_IPI logic. When any CPU +wanted to pull a task, instead of grabbing the runqueue lock of the +overloaded CPU, it would start by sending an IPI to the overloaded CPU, +and that IPI handler would have the CPU with the waiting RT task do a push +instead. Then that handler would send an IPI to the next CPU with +overloaded RT tasks, and so on. Note, after the first CPU starts this +process, if another CPU wanted to do a pull, it would see that the process +has already begun and would only increment a counter to have the IPIs +continue again. + +The RT_PUSH_IPI solved the latency problem with PREEMPT_RT but could cause +a new issue with non PREEMPT_RT. Namely, softirqs run in a threaded +context on PREEMPT_RT but they can run in an interrupt context in non-RT. + +If an IPI lands on a CPU that has just woken up multiple RT tasks and the +current CPU is running a non RT or a low priority RT task, instead of +doing a push, it would simply do a schedule on that CPU. But if a softirq +was also executing on this CPU, the schedule would need to wait until the +softirq finished. Until then, the CPU would still be considered overloaded +as there are RT tasks still waiting to run on it. + +A live lock occurred on a workload that was doing heavy networking traffic +on a large machine where the softirqs would run 500us out of 750us. And it +would also be waking up RT tasks, causing the RT pull logic to be +constantly executed. + +When a softirq triggered on a CPU with RT tasks queued but not running +yet, and the other CPUs would see this CPU as being overloaded, they would +send an IPI over to it. The CPU would notice that the waiting RT tasks are +of higher priority than the currently running task and simply schedule +that CPU instead. But because the softirq was executing, before it could +schedule, it would receive another IPI to do the same. The amount of IPIs +would slow down the currently running softirq so much that before it could +return back to task context, it would execute another softirq never +allowing the CPU to schedule. This live locked that CPU. + +As RT_PUSH_IPI was created to help PREEMPT_RT, make it default off if +PREEMPT_RT is not enabled. + +Fixes: b6366f048e0c ("sched/rt: Use IPI to trigger RT task push migration instead of pulling") +Closes: https://lore.kernel.org/all/20260506235716.2530720-1-tj@kernel.org/ +Reported-by: Tejun Heo +Signed-off-by: Steven Rostedt +Signed-off-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/20260515103740.25ccbed8@gandalf.local.home +Signed-off-by: Greg Kroah-Hartman +--- + kernel/sched/features.h | 8 ++++++++ + 1 file changed, 8 insertions(+) + +--- a/kernel/sched/features.h ++++ b/kernel/sched/features.h +@@ -103,8 +103,16 @@ SCHED_FEAT(WARN_DOUBLE_CLOCK, false) + * rq lock and possibly create a large contention, sending an + * IPI to that CPU and let that CPU push the RT task to where + * it should go may be a better scenario. ++ * ++ * This is best for PREEMPT_RT, but for non-RT it can cause issues ++ * when preemption is disabled for long periods of time. Have ++ * it only default enabled for PREEMPT_RT. + */ ++# ifdef CONFIG_PREEMPT_RT + SCHED_FEAT(RT_PUSH_IPI, true) ++# else ++SCHED_FEAT(RT_PUSH_IPI, false) ++# endif + #endif + + SCHED_FEAT(RT_RUNTIME_SHARE, false) diff --git a/queue-6.18/series b/queue-6.18/series index 719b6a4208..b8438fa253 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -237,3 +237,33 @@ smb-client-use-unaligned-reads-in-parse_posix_ctxt.patch smb-client-harden-posix-sid-length-parsing.patch smb-client-fix-atime-clamp-check-in-read-completion.patch smb-client-mask-server-provided-mode-to-07777-in-modefromsid.patch +writeback-fix-race-between-cgroup_writeback_umount-and-inode_switch_wbs.patch +opp-of-fix-potential-memory-leak-in-opp_parse_supplies.patch +cpufreq-qcom-cpufreq-hw-fix-possible-double-free.patch +firmware_loader-fix-device-reference-leak-in-firmware_upload_register.patch +libfs-set-sb_i_noexec-and-sb_i_nodev-by-default-in-init_pseudo.patch +perf-x86-intel-uncore-defer-adl-global-pmon-enable-to-enable_box.patch +cpufreq-intel_pstate-sync-policy-cur-during-cpu-offline.patch +sched-rt-have-rt_push_ipi-be-default-off-for-non-preempt_rt.patch +cpufreq-fix-hotplug-suspend-race-during-reboot.patch +cpufreq-pcc-fix-use-after-free-and-double-free-in-_osc-evaluation.patch +posix-cpu-timers-fix-pid-refcount-leak-in-do_cpu_nanosleep-error-path.patch +time-jiffies-register-jiffies-clocksource-before-usage.patch +clocksource-drivers-timer-tegra186-fix-support-for-multiple-watchdog-instances.patch +s390-revert-support-for-dcache_word_access.patch +perf-arm-cmn-fix-dvm-node-events.patch +x.509-fix-validation-of-asn.1-certificate-header.patch +mm-slab-do-not-limit-zeroing-to-orig_size-when-only-red-zoning-is-enabled.patch +tools-mm-slabinfo-fix-trace-disable-logic-inversion.patch +tools-mm-slabinfo-fix-total_objects-attribute-name.patch +hid-hid-goodix-spi-validate-report-size-to-prevent-stack-buffer-overflow.patch +hid-uhid-convert-to-hid_safe_input_report.patch +hid-wacom-stop-hardware-after-post-start-probe-failures.patch +hid-pidff-use-correct-effect-type-in-effect-update.patch +hid-wacom-fix-slab-out-of-bounds-write-in-wacom_wac_queue_insert.patch +hid-wacom-use-gfp_atomic-in-wacom_wac_queue_flush.patch +hid-letsketch-fix-uaf-on-inrange_timer-at-driver-unbind.patch +hid-multitouch-fix-out-of-bounds-bit-access-on-mt_io_flags.patch +hid-appleir-fix-uaf-on-pending-key_up_timer-in-remove.patch +hid-lg-g15-cancel-pending-work-on-remove-to-fix-a-use-after-free.patch +hid-sensor-hub-add-sensor_hub_input_attr_read_values-for-multi-byte-reads.patch diff --git a/queue-6.18/time-jiffies-register-jiffies-clocksource-before-usage.patch b/queue-6.18/time-jiffies-register-jiffies-clocksource-before-usage.patch new file mode 100644 index 0000000000..d9cd14e49d --- /dev/null +++ b/queue-6.18/time-jiffies-register-jiffies-clocksource-before-usage.patch @@ -0,0 +1,53 @@ +From f24df84cbe05e4471c04ac4b921fc0340bbc7752 Mon Sep 17 00:00:00 2001 +From: Thomas Gleixner +Date: Tue, 9 Jun 2026 17:14:45 +0200 +Subject: time/jiffies: Register jiffies clocksource before usage + +From: Thomas Gleixner + +commit f24df84cbe05e4471c04ac4b921fc0340bbc7752 upstream. + +Teddy reported that a XEN HVM has a long boot delay, which was bisected to +the recent enhancements to the negative motion detection. It turned out +that the jiffies clocksource is used in early boot before it is registered, +which leaves the max_delta_raw field at zero. That causes the read out to +be clamped to the max delta of 0, which means time is not making progress. + +Cure it by ensuring that it is initialized before its first usage in +timekeeping_init(). + +Fixes: 76031d9536a0 ("clocksource: Make negative motion detection more robust") +Reported-by: Teddy Astie +Signed-off-by: Thomas Gleixner +Tested-by: Teddy Astie +Cc: stable@vger.kernel.org +Link: https://patch.msgid.link/87y0gn3fve.ffs@fw13 +Closes: https://lore.kernel.org/all/1780914594.8631fc262581453bbf619ec5b2062170.19ea6c8227b000701b@vates.tech +Signed-off-by: Greg Kroah-Hartman +--- + kernel/time/jiffies.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +--- a/kernel/time/jiffies.c ++++ b/kernel/time/jiffies.c +@@ -61,15 +61,14 @@ EXPORT_SYMBOL(get_jiffies_64); + + EXPORT_SYMBOL(jiffies); + +-static int __init init_jiffies_clocksource(void) +-{ +- return __clocksource_register(&clocksource_jiffies); +-} +- +-core_initcall(init_jiffies_clocksource); ++static bool cs_jiffies_registered __initdata; + + struct clocksource * __init __weak clocksource_default_clock(void) + { ++ if (!cs_jiffies_registered) { ++ __clocksource_register(&clocksource_jiffies); ++ cs_jiffies_registered = true; ++ } + return &clocksource_jiffies; + } + diff --git a/queue-6.18/tools-mm-slabinfo-fix-total_objects-attribute-name.patch b/queue-6.18/tools-mm-slabinfo-fix-total_objects-attribute-name.patch new file mode 100644 index 0000000000..865c425977 --- /dev/null +++ b/queue-6.18/tools-mm-slabinfo-fix-total_objects-attribute-name.patch @@ -0,0 +1,46 @@ +From 892a7864730775c3dbee2a39e9ead4fa8d4256e7 Mon Sep 17 00:00:00 2001 +From: Yichong Chen +Date: Fri, 12 Jun 2026 15:13:59 +0800 +Subject: tools/mm/slabinfo: fix total_objects attribute name + +From: Yichong Chen + +commit 892a7864730775c3dbee2a39e9ead4fa8d4256e7 upstream. + +SLUB exports the total_objects sysfs attribute, but slabinfo tries to read +objects_total. As a result, the lookup fails and the field remains zero. + +Use the correct attribute name and rename the corresponding structure +member to match. + +Fixes: 205ab99dd103 ("slub: Update statistics handling for variable order slabs") +Signed-off-by: Yichong Chen +Cc: +Reviewed-by: SeongJae Park +Link: https://patch.msgid.link/96556748872BB47E+20260612071359.649946-1-chenyichong@uniontech.com +Signed-off-by: Vlastimil Babka (SUSE) +Signed-off-by: Greg Kroah-Hartman +--- + tools/mm/slabinfo.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/tools/mm/slabinfo.c ++++ b/tools/mm/slabinfo.c +@@ -33,7 +33,7 @@ struct slabinfo { + unsigned int hwcache_align, object_size, objs_per_slab; + unsigned int sanity_checks, slab_size, store_user, trace; + int order, poison, reclaim_account, red_zone; +- unsigned long partial, objects, slabs, objects_partial, objects_total; ++ unsigned long partial, objects, slabs, objects_partial, total_objects; + unsigned long alloc_fastpath, alloc_slowpath; + unsigned long free_fastpath, free_slowpath; + unsigned long free_frozen, free_add_partial, free_remove_partial; +@@ -1263,7 +1263,7 @@ static void read_slab_dir(void) + slab->object_size = get_obj("object_size"); + slab->objects = get_obj("objects"); + slab->objects_partial = get_obj("objects_partial"); +- slab->objects_total = get_obj("objects_total"); ++ slab->total_objects = get_obj("total_objects"); + slab->objs_per_slab = get_obj("objs_per_slab"); + slab->order = get_obj("order"); + slab->partial = get_obj("partial"); diff --git a/queue-6.18/tools-mm-slabinfo-fix-trace-disable-logic-inversion.patch b/queue-6.18/tools-mm-slabinfo-fix-trace-disable-logic-inversion.patch new file mode 100644 index 0000000000..77d3d84ed8 --- /dev/null +++ b/queue-6.18/tools-mm-slabinfo-fix-trace-disable-logic-inversion.patch @@ -0,0 +1,36 @@ +From 235ab68d67eadbef1fdbfb771f21f5bacc77a2ae Mon Sep 17 00:00:00 2001 +From: Xuewen Wang +Date: Mon, 18 May 2026 14:21:57 +0800 +Subject: tools/mm/slabinfo: Fix trace disable logic inversion + +From: Xuewen Wang + +commit 235ab68d67eadbef1fdbfb771f21f5bacc77a2ae upstream. + +The disable trace path in slab_debug() had a logic error where it would +set trace=1 instead of trace=0. This made trace functionality permanently +enabled once turned on for any slab cache. + +Fixes: a87615b8f9e2 ("SLUB: slabinfo upgrade") +Cc: stable@vger.kernel.org +Reviewed-by: SeongJae Park +Signed-off-by: Xuewen Wang +WARNING: From:/Signed-off-by: email address mismatch: 'From: wangxuewen <18810879172@163.com>' != 'Signed-off-by: wangxuewen ' +Link: https://patch.msgid.link/20260518062159.80664-2-wangxuewen@kylinos.cn +Signed-off-by: Vlastimil Babka (SUSE) +Signed-off-by: Greg Kroah-Hartman +--- + tools/mm/slabinfo.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/tools/mm/slabinfo.c ++++ b/tools/mm/slabinfo.c +@@ -798,7 +798,7 @@ static void slab_debug(struct slabinfo * + fprintf(stderr, "%s can only enable trace for one slab at a time\n", s->name); + } + if (!tracing && s->trace) +- set_obj(s, "trace", 1); ++ set_obj(s, "trace", 0); + } + + static void totals(void) diff --git a/queue-6.18/writeback-fix-race-between-cgroup_writeback_umount-and-inode_switch_wbs.patch b/queue-6.18/writeback-fix-race-between-cgroup_writeback_umount-and-inode_switch_wbs.patch new file mode 100644 index 0000000000..7cdf583f1b --- /dev/null +++ b/queue-6.18/writeback-fix-race-between-cgroup_writeback_umount-and-inode_switch_wbs.patch @@ -0,0 +1,177 @@ +From cba38ec4cbd3a7b8b942a8d52531a05be8a9ff0d Mon Sep 17 00:00:00 2001 +From: Baokun Li +Date: Thu, 21 May 2026 17:50:14 +0800 +Subject: writeback: fix race between cgroup_writeback_umount() and inode_switch_wbs() + +From: Baokun Li + +commit cba38ec4cbd3a7b8b942a8d52531a05be8a9ff0d upstream. + +When a container exits, the following BUG_ON() is occasionally triggered: + +================================================================== + VFS: Busy inodes after unmount of sdb (ext4) + ------------[ cut here ]------------ + kernel BUG at fs/super.c:695! + CPU: 3 PID: 6 Comm: containerd-shim Tainted: G OE K 6.6 #1 + pstate: 63400009 (nZCv daif +PAN -UAO +TCO +DIT -SSBS BTYPE=--) + pc : generic_shutdown_super+0xf0/0x100 + lr : generic_shutdown_super+0xf0/0x100 + Call trace: + generic_shutdown_super+0xf0/0x100 + kill_block_super+0x20/0x48 + ext4_kill_sb+0x28/0x60 + deactivate_locked_super+0x54/0x130 + deactivate_super+0x84/0xa0 + cleanup_mnt+0xa4/0x140 + __cleanup_mnt+0x18/0x28 + task_work_run+0x78/0xe0 + do_notify_resume+0x204/0x240 +================================================================== + +The root cause is a race between cgroup_writeback_umount() and +inode_switch_wbs()/cleanup_offline_cgwb(). There is a window between +inode_prepare_wbs_switch() returning true and the subsequent +wb_queue_isw() call. Following is the process that triggers the issue: + + CPU A (umount) | CPU B (writeback) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + inode_switch_wbs/cleanup_offline_cgwb + atomic_inc(&isw_nr_in_flight) + inode_prepare_wbs_switch + -> passes SB_ACTIVE check + __iget(inode) + generic_shutdown_super + sb->s_flags &= ~SB_ACTIVE + cgroup_writeback_umount(sb) + smp_mb() + atomic_read(&isw_nr_in_flight) + rcu_barrier() + -> no pending RCU callbacks + flush_workqueue(isw_wq) + -> nothing queued, returns + evict_inodes(sb) + -> Inode skipped as isw still holds a ref. + sop->put_super(sb) + /* destroys percpu counters */ + -> VFS: Busy inodes after unmount! + wb_queue_isw() + queue_work(isw_wq, ...) + /* later in work function */ + inode_switch_wbs_work_fn + process_inode_switch_wbs + iput() -> evict + percpu_counter_dec() // UAF! + +Fix this by extending the RCU read-side critical section in +inode_switch_wbs() and cleanup_offline_cgwb() to cover from +inode_prepare_wbs_switch() through wb_queue_isw(). Since there is +no sleep in this window, rcu_read_lock() can be used. Then add a +synchronize_rcu() in cgroup_writeback_umount() before the existing +rcu_barrier(), so that all in-flight switchers that have passed the +SB_ACTIVE check have completed queue_work() before flush_workqueue() +is called. + +The existing rcu_barrier() is intentionally retained so this fix can +be backported unchanged to stable kernels (5.10.y, 6.6.y, ...) that +still queue switches via queue_rcu_work(). It is a no-op on current +mainline (since commit e1b849cfa6b6 ("writeback: Avoid contention on +wb->list_lock when switching inodes")) and is removed in a follow-up +patch. + +Fixes: a1a0e23e4903 ("writeback: flush inode cgroup wb switches instead of pinning super_block") +Cc: stable@vger.kernel.org +Suggested-by: Jan Kara +Link: https://lore.kernel.org/all/mxnjq2l6guusfchvauxr3v7c4bwjasybxlleqbbh4efloeqspz@iqylk76ohufz +Reviewed-by: Jan Kara +Signed-off-by: Baokun Li +Link: https://patch.msgid.link/20260521095016.2791354-2-libaokun@linux.alibaba.com +Acked-by: Tejun Heo +Signed-off-by: Christian Brauner (Amutable) +Signed-off-by: Greg Kroah-Hartman +--- + fs/fs-writeback.c | 31 +++++++++++++++++++++++++++++-- + 1 file changed, 29 insertions(+), 2 deletions(-) + +--- a/fs/fs-writeback.c ++++ b/fs/fs-writeback.c +@@ -650,12 +650,19 @@ static void inode_switch_wbs(struct inod + + atomic_inc(&isw_nr_in_flight); + +- /* find and pin the new wb */ ++ /* ++ * Paired with synchronize_rcu() in cgroup_writeback_umount(): ++ * holding rcu_read_lock across inode_prepare_wbs_switch() ++ * (covering the SB_ACTIVE check and the inode grab) and ++ * wb_queue_isw() ensures synchronize_rcu() cannot return until ++ * the work is queued, so the subsequent flush_workqueue() will ++ * wait for the switch. ++ */ + rcu_read_lock(); ++ /* find and pin the new wb */ + memcg_css = css_from_id(new_wb_id, &memory_cgrp_subsys); + if (memcg_css && !css_tryget(memcg_css)) + memcg_css = NULL; +- rcu_read_unlock(); + if (!memcg_css) + goto out_free; + +@@ -671,9 +678,11 @@ static void inode_switch_wbs(struct inod + + trace_inode_switch_wbs_queue(inode->i_wb, new_wb, 1); + wb_queue_isw(new_wb, isw); ++ rcu_read_unlock(); + return; + + out_free: ++ rcu_read_unlock(); + atomic_dec(&isw_nr_in_flight); + if (new_wb) + wb_put(new_wb); +@@ -732,6 +741,14 @@ bool cleanup_offline_cgwb(struct bdi_wri + new_wb = &wb->bdi->wb; /* wb_get() is noop for bdi's wb */ + + nr = 0; ++ /* ++ * Paired with synchronize_rcu() in cgroup_writeback_umount(). ++ * Holding rcu_read_lock across the SB_ACTIVE check, the inode grab ++ * and wb_queue_isw() ensures synchronize_rcu() cannot return until ++ * the work is queued, so the subsequent flush_workqueue() will wait ++ * for the switch. ++ */ ++ rcu_read_lock(); + spin_lock(&wb->list_lock); + /* + * In addition to the inodes that have completed writeback, also switch +@@ -749,6 +766,7 @@ bool cleanup_offline_cgwb(struct bdi_wri + + /* no attached inodes? bail out */ + if (nr == 0) { ++ rcu_read_unlock(); + atomic_dec(&isw_nr_in_flight); + wb_put(new_wb); + kfree(isw); +@@ -757,6 +775,7 @@ bool cleanup_offline_cgwb(struct bdi_wri + + trace_inode_switch_wbs_queue(wb, new_wb, nr); + wb_queue_isw(new_wb, isw); ++ rcu_read_unlock(); + + return restart; + } +@@ -1211,6 +1230,14 @@ void cgroup_writeback_umount(struct supe + + if (atomic_read(&isw_nr_in_flight)) { + /* ++ * Paired with rcu_read_lock() in inode_switch_wbs() and ++ * cleanup_offline_cgwb(). synchronize_rcu() waits for any ++ * in-flight switcher that already passed the SB_ACTIVE check ++ * to finish queueing its work, so flush_workqueue() below ++ * will then drain it. ++ */ ++ synchronize_rcu(); ++ /* + * Use rcu_barrier() to wait for all pending callbacks to + * ensure that all in-flight wb switches are in the workqueue. + */ diff --git a/queue-6.18/x.509-fix-validation-of-asn.1-certificate-header.patch b/queue-6.18/x.509-fix-validation-of-asn.1-certificate-header.patch new file mode 100644 index 0000000000..ec56166c9a --- /dev/null +++ b/queue-6.18/x.509-fix-validation-of-asn.1-certificate-header.patch @@ -0,0 +1,40 @@ +From 3b626ba431c4501512ad07549310685e07fe4706 Mon Sep 17 00:00:00 2001 +From: Lukas Wunner +Date: Thu, 14 May 2026 08:55:58 +0200 +Subject: X.509: Fix validation of ASN.1 certificate header + +From: Lukas Wunner + +commit 3b626ba431c4501512ad07549310685e07fe4706 upstream. + +x509_load_certificate_list() seeks to enforce that a certificate starts +with 0x30 0x82 (ASN.1 SEQUENCE tag followed by a length of more than 256 +and less than 65535 bytes). + +But it only enforces that *either* of those two byte values are present, +instead of checking for the *conjunction* of the two values. Fix it. + +Fixes: 631cc66eb9ea ("MODSIGN: Provide module signing public keys to the kernel") +Reported-by: Sashiko +Closes: https://lore.kernel.org/r/20260508033917.B5873C2BCB0@smtp.kernel.org/ +Signed-off-by: Lukas Wunner +Cc: stable@vger.kernel.org # v3.7+ +Reviewed-by: Ignat Korchagin +Reviewed-by: Alistair Francis +Signed-off-by: Herbert Xu +Signed-off-by: Greg Kroah-Hartman +--- + crypto/asymmetric_keys/x509_loader.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/crypto/asymmetric_keys/x509_loader.c ++++ b/crypto/asymmetric_keys/x509_loader.c +@@ -20,7 +20,7 @@ int x509_load_certificate_list(const u8 + */ + if (end - p < 4) + goto dodgy_cert; +- if (p[0] != 0x30 && ++ if (p[0] != 0x30 || + p[1] != 0x82) + goto dodgy_cert; + plen = (p[2] << 8) | p[3];