From: Greg Kroah-Hartman Date: Tue, 2 Dec 2025 15:54:13 +0000 (+0100) Subject: 6.17-stable patches X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4a07da4d4013c1ae040d31a2481a94dc8eea8377;p=thirdparty%2Fkernel%2Fstable-queue.git 6.17-stable patches added patches: mm-swap-remove-duplicate-nr_swap_pages-decrement-in-get_swap_page_of_type.patch usb-gadget-udc-fix-use-after-free-in-usb_gadget_state_work.patch usb-udc-add-trace-event-for-usb_gadget_set_state.patch --- diff --git a/queue-6.17/mm-swap-remove-duplicate-nr_swap_pages-decrement-in-get_swap_page_of_type.patch b/queue-6.17/mm-swap-remove-duplicate-nr_swap_pages-decrement-in-get_swap_page_of_type.patch new file mode 100644 index 0000000000..172b47c11a --- /dev/null +++ b/queue-6.17/mm-swap-remove-duplicate-nr_swap_pages-decrement-in-get_swap_page_of_type.patch @@ -0,0 +1,58 @@ +From stable+bounces-198015-greg=kroah.com@vger.kernel.org Tue Dec 2 00:53:36 2025 +From: Sasha Levin +Date: Mon, 1 Dec 2025 18:53:26 -0500 +Subject: mm: swap: remove duplicate nr_swap_pages decrement in get_swap_page_of_type() +To: stable@vger.kernel.org +Cc: Youngjun Park , Chris Li , Barry Song , Kairui Song , Nhat Pham , Baoquan He , Kemeng Shi , Andrew Morton , Sasha Levin +Message-ID: <20251201235326.1315049-1-sashal@kernel.org> + +From: Youngjun Park + +[ Upstream commit f5e31a196edcd1f1bb44f26b6f9299b9a5b9b3c4 ] + +After commit 4f78252da887, nr_swap_pages is decremented in +swap_range_alloc(). Since cluster_alloc_swap_entry() calls +swap_range_alloc() internally, the decrement in get_swap_page_of_type() +causes double-decrementing. + +As a representative userspace-visible runtime example of the impact, +/proc/meminfo reports increasingly inaccurate SwapFree values. The +discrepancy grows with each swap allocation, and during hibernation +when large amounts of memory are written to swap, the reported value +can deviate significantly from actual available swap space, misleading +users and monitoring tools. + +Remove the duplicate decrement. + +Link: https://lkml.kernel.org/r/20251102082456.79807-1-youngjun.park@lge.com +Fixes: 4f78252da887 ("mm: swap: move nr_swap_pages counter decrement from folio_alloc_swap() to swap_range_alloc()") +Signed-off-by: Youngjun Park +Acked-by: Chris Li +Reviewed-by: Barry Song +Reviewed-by: Kairui Song +Acked-by: Nhat Pham +Cc: Baoquan He +Cc: Kemeng Shi +Cc: [6.17+] +Signed-off-by: Andrew Morton +[ adjusted context ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + mm/swapfile.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/mm/swapfile.c ++++ b/mm/swapfile.c +@@ -1866,10 +1866,8 @@ swp_entry_t get_swap_page_of_type(int ty + if (get_swap_device_info(si)) { + if (si->flags & SWP_WRITEOK) { + offset = cluster_alloc_swap_entry(si, 0, 1); +- if (offset) { ++ if (offset) + entry = swp_entry(si->type, offset); +- atomic_long_dec(&nr_swap_pages); +- } + } + put_swap_device(si); + } diff --git a/queue-6.17/series b/queue-6.17/series index 5a09a0f034..0a47ca6049 100644 --- a/queue-6.17/series +++ b/queue-6.17/series @@ -139,3 +139,6 @@ net-dsa-microchip-fix-symetry-in-ksz_ptp_msg_irq_-setup-free.patch libceph-fix-potential-use-after-free-in-have_mon_and_osd_map.patch libceph-prevent-potential-out-of-bounds-writes-in-handle_auth_session_key.patch libceph-replace-bug_on-with-bounds-check-for-map-max_osd.patch +mm-swap-remove-duplicate-nr_swap_pages-decrement-in-get_swap_page_of_type.patch +usb-udc-add-trace-event-for-usb_gadget_set_state.patch +usb-gadget-udc-fix-use-after-free-in-usb_gadget_state_work.patch diff --git a/queue-6.17/usb-gadget-udc-fix-use-after-free-in-usb_gadget_state_work.patch b/queue-6.17/usb-gadget-udc-fix-use-after-free-in-usb_gadget_state_work.patch new file mode 100644 index 0000000000..888fbeaa46 --- /dev/null +++ b/queue-6.17/usb-gadget-udc-fix-use-after-free-in-usb_gadget_state_work.patch @@ -0,0 +1,116 @@ +From stable+bounces-198029-greg=kroah.com@vger.kernel.org Tue Dec 2 02:44:01 2025 +From: Sasha Levin +Date: Mon, 1 Dec 2025 20:43:45 -0500 +Subject: usb: gadget: udc: fix use-after-free in usb_gadget_state_work +To: stable@vger.kernel.org +Cc: Jimmy Hu , stable , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251202014345.1598525-2-sashal@kernel.org> + +From: Jimmy Hu + +[ Upstream commit baeb66fbd4201d1c4325074e78b1f557dff89b5b ] + +A race condition during gadget teardown can lead to a use-after-free +in usb_gadget_state_work(), as reported by KASAN: + + BUG: KASAN: invalid-access in sysfs_notify+0x2c/0xd0 + Workqueue: events usb_gadget_state_work + +The fundamental race occurs because a concurrent event (e.g., an +interrupt) can call usb_gadget_set_state() and schedule gadget->work +at any time during the cleanup process in usb_del_gadget(). + +Commit 399a45e5237c ("usb: gadget: core: flush gadget workqueue after +device removal") attempted to fix this by moving flush_work() to after +device_del(). However, this does not fully solve the race, as a new +work item can still be scheduled *after* flush_work() completes but +before the gadget's memory is freed, leading to the same use-after-free. + +This patch fixes the race condition robustly by introducing a 'teardown' +flag and a 'state_lock' spinlock to the usb_gadget struct. The flag is +set during cleanup in usb_del_gadget() *before* calling flush_work() to +prevent any new work from being scheduled once cleanup has commenced. +The scheduling site, usb_gadget_set_state(), now checks this flag under +the lock before queueing the work, thus safely closing the race window. + +Fixes: 5702f75375aa9 ("usb: gadget: udc-core: move sysfs_notify() to a workqueue") +Cc: stable +Signed-off-by: Jimmy Hu +Link: https://patch.msgid.link/20251023054945.233861-1-hhhuuu@google.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/core.c | 17 ++++++++++++++++- + include/linux/usb/gadget.h | 5 +++++ + 2 files changed, 21 insertions(+), 1 deletion(-) + +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -1126,8 +1126,13 @@ static void usb_gadget_state_work(struct + void usb_gadget_set_state(struct usb_gadget *gadget, + enum usb_device_state state) + { ++ unsigned long flags; ++ ++ spin_lock_irqsave(&gadget->state_lock, flags); + gadget->state = state; +- schedule_work(&gadget->work); ++ if (!gadget->teardown) ++ schedule_work(&gadget->work); ++ spin_unlock_irqrestore(&gadget->state_lock, flags); + trace_usb_gadget_set_state(gadget, 0); + } + EXPORT_SYMBOL_GPL(usb_gadget_set_state); +@@ -1361,6 +1366,8 @@ static void usb_udc_nop_release(struct d + void usb_initialize_gadget(struct device *parent, struct usb_gadget *gadget, + void (*release)(struct device *dev)) + { ++ spin_lock_init(&gadget->state_lock); ++ gadget->teardown = false; + INIT_WORK(&gadget->work, usb_gadget_state_work); + gadget->dev.parent = parent; + +@@ -1535,6 +1542,7 @@ EXPORT_SYMBOL_GPL(usb_add_gadget_udc); + void usb_del_gadget(struct usb_gadget *gadget) + { + struct usb_udc *udc = gadget->udc; ++ unsigned long flags; + + if (!udc) + return; +@@ -1548,6 +1556,13 @@ void usb_del_gadget(struct usb_gadget *g + kobject_uevent(&udc->dev.kobj, KOBJ_REMOVE); + sysfs_remove_link(&udc->dev.kobj, "gadget"); + device_del(&gadget->dev); ++ /* ++ * Set the teardown flag before flushing the work to prevent new work ++ * from being scheduled while we are cleaning up. ++ */ ++ spin_lock_irqsave(&gadget->state_lock, flags); ++ gadget->teardown = true; ++ spin_unlock_irqrestore(&gadget->state_lock, flags); + flush_work(&gadget->work); + ida_free(&gadget_id_numbers, gadget->id_number); + cancel_work_sync(&udc->vbus_work); +--- a/include/linux/usb/gadget.h ++++ b/include/linux/usb/gadget.h +@@ -376,6 +376,9 @@ struct usb_gadget_ops { + * can handle. The UDC must support this and all slower speeds and lower + * number of lanes. + * @state: the state we are now (attached, suspended, configured, etc) ++ * @state_lock: Spinlock protecting the `state` and `teardown` members. ++ * @teardown: True if the device is undergoing teardown, used to prevent ++ * new work from being scheduled during cleanup. + * @name: Identifies the controller hardware type. Used in diagnostics + * and sometimes configuration. + * @dev: Driver model state for this abstract device. +@@ -451,6 +454,8 @@ struct usb_gadget { + enum usb_ssp_rate max_ssp_rate; + + enum usb_device_state state; ++ spinlock_t state_lock; ++ bool teardown; + const char *name; + struct device dev; + unsigned isoch_delay; diff --git a/queue-6.17/usb-udc-add-trace-event-for-usb_gadget_set_state.patch b/queue-6.17/usb-udc-add-trace-event-for-usb_gadget_set_state.patch new file mode 100644 index 0000000000..f6e7087742 --- /dev/null +++ b/queue-6.17/usb-udc-add-trace-event-for-usb_gadget_set_state.patch @@ -0,0 +1,54 @@ +From stable+bounces-198028-greg=kroah.com@vger.kernel.org Tue Dec 2 02:43:58 2025 +From: Sasha Levin +Date: Mon, 1 Dec 2025 20:43:44 -0500 +Subject: usb: udc: Add trace event for usb_gadget_set_state +To: stable@vger.kernel.org +Cc: Kuen-Han Tsai , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251202014345.1598525-1-sashal@kernel.org> + +From: Kuen-Han Tsai + +[ Upstream commit 7bf1158514e410310aec975e630cec99d4e4092f ] + +While the userspace program can be notified of gadget state changes, +timing issue can lead to missed transitions when reading the state +value. + +Introduce a trace event for usb_gadget_set_state to reliably track state +transitions. + +Signed-off-by: Kuen-Han Tsai +Link: https://lore.kernel.org/r/20250818082722.2952867-1-khtsai@google.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: baeb66fbd420 ("usb: gadget: udc: fix use-after-free in usb_gadget_state_work") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/usb/gadget/udc/core.c | 1 + + drivers/usb/gadget/udc/trace.h | 5 +++++ + 2 files changed, 6 insertions(+) + +--- a/drivers/usb/gadget/udc/core.c ++++ b/drivers/usb/gadget/udc/core.c +@@ -1128,6 +1128,7 @@ void usb_gadget_set_state(struct usb_gad + { + gadget->state = state; + schedule_work(&gadget->work); ++ trace_usb_gadget_set_state(gadget, 0); + } + EXPORT_SYMBOL_GPL(usb_gadget_set_state); + +--- a/drivers/usb/gadget/udc/trace.h ++++ b/drivers/usb/gadget/udc/trace.h +@@ -81,6 +81,11 @@ DECLARE_EVENT_CLASS(udc_log_gadget, + __entry->ret) + ); + ++DEFINE_EVENT(udc_log_gadget, usb_gadget_set_state, ++ TP_PROTO(struct usb_gadget *g, int ret), ++ TP_ARGS(g, ret) ++); ++ + DEFINE_EVENT(udc_log_gadget, usb_gadget_frame_number, + TP_PROTO(struct usb_gadget *g, int ret), + TP_ARGS(g, ret)