From: Greg Kroah-Hartman Date: Sun, 12 Apr 2026 05:19:31 +0000 (+0200) Subject: 5.10-stable patches X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5df8f74c3685964539f1cd3deaaf10708ef26c34;p=thirdparty%2Fkernel%2Fstable-queue.git 5.10-stable patches added patches: input-uinput-fix-circular-locking-dependency-with-ff-core.patch input-uinput-take-event-lock-when-submitting-ff-request-event.patch lib-crypto-chacha-zeroize-permuted_state-before-it-leaves-scope.patch wifi-rt2x00usb-fix-devres-lifetime.patch xfrm_user-fix-info-leak-in-build_report.patch --- diff --git a/queue-5.10/input-uinput-fix-circular-locking-dependency-with-ff-core.patch b/queue-5.10/input-uinput-fix-circular-locking-dependency-with-ff-core.patch new file mode 100644 index 0000000000..873d0363b3 --- /dev/null +++ b/queue-5.10/input-uinput-fix-circular-locking-dependency-with-ff-core.patch @@ -0,0 +1,158 @@ +From 4cda78d6f8bf2b700529f2fbccb994c3e826d7c2 Mon Sep 17 00:00:00 2001 +From: Mikhail Gavrilov +Date: Tue, 7 Apr 2026 12:50:31 +0500 +Subject: Input: uinput - fix circular locking dependency with ff-core + +From: Mikhail Gavrilov + +commit 4cda78d6f8bf2b700529f2fbccb994c3e826d7c2 upstream. + +A lockdep circular locking dependency warning can be triggered +reproducibly when using a force-feedback gamepad with uinput (for +example, playing ELDEN RING under Wine with a Flydigi Vader 5 +controller): + + ff->mutex -> udev->mutex -> input_mutex -> dev->mutex -> ff->mutex + +The cycle is caused by four lock acquisition paths: + +1. ff upload: input_ff_upload() holds ff->mutex and calls + uinput_dev_upload_effect() -> uinput_request_submit() -> + uinput_request_send(), which acquires udev->mutex. + +2. device create: uinput_ioctl_handler() holds udev->mutex and calls + uinput_create_device() -> input_register_device(), which acquires + input_mutex. + +3. device register: input_register_device() holds input_mutex and + calls kbd_connect() -> input_register_handle(), which acquires + dev->mutex. + +4. evdev release: evdev_release() calls input_flush_device() under + dev->mutex, which calls input_ff_flush() acquiring ff->mutex. + +Fix this by introducing a new state_lock spinlock to protect +udev->state and udev->dev access in uinput_request_send() instead of +acquiring udev->mutex. The function only needs to atomically check +device state and queue an input event into the ring buffer via +uinput_dev_event() -- both operations are safe under a spinlock +(ktime_get_ts64() and wake_up_interruptible() do not sleep). This +breaks the ff->mutex -> udev->mutex link since a spinlock is a leaf in +the lock ordering and cannot form cycles with mutexes. + +To keep state transitions visible to uinput_request_send(), protect +writes to udev->state in uinput_create_device() and +uinput_destroy_device() with the same state_lock spinlock. + +Additionally, move init_completion(&request->done) from +uinput_request_send() to uinput_request_submit() before +uinput_request_reserve_slot(). Once the slot is allocated, +uinput_flush_requests() may call complete() on it at any time from +the destroy path, so the completion must be initialised before the +request becomes visible. + +Lock ordering after the fix: + + ff->mutex -> state_lock (spinlock, leaf) + udev->mutex -> state_lock (spinlock, leaf) + udev->mutex -> input_mutex -> dev->mutex -> ff->mutex (no back-edge) + +Fixes: ff462551235d ("Input: uinput - switch to the new FF interface") +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/all/CABXGCsMoxag+kEwHhb7KqhuyxfmGGd0P=tHZyb1uKE0pLr8Hkg@mail.gmail.com/ +Signed-off-by: Mikhail Gavrilov +Link: https://patch.msgid.link/20260407075031.38351-1-mikhail.v.gavrilov@gmail.com +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/uinput.c | 28 +++++++++++++++++++++------- + 1 file changed, 21 insertions(+), 7 deletions(-) + +--- a/drivers/input/misc/uinput.c ++++ b/drivers/input/misc/uinput.c +@@ -56,6 +56,7 @@ struct uinput_device { + struct input_dev *dev; + struct mutex mutex; + enum uinput_state state; ++ spinlock_t state_lock; + wait_queue_head_t waitq; + unsigned char ready; + unsigned char head; +@@ -145,19 +146,15 @@ static void uinput_request_release_slot( + static int uinput_request_send(struct uinput_device *udev, + struct uinput_request *request) + { +- int retval; ++ int retval = 0; + +- retval = mutex_lock_interruptible(&udev->mutex); +- if (retval) +- return retval; ++ spin_lock(&udev->state_lock); + + if (udev->state != UIST_CREATED) { + retval = -ENODEV; + goto out; + } + +- init_completion(&request->done); +- + /* + * Tell our userspace application about this new request + * by queueing an input event. +@@ -165,7 +162,7 @@ static int uinput_request_send(struct ui + uinput_dev_event(udev->dev, EV_UINPUT, request->code, request->id); + + out: +- mutex_unlock(&udev->mutex); ++ spin_unlock(&udev->state_lock); + return retval; + } + +@@ -174,6 +171,13 @@ static int uinput_request_submit(struct + { + int retval; + ++ /* ++ * Initialize completion before allocating the request slot. ++ * Once the slot is allocated, uinput_flush_requests() may ++ * complete it at any time, so it must be initialized first. ++ */ ++ init_completion(&request->done); ++ + retval = uinput_request_reserve_slot(udev, request); + if (retval) + return retval; +@@ -288,7 +292,14 @@ static void uinput_destroy_device(struct + struct input_dev *dev = udev->dev; + enum uinput_state old_state = udev->state; + ++ /* ++ * Update state under state_lock so that concurrent ++ * uinput_request_send() sees the state change before we ++ * flush pending requests and tear down the device. ++ */ ++ spin_lock(&udev->state_lock); + udev->state = UIST_NEW_DEVICE; ++ spin_unlock(&udev->state_lock); + + if (dev) { + name = dev->name; +@@ -365,7 +376,9 @@ static int uinput_create_device(struct u + if (error) + goto fail2; + ++ spin_lock(&udev->state_lock); + udev->state = UIST_CREATED; ++ spin_unlock(&udev->state_lock); + + return 0; + +@@ -383,6 +396,7 @@ static int uinput_open(struct inode *ino + return -ENOMEM; + + mutex_init(&newdev->mutex); ++ spin_lock_init(&newdev->state_lock); + spin_lock_init(&newdev->requests_lock); + init_waitqueue_head(&newdev->requests_waitq); + init_waitqueue_head(&newdev->waitq); diff --git a/queue-5.10/input-uinput-take-event-lock-when-submitting-ff-request-event.patch b/queue-5.10/input-uinput-take-event-lock-when-submitting-ff-request-event.patch new file mode 100644 index 0000000000..435b701a05 --- /dev/null +++ b/queue-5.10/input-uinput-take-event-lock-when-submitting-ff-request-event.patch @@ -0,0 +1,62 @@ +From ff14dafde15c11403fac61367a34fea08926e9ee Mon Sep 17 00:00:00 2001 +From: Dmitry Torokhov +Date: Tue, 7 Apr 2026 22:16:27 -0700 +Subject: Input: uinput - take event lock when submitting FF request "event" + +From: Dmitry Torokhov + +commit ff14dafde15c11403fac61367a34fea08926e9ee upstream. + +To avoid racing with FF playback events and corrupting device's event +queue take event_lock spinlock when calling uinput_dev_event() when +submitting a FF upload or erase "event". + +Tested-by: Mikhail Gavrilov +Link: https://patch.msgid.link/adXkf6MWzlB8LA_s@google.com +Cc: stable@vger.kernel.org +Signed-off-by: Dmitry Torokhov +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/misc/uinput.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/input/misc/uinput.c ++++ b/drivers/input/misc/uinput.c +@@ -25,8 +25,10 @@ + #include + #include + #include ++#include + #include + #include ++#include + #include + #include "../input-compat.h" + +@@ -75,6 +77,8 @@ static int uinput_dev_event(struct input + struct uinput_device *udev = input_get_drvdata(dev); + struct timespec64 ts; + ++ lockdep_assert_held(&dev->event_lock); ++ + ktime_get_ts64(&ts); + + udev->buff[udev->head] = (struct input_event) { +@@ -146,6 +150,7 @@ static void uinput_request_release_slot( + static int uinput_request_send(struct uinput_device *udev, + struct uinput_request *request) + { ++ unsigned long flags; + int retval = 0; + + spin_lock(&udev->state_lock); +@@ -159,7 +164,9 @@ static int uinput_request_send(struct ui + * Tell our userspace application about this new request + * by queueing an input event. + */ ++ spin_lock_irqsave(&udev->dev->event_lock, flags); + uinput_dev_event(udev->dev, EV_UINPUT, request->code, request->id); ++ spin_unlock_irqrestore(&udev->dev->event_lock, flags); + + out: + spin_unlock(&udev->state_lock); diff --git a/queue-5.10/lib-crypto-chacha-zeroize-permuted_state-before-it-leaves-scope.patch b/queue-5.10/lib-crypto-chacha-zeroize-permuted_state-before-it-leaves-scope.patch new file mode 100644 index 0000000000..7f0a54f5a6 --- /dev/null +++ b/queue-5.10/lib-crypto-chacha-zeroize-permuted_state-before-it-leaves-scope.patch @@ -0,0 +1,49 @@ +From e5046823f8fa3677341b541a25af2fcb99a5b1e0 Mon Sep 17 00:00:00 2001 +From: Eric Biggers +Date: Wed, 25 Mar 2026 20:29:20 -0700 +Subject: lib/crypto: chacha: Zeroize permuted_state before it leaves scope + +From: Eric Biggers + +commit e5046823f8fa3677341b541a25af2fcb99a5b1e0 upstream. + +Since the ChaCha permutation is invertible, the local variable +'permuted_state' is sufficient to compute the original 'state', and thus +the key, even after the permutation has been done. + +While the kernel is quite inconsistent about zeroizing secrets on the +stack (and some prominent userspace crypto libraries don't bother at all +since it's not guaranteed to work anyway), the kernel does try to do it +as a best practice, especially in cases involving the RNG. + +Thus, explicitly zeroize 'permuted_state' before it goes out of scope. + +Fixes: c08d0e647305 ("crypto: chacha20 - Add a generic ChaCha20 stream cipher implementation") +Cc: stable@vger.kernel.org +Acked-by: Ard Biesheuvel +Link: https://lore.kernel.org/r/20260326032920.39408-1-ebiggers@kernel.org +Signed-off-by: Eric Biggers +Signed-off-by: Greg Kroah-Hartman +--- + lib/crypto/chacha.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/lib/crypto/chacha.c ++++ b/lib/crypto/chacha.c +@@ -86,6 +86,8 @@ void chacha_block_generic(u32 *state, u8 + put_unaligned_le32(x[i] + state[i], &stream[i * sizeof(u32)]); + + state[12]++; ++ ++ memzero_explicit(x, sizeof(x)); + } + EXPORT_SYMBOL(chacha_block_generic); + +@@ -110,5 +112,7 @@ void hchacha_block_generic(const u32 *st + + memcpy(&stream[0], &x[0], 16); + memcpy(&stream[4], &x[12], 16); ++ ++ memzero_explicit(x, sizeof(x)); + } + EXPORT_SYMBOL(hchacha_block_generic); diff --git a/queue-5.10/series b/queue-5.10/series index 6fb74b43ad..bfa8501557 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -414,3 +414,8 @@ usb-gadget-f_subset-fix-unbalanced-refcnt-in-geth_free.patch usb-gadget-f_rndis-protect-rndis-options-with-mutex.patch usb-gadget-f_uac1_legacy-validate-control-request-size.patch io_uring-tctx-work-around-xa_store-allocation-error-issue.patch +lib-crypto-chacha-zeroize-permuted_state-before-it-leaves-scope.patch +wifi-rt2x00usb-fix-devres-lifetime.patch +xfrm_user-fix-info-leak-in-build_report.patch +input-uinput-fix-circular-locking-dependency-with-ff-core.patch +input-uinput-take-event-lock-when-submitting-ff-request-event.patch diff --git a/queue-5.10/wifi-rt2x00usb-fix-devres-lifetime.patch b/queue-5.10/wifi-rt2x00usb-fix-devres-lifetime.patch new file mode 100644 index 0000000000..9757234e96 --- /dev/null +++ b/queue-5.10/wifi-rt2x00usb-fix-devres-lifetime.patch @@ -0,0 +1,41 @@ +From 25369b22223d1c56e42a0cd4ac9137349d5a898e Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 27 Mar 2026 12:32:19 +0100 +Subject: wifi: rt2x00usb: fix devres lifetime + +From: Johan Hovold + +commit 25369b22223d1c56e42a0cd4ac9137349d5a898e upstream. + +USB drivers bind to USB interfaces and any device managed resources +should have their lifetime tied to the interface rather than parent USB +device. This avoids issues like memory leaks when drivers are unbound +without their devices being physically disconnected (e.g. on probe +deferral or configuration changes). + +Fix the USB anchor lifetime so that it is released on driver unbind. + +Fixes: 8b4c0009313f ("rt2x00usb: Use usb anchor to manage URB") +Cc: stable@vger.kernel.org # 4.7 +Cc: Vishal Thanki +Signed-off-by: Johan Hovold +Acked-by: Stanislaw Gruszka +Reviewed-by: Greg Kroah-Hartman +Link: https://patch.msgid.link/20260327113219.1313748-1-johan@kernel.org +Signed-off-by: Johannes Berg +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +@@ -830,7 +830,7 @@ int rt2x00usb_probe(struct usb_interface + if (retval) + goto exit_free_device; + +- rt2x00dev->anchor = devm_kmalloc(&usb_dev->dev, ++ rt2x00dev->anchor = devm_kmalloc(&usb_intf->dev, + sizeof(struct usb_anchor), + GFP_KERNEL); + if (!rt2x00dev->anchor) { diff --git a/queue-5.10/xfrm_user-fix-info-leak-in-build_report.patch b/queue-5.10/xfrm_user-fix-info-leak-in-build_report.patch new file mode 100644 index 0000000000..1748339a2b --- /dev/null +++ b/queue-5.10/xfrm_user-fix-info-leak-in-build_report.patch @@ -0,0 +1,40 @@ +From d10119968d0e1f2b669604baf2a8b5fdb72fa6b4 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Mon, 6 Apr 2026 17:34:22 +0200 +Subject: xfrm_user: fix info leak in build_report() + +From: Greg Kroah-Hartman + +commit d10119968d0e1f2b669604baf2a8b5fdb72fa6b4 upstream. + +struct xfrm_user_report is a __u8 proto field followed by a struct +xfrm_selector which means there is three "empty" bytes of padding, but +the padding is never zeroed before copying to userspace. Fix that up by +zeroing the structure before setting individual member variables. + +Cc: stable +Cc: Steffen Klassert +Cc: Herbert Xu +Cc: "David S. Miller" +Cc: Eric Dumazet +Cc: Jakub Kicinski +Cc: Paolo Abeni +Cc: Simon Horman +Assisted-by: gregkh_clanker_t1000 +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Steffen Klassert +Signed-off-by: Greg Kroah-Hartman +--- + net/xfrm/xfrm_user.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/xfrm/xfrm_user.c ++++ b/net/xfrm/xfrm_user.c +@@ -3445,6 +3445,7 @@ static int build_report(struct sk_buff * + return -EMSGSIZE; + + ur = nlmsg_data(nlh); ++ memset(ur, 0, sizeof(*ur)); + ur->proto = proto; + memcpy(&ur->sel, sel, sizeof(ur->sel)); +