From: Sasha Levin Date: Sun, 3 May 2026 18:16:29 +0000 (-0400) Subject: Fixes for all trees X-Git-Tag: v6.12.86~32 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d68f4377b5629a491cc1b345e687bc352c5a9475;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for all trees Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/io_uring-poll-fix-backport-of-io_poll_add-changes.patch-11453 b/queue-5.10/io_uring-poll-fix-backport-of-io_poll_add-changes.patch-11453 new file mode 100644 index 0000000000..a4a11a8e3c --- /dev/null +++ b/queue-5.10/io_uring-poll-fix-backport-of-io_poll_add-changes.patch-11453 @@ -0,0 +1,67 @@ +From 6e90576a39283de94bfb254e5c7551be41bed305 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Apr 2026 16:44:06 -0600 +Subject: io_uring/poll: fix backport of io_poll_add() changes + +From: Jens Axboe + +The 5.15/5.10 backport of 84230ad2d2af had a few issues, due to the +older poll base. Notably return value handling __io_arm_poll_handler() +and in return __io_poll_add() as well. Fix them up. + +Reported-by: Ben Hutchings +Fixes: 349ef5d2e7bf ("io_uring/poll: correctly handle io_poll_add() return value on update") +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/io_uring.c | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index 7cb4eeefd3cf4..2ca09e2dbd3d4 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -5997,26 +5997,22 @@ static int __io_poll_add(struct io_kiocb *req, unsigned int issue_flags) + if (!ret && ipt.error) + req_set_fail(req); + ret = ret ?: ipt.error; +- if (ret > 0) { ++ if (ret) + __io_req_complete(req, issue_flags, ret, 0); +- return ret; +- } +- return 0; ++ return ret; + } + + static int io_poll_add(struct io_kiocb *req, unsigned int issue_flags) + { +- int ret; +- +- ret = __io_poll_add(req, issue_flags); +- return ret < 0 ? ret : 0; ++ __io_poll_add(req, issue_flags); ++ return 0; + } + + static int io_poll_update(struct io_kiocb *req, unsigned int issue_flags) + { + struct io_ring_ctx *ctx = req->ctx; + struct io_kiocb *preq; +- int ret2, ret = 0; ++ int ret2 = -ECANCELED, ret = 0; + + io_ring_submit_lock(ctx, !(issue_flags & IO_URING_F_NONBLOCK)); + +@@ -6047,7 +6043,7 @@ static int io_poll_update(struct io_kiocb *req, unsigned int issue_flags) + preq->result = ret2; + + } +- if (preq->result < 0) ++ if (ret2 < 0) + req_set_fail(preq); + io_req_complete(preq, preq->result); + out: +-- +2.53.0 + diff --git a/queue-5.10/io_uring-poll-fix-epoll_uring_wake-sometimes-not-bei.patch-12437 b/queue-5.10/io_uring-poll-fix-epoll_uring_wake-sometimes-not-bei.patch-12437 new file mode 100644 index 0000000000..1554080bea --- /dev/null +++ b/queue-5.10/io_uring-poll-fix-epoll_uring_wake-sometimes-not-bei.patch-12437 @@ -0,0 +1,54 @@ +From 8d88e04415773b58636f5e99d2a7033e10f9bb96 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Apr 2026 16:41:32 -0600 +Subject: io_uring/poll: fix EPOLL_URING_WAKE sometimes not being honored + +From: Jens Axboe + +Rather than do the masking only when we jump straight to execution, +mark it as EPOLLONESHOT regardless. This ensures it doesn't get lost. +And just kill the poll entry upfront, if marked. This is an optimization +in later kernels, but it's actually required on the older kernels to +note the EPOLL_URING_WAKE mask correctly. + +Fixes: ccf06b5a981c ("io_uring: pass in EPOLL_URING_WAKE for eventfd signaling and wakeups") +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/io_uring.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index dea1fb22c0efb..7cb4eeefd3cf4 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -5647,14 +5647,19 @@ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, + if (mask && !(mask & poll->events)) + return 0; + ++ /* ++ * If we trigger a multishot poll off our own wakeup path, ++ * disable multishot as there is a circular dependency between ++ * CQ posting and triggering the event. ++ */ ++ if (mask & EPOLL_URING_WAKE) ++ poll->events |= EPOLLONESHOT; ++ + if (io_poll_get_ownership(req)) { +- /* +- * If we trigger a multishot poll off our own wakeup path, +- * disable multishot as there is a circular dependency between +- * CQ posting and triggering the event. +- */ +- if (mask & EPOLL_URING_WAKE) +- poll->events |= EPOLLONESHOT; ++ if (mask && poll->events & EPOLLONESHOT) { ++ list_del_init(&poll->wait.entry); ++ smp_store_release(&poll->head, NULL); ++ } + + __io_poll_execute(req, mask); + } +-- +2.53.0 + diff --git a/queue-5.10/mtd-docg3-fix-use-after-free-in-docg3_release.patch b/queue-5.10/mtd-docg3-fix-use-after-free-in-docg3_release.patch new file mode 100644 index 0000000000..7f723febfb --- /dev/null +++ b/queue-5.10/mtd-docg3-fix-use-after-free-in-docg3_release.patch @@ -0,0 +1,53 @@ +From 26f596b2a48186eb0f23a1a0e6bd4454f0fa0e65 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 2 May 2026 07:32:48 -0400 +Subject: mtd: docg3: fix use-after-free in docg3_release() + +From: James Kim + +[ Upstream commit ca19808bc6fac7e29420d8508df569b346b3e339 ] + +In docg3_release(), the docg3 pointer is obtained from +cascade->floors[0]->priv before the loop that calls +doc_release_device() on each floor. doc_release_device() frees the +docg3 struct via kfree(docg3) at line 1881. After the loop, +docg3->cascade->bch dereferences the already-freed pointer. + +Fix this by accessing cascade->bch directly, which is equivalent +since docg3->cascade points back to the same cascade struct, and +is already available as a local variable. This also removes the +now-unused docg3 local variable. + +Fixes: c8ae3f744ddc ("lib/bch: Rework a little bit the exported function names") +Cc: stable@vger.kernel.org +Signed-off-by: James Kim +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/devices/docg3.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c +index fa42473d04c1b..378239c7513e0 100644 +--- a/drivers/mtd/devices/docg3.c ++++ b/drivers/mtd/devices/docg3.c +@@ -2042,7 +2042,6 @@ static int __init docg3_probe(struct platform_device *pdev) + static int docg3_release(struct platform_device *pdev) + { + struct docg3_cascade *cascade = platform_get_drvdata(pdev); +- struct docg3 *docg3 = cascade->floors[0]->priv; + int floor; + + doc_unregister_sysfs(pdev, cascade); +@@ -2050,7 +2049,7 @@ static int docg3_release(struct platform_device *pdev) + if (cascade->floors[floor]) + doc_release_device(cascade->floors[floor]); + +- bch_free(docg3->cascade->bch); ++ bch_free(cascade->bch); + return 0; + } + +-- +2.53.0 + diff --git a/queue-5.10/revert-io_uring-poll-fix-backport-of-io_poll_add-cha.patch b/queue-5.10/revert-io_uring-poll-fix-backport-of-io_poll_add-cha.patch new file mode 100644 index 0000000000..c127662bba --- /dev/null +++ b/queue-5.10/revert-io_uring-poll-fix-backport-of-io_poll_add-cha.patch @@ -0,0 +1,43 @@ +From dc40b77c2bb2dc092136b2d7443df6c352cdb845 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 2 May 2026 20:32:43 -0400 +Subject: Revert "io_uring/poll: fix backport of io_poll_add() changes" + +This reverts commit 3edc04cc05f37faf1f0f1f77ca33fb616e8f6306. + +Signed-off-by: Sasha Levin +--- + io_uring/io_uring.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index 8b0dfea96ee09..83806b3c6e3bc 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -5991,15 +5991,19 @@ static int __io_poll_add(struct io_kiocb *req, unsigned int issue_flags) + if (!ret && ipt.error) + req_set_fail(req); + ret = ret ?: ipt.error; +- if (ret) ++ if (ret > 0) { + __io_req_complete(req, issue_flags, ret, 0); +- return ret; ++ return ret; ++ } ++ return 0; + } + + static int io_poll_add(struct io_kiocb *req, unsigned int issue_flags) + { +- __io_poll_add(req, issue_flags); +- return 0; ++ int ret; ++ ++ ret = __io_poll_add(req, issue_flags); ++ return ret < 0 ? ret : 0; + } + + static int io_poll_update(struct io_kiocb *req, unsigned int issue_flags) +-- +2.53.0 + diff --git a/queue-5.10/revert-io_uring-poll-fix-epoll_uring_wake-sometimes-.patch b/queue-5.10/revert-io_uring-poll-fix-epoll_uring_wake-sometimes-.patch new file mode 100644 index 0000000000..16d402ccfa --- /dev/null +++ b/queue-5.10/revert-io_uring-poll-fix-epoll_uring_wake-sometimes-.patch @@ -0,0 +1,46 @@ +From 3d639af7101238d66e215369d7ddd6701d27d115 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 2 May 2026 20:32:43 -0400 +Subject: Revert "io_uring/poll: fix EPOLL_URING_WAKE sometimes not being + masked in" + +This reverts commit cc89e4186443c894e390e4db39a117bba23f17e8. + +Signed-off-by: Sasha Levin +--- + io_uring/io_uring.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index 83806b3c6e3bc..dea1fb22c0efb 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -5647,16 +5647,17 @@ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, + if (mask && !(mask & poll->events)) + return 0; + +- /* +- * If we trigger a multishot poll off our own wakeup path, +- * disable multishot as there is a circular dependency between +- * CQ posting and triggering the event. +- */ +- if (mask & EPOLL_URING_WAKE) +- poll->events |= EPOLLONESHOT; ++ if (io_poll_get_ownership(req)) { ++ /* ++ * If we trigger a multishot poll off our own wakeup path, ++ * disable multishot as there is a circular dependency between ++ * CQ posting and triggering the event. ++ */ ++ if (mask & EPOLL_URING_WAKE) ++ poll->events |= EPOLLONESHOT; + +- if (io_poll_get_ownership(req)) + __io_poll_execute(req, mask); ++ } + return 1; + } + +-- +2.53.0 + diff --git a/queue-5.10/series b/queue-5.10/series index 0742622d01..5c4c3a07e1 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -180,3 +180,8 @@ kvm-nsvm-sync-nextrip-to-cached-vmcb12-after-vmrun-of-l2.patch kvm-nsvm-sync-interrupt-shadow-to-cached-vmcb12-after-vmrun-of-l2.patch kvm-nsvm-ensure-avic-is-inhibited-when-restoring-a-vcpu-to-guest-mode.patch kvm-nsvm-clear-gif-on-nested-vmexit-invalid.patch +revert-io_uring-poll-fix-backport-of-io_poll_add-cha.patch +revert-io_uring-poll-fix-epoll_uring_wake-sometimes-.patch +io_uring-poll-fix-epoll_uring_wake-sometimes-not-bei.patch-12437 +io_uring-poll-fix-backport-of-io_poll_add-changes.patch-11453 +mtd-docg3-fix-use-after-free-in-docg3_release.patch diff --git a/queue-5.15/io_uring-poll-fix-backport-of-io_poll_add-changes.patch-10615 b/queue-5.15/io_uring-poll-fix-backport-of-io_poll_add-changes.patch-10615 new file mode 100644 index 0000000000..594246f57f --- /dev/null +++ b/queue-5.15/io_uring-poll-fix-backport-of-io_poll_add-changes.patch-10615 @@ -0,0 +1,67 @@ +From 8b7b70d38d92ba6e8dec66e6fd27b54019fdfb76 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Apr 2026 16:44:06 -0600 +Subject: io_uring/poll: fix backport of io_poll_add() changes + +From: Jens Axboe + +The 5.15/5.10 backport of 84230ad2d2af had a few issues, due to the +older poll base. Notably return value handling __io_arm_poll_handler() +and in return __io_poll_add() as well. Fix them up. + +Reported-by: Ben Hutchings +Fixes: 349ef5d2e7bf ("io_uring/poll: correctly handle io_poll_add() return value on update") +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/io_uring.c | 16 ++++++---------- + 1 file changed, 6 insertions(+), 10 deletions(-) + +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index 4f1dda7d68c22..cb54ebda0a8a7 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -6144,26 +6144,22 @@ static int __io_poll_add(struct io_kiocb *req, unsigned int issue_flags) + if (!ret && ipt.error) + req_set_fail(req); + ret = ret ?: ipt.error; +- if (ret > 0) { ++ if (ret) + __io_req_complete(req, issue_flags, ret, 0); +- return ret; +- } +- return 0; ++ return ret; + } + + static int io_poll_add(struct io_kiocb *req, unsigned int issue_flags) + { +- int ret; +- +- ret = __io_poll_add(req, issue_flags); +- return ret < 0 ? ret : 0; ++ __io_poll_add(req, issue_flags); ++ return 0; + } + + static int io_poll_update(struct io_kiocb *req, unsigned int issue_flags) + { + struct io_ring_ctx *ctx = req->ctx; + struct io_kiocb *preq; +- int ret2, ret = 0; ++ int ret2 = -ECANCELED, ret = 0; + + io_ring_submit_lock(ctx, !(issue_flags & IO_URING_F_NONBLOCK)); + +@@ -6194,7 +6190,7 @@ static int io_poll_update(struct io_kiocb *req, unsigned int issue_flags) + preq->result = ret2; + + } +- if (preq->result < 0) ++ if (ret2 < 0) + req_set_fail(preq); + io_req_complete(preq, preq->result); + out: +-- +2.53.0 + diff --git a/queue-5.15/io_uring-poll-fix-epoll_uring_wake-sometimes-not-bei.patch b/queue-5.15/io_uring-poll-fix-epoll_uring_wake-sometimes-not-bei.patch new file mode 100644 index 0000000000..eae5a8ab34 --- /dev/null +++ b/queue-5.15/io_uring-poll-fix-epoll_uring_wake-sometimes-not-bei.patch @@ -0,0 +1,54 @@ +From 0ff02ef66f9c928580e07a8e7924b8e994504996 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 21 Apr 2026 16:41:32 -0600 +Subject: io_uring/poll: fix EPOLL_URING_WAKE sometimes not being honored + +From: Jens Axboe + +Rather than do the masking only when we jump straight to execution, +mark it as EPOLLONESHOT regardless. This ensures it doesn't get lost. +And just kill the poll entry upfront, if marked. This is an optimization +in later kernels, but it's actually required on the older kernels to +note the EPOLL_URING_WAKE mask correctly. + +Fixes: ccf06b5a981c ("io_uring: pass in EPOLL_URING_WAKE for eventfd signaling and wakeups") +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + io_uring/io_uring.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index 38decfc1a914a..4f1dda7d68c22 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -5794,14 +5794,19 @@ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, + if (mask && !(mask & poll->events)) + return 0; + ++ /* ++ * If we trigger a multishot poll off our own wakeup path, ++ * disable multishot as there is a circular dependency between ++ * CQ posting and triggering the event. ++ */ ++ if (mask & EPOLL_URING_WAKE) ++ poll->events |= EPOLLONESHOT; ++ + if (io_poll_get_ownership(req)) { +- /* +- * If we trigger a multishot poll off our own wakeup path, +- * disable multishot as there is a circular dependency between +- * CQ posting and triggering the event. +- */ +- if (mask & EPOLL_URING_WAKE) +- poll->events |= EPOLLONESHOT; ++ if (mask && poll->events & EPOLLONESHOT) { ++ list_del_init(&poll->wait.entry); ++ smp_store_release(&poll->head, NULL); ++ } + + __io_poll_execute(req, mask); + } +-- +2.53.0 + diff --git a/queue-5.15/mtd-docg3-convert-to-platform-remove-callback-return.patch b/queue-5.15/mtd-docg3-convert-to-platform-remove-callback-return.patch new file mode 100644 index 0000000000..023a865061 --- /dev/null +++ b/queue-5.15/mtd-docg3-convert-to-platform-remove-callback-return.patch @@ -0,0 +1,68 @@ +From d2f729559442ab0acbe8812d3f69257a053fa686 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 May 2026 22:11:53 -0400 +Subject: mtd: docg3: Convert to platform remove callback returning void +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit eb0cec77d534413a800ec20944a2b1e37cfecdcf ] + +The .remove() callback for a platform driver returns an int which makes +many driver authors wrongly assume it's possible to do error handling by +returning an error code. However the value returned is ignored (apart +from emitting a warning) and this typically results in resource leaks. + +To improve here there is a quest to make the remove callback return +void. In the first step of this quest all drivers are converted to +.remove_new(), which already returns void. Eventually after all drivers +are converted, .remove_new() will be renamed to .remove(). + +Trivially convert this driver from always returning zero in the remove +callback to the void returning variant. + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Miquel Raynal +Acked-by: Tudor Ambarus +Link: https://lore.kernel.org/linux-mtd/20231008200143.196369-5-u.kleine-koenig@pengutronix.de +Stable-dep-of: ca19808bc6fa ("mtd: docg3: fix use-after-free in docg3_release()") +Signed-off-by: Sasha Levin +--- + drivers/mtd/devices/docg3.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c +index 27c08f22dec8c..25a7df6448028 100644 +--- a/drivers/mtd/devices/docg3.c ++++ b/drivers/mtd/devices/docg3.c +@@ -2038,7 +2038,7 @@ static int __init docg3_probe(struct platform_device *pdev) + * + * Returns 0 + */ +-static int docg3_release(struct platform_device *pdev) ++static void docg3_release(struct platform_device *pdev) + { + struct docg3_cascade *cascade = platform_get_drvdata(pdev); + struct docg3 *docg3 = cascade->floors[0]->priv; +@@ -2050,7 +2050,6 @@ static int docg3_release(struct platform_device *pdev) + doc_release_device(cascade->floors[floor]); + + bch_free(docg3->cascade->bch); +- return 0; + } + + #ifdef CONFIG_OF +@@ -2068,7 +2067,7 @@ static struct platform_driver g3_driver = { + }, + .suspend = docg3_suspend, + .resume = docg3_resume, +- .remove = docg3_release, ++ .remove_new = docg3_release, + }; + + module_platform_driver_probe(g3_driver, docg3_probe); +-- +2.53.0 + diff --git a/queue-5.15/mtd-docg3-fix-use-after-free-in-docg3_release.patch b/queue-5.15/mtd-docg3-fix-use-after-free-in-docg3_release.patch new file mode 100644 index 0000000000..cff3edf37a --- /dev/null +++ b/queue-5.15/mtd-docg3-fix-use-after-free-in-docg3_release.patch @@ -0,0 +1,53 @@ +From 8503e9d05ba68119d9feff4bf702a874a1ec3292 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 May 2026 22:11:54 -0400 +Subject: mtd: docg3: fix use-after-free in docg3_release() + +From: James Kim + +[ Upstream commit ca19808bc6fac7e29420d8508df569b346b3e339 ] + +In docg3_release(), the docg3 pointer is obtained from +cascade->floors[0]->priv before the loop that calls +doc_release_device() on each floor. doc_release_device() frees the +docg3 struct via kfree(docg3) at line 1881. After the loop, +docg3->cascade->bch dereferences the already-freed pointer. + +Fix this by accessing cascade->bch directly, which is equivalent +since docg3->cascade points back to the same cascade struct, and +is already available as a local variable. This also removes the +now-unused docg3 local variable. + +Fixes: c8ae3f744ddc ("lib/bch: Rework a little bit the exported function names") +Cc: stable@vger.kernel.org +Signed-off-by: James Kim +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/devices/docg3.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c +index 25a7df6448028..7de576404b14f 100644 +--- a/drivers/mtd/devices/docg3.c ++++ b/drivers/mtd/devices/docg3.c +@@ -2041,7 +2041,6 @@ static int __init docg3_probe(struct platform_device *pdev) + static void docg3_release(struct platform_device *pdev) + { + struct docg3_cascade *cascade = platform_get_drvdata(pdev); +- struct docg3 *docg3 = cascade->floors[0]->priv; + int floor; + + doc_unregister_sysfs(pdev, cascade); +@@ -2049,7 +2048,7 @@ static void docg3_release(struct platform_device *pdev) + if (cascade->floors[floor]) + doc_release_device(cascade->floors[floor]); + +- bch_free(docg3->cascade->bch); ++ bch_free(cascade->bch); + } + + #ifdef CONFIG_OF +-- +2.53.0 + diff --git a/queue-5.15/revert-io_uring-poll-fix-backport-of-io_poll_add-cha.patch b/queue-5.15/revert-io_uring-poll-fix-backport-of-io_poll_add-cha.patch new file mode 100644 index 0000000000..efbe03489d --- /dev/null +++ b/queue-5.15/revert-io_uring-poll-fix-backport-of-io_poll_add-cha.patch @@ -0,0 +1,43 @@ +From 3eb256e82f341cd1ffe335f87d6f95ca664d94b1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 2 May 2026 19:29:45 -0400 +Subject: Revert "io_uring/poll: fix backport of io_poll_add() changes" + +This reverts commit 66d59bd23bb8437e495becdfdcf1f503d32910c1. + +Signed-off-by: Sasha Levin +--- + io_uring/io_uring.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index 07519e9a695c0..db5c9fbdec3b4 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -6138,15 +6138,19 @@ static int __io_poll_add(struct io_kiocb *req, unsigned int issue_flags) + if (!ret && ipt.error) + req_set_fail(req); + ret = ret ?: ipt.error; +- if (ret) ++ if (ret > 0) { + __io_req_complete(req, issue_flags, ret, 0); +- return ret; ++ return ret; ++ } ++ return 0; + } + + static int io_poll_add(struct io_kiocb *req, unsigned int issue_flags) + { +- __io_poll_add(req, issue_flags); +- return 0; ++ int ret; ++ ++ ret = __io_poll_add(req, issue_flags); ++ return ret < 0 ? ret : 0; + } + + static int io_poll_update(struct io_kiocb *req, unsigned int issue_flags) +-- +2.53.0 + diff --git a/queue-5.15/revert-io_uring-poll-fix-epoll_uring_wake-sometimes-.patch b/queue-5.15/revert-io_uring-poll-fix-epoll_uring_wake-sometimes-.patch new file mode 100644 index 0000000000..62dc6102d7 --- /dev/null +++ b/queue-5.15/revert-io_uring-poll-fix-epoll_uring_wake-sometimes-.patch @@ -0,0 +1,46 @@ +From 404c0e8bea17a8d458a492d5a982399570ec4db8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 2 May 2026 19:29:45 -0400 +Subject: Revert "io_uring/poll: fix EPOLL_URING_WAKE sometimes not being + masked in" + +This reverts commit ae388b6752cb4b82f7be8b2edb704cd9569923f0. + +Signed-off-by: Sasha Levin +--- + io_uring/io_uring.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c +index db5c9fbdec3b4..38decfc1a914a 100644 +--- a/io_uring/io_uring.c ++++ b/io_uring/io_uring.c +@@ -5794,16 +5794,17 @@ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync, + if (mask && !(mask & poll->events)) + return 0; + +- /* +- * If we trigger a multishot poll off our own wakeup path, +- * disable multishot as there is a circular dependency between +- * CQ posting and triggering the event. +- */ +- if (mask & EPOLL_URING_WAKE) +- poll->events |= EPOLLONESHOT; ++ if (io_poll_get_ownership(req)) { ++ /* ++ * If we trigger a multishot poll off our own wakeup path, ++ * disable multishot as there is a circular dependency between ++ * CQ posting and triggering the event. ++ */ ++ if (mask & EPOLL_URING_WAKE) ++ poll->events |= EPOLLONESHOT; + +- if (io_poll_get_ownership(req)) + __io_poll_execute(req, mask); ++ } + return 1; + } + +-- +2.53.0 + diff --git a/queue-5.15/series b/queue-5.15/series index 61841ebe52..fe8d16e695 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -239,3 +239,9 @@ kvm-nsvm-ensure-avic-is-inhibited-when-restoring-a-vcpu-to-guest-mode.patch kvm-nsvm-always-inject-a-gp-if-mapping-vmcb12-fails-on-nested-vmrun.patch kvm-nsvm-clear-gif-on-nested-vmexit-invalid.patch kvm-nsvm-add-missing-consistency-check-for-ncr3-validity.patch +revert-io_uring-poll-fix-backport-of-io_poll_add-cha.patch +revert-io_uring-poll-fix-epoll_uring_wake-sometimes-.patch +io_uring-poll-fix-epoll_uring_wake-sometimes-not-bei.patch +io_uring-poll-fix-backport-of-io_poll_add-changes.patch-10615 +mtd-docg3-convert-to-platform-remove-callback-return.patch +mtd-docg3-fix-use-after-free-in-docg3_release.patch diff --git a/queue-6.1/io_uring-poll-fix-multishot-recv-missing-eof-on-wake.patch b/queue-6.1/io_uring-poll-fix-multishot-recv-missing-eof-on-wake.patch new file mode 100644 index 0000000000..656a97d6fd --- /dev/null +++ b/queue-6.1/io_uring-poll-fix-multishot-recv-missing-eof-on-wake.patch @@ -0,0 +1,65 @@ +From 2a08a811f05c35b6848b13da6aa5d2e4e1b82ead Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 2 May 2026 01:51:56 +0300 +Subject: io_uring/poll: fix multishot recv missing EOF on wakeup race + +From: Jens Axboe + +[ Upstream commit a68ed2df72131447d131531a08fe4dfcf4fa4653 ] + +When a socket send and shutdown() happen back-to-back, both fire +wake-ups before the receiver's task_work has a chance to run. The first +wake gets poll ownership (poll_refs=1), and the second bumps it to 2. +When io_poll_check_events() runs, it calls io_poll_issue() which does a +recv that reads the data and returns IOU_RETRY. The loop then drains all +accumulated refs (atomic_sub_return(2) -> 0) and exits, even though only +the first event was consumed. Since the shutdown is a persistent state +change, no further wakeups will happen, and the multishot recv can hang +forever. + +Check specifically for HUP in the poll loop, and ensure that another +loop is done to check for status if more than a single poll activation +is pending. This ensures we don't lose the shutdown event. + +Backport notes for linux-6.1.y: + - In 6.1.y the do-while masks v in the while-condition itself, so + v can carry IO_POLL_RETRY_FLAG/IO_POLL_CANCEL_FLAG bits when we + reach the multishot branch. The HUP check therefore compares + `(v & IO_POLL_REF_MASK) != 1` rather than the upstream `v != 1`. + - io_poll_issue takes `bool *locked` here (renamed to `ts` in 6.6+). + - 6.1.y has no IOU_REQUEUE return path; only IOU_STOP_MULTISHOT. + +CVE: CVE-2026-23473 +Cc: stable@vger.kernel.org # 6.1.y +Fixes: dbc2564cfe0f ("io_uring: let fast poll support multishot") +Reported-by: Francis Brosseau +Link: https://github.com/axboe/liburing/issues/1549 +Signed-off-by: Jens Axboe +[backport for linux-6.1.y, verified 2026-05-01] +Signed-off-by: Sasha Levin +--- + io_uring/poll.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/io_uring/poll.c b/io_uring/poll.c +index 367605a5878fe..cdf1f2f57b9a2 100644 +--- a/io_uring/poll.c ++++ b/io_uring/poll.c +@@ -303,7 +303,13 @@ static int io_poll_check_events(struct io_kiocb *req, bool *locked) + return IOU_POLL_REMOVE_POLL_USE_RES; + } + } else { +- int ret = io_poll_issue(req, locked); ++ int ret; ++ ++ /* multiple refs and HUP, ensure we loop once more */ ++ if ((req->cqe.res & (POLLHUP | POLLRDHUP)) && ++ (v & IO_POLL_REF_MASK) != 1) ++ v--; ++ ret = io_poll_issue(req, locked); + io_kbuf_recycle(req, 0); + + if (ret == IOU_STOP_MULTISHOT) +-- +2.53.0 + diff --git a/queue-6.1/mtd-docg3-convert-to-platform-remove-callback-return.patch b/queue-6.1/mtd-docg3-convert-to-platform-remove-callback-return.patch new file mode 100644 index 0000000000..5261dd4b93 --- /dev/null +++ b/queue-6.1/mtd-docg3-convert-to-platform-remove-callback-return.patch @@ -0,0 +1,68 @@ +From 159ea51e5e9cbc145d7c94dea04e5a6bf38f9220 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 May 2026 19:41:35 -0400 +Subject: mtd: docg3: Convert to platform remove callback returning void +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit eb0cec77d534413a800ec20944a2b1e37cfecdcf ] + +The .remove() callback for a platform driver returns an int which makes +many driver authors wrongly assume it's possible to do error handling by +returning an error code. However the value returned is ignored (apart +from emitting a warning) and this typically results in resource leaks. + +To improve here there is a quest to make the remove callback return +void. In the first step of this quest all drivers are converted to +.remove_new(), which already returns void. Eventually after all drivers +are converted, .remove_new() will be renamed to .remove(). + +Trivially convert this driver from always returning zero in the remove +callback to the void returning variant. + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Miquel Raynal +Acked-by: Tudor Ambarus +Link: https://lore.kernel.org/linux-mtd/20231008200143.196369-5-u.kleine-koenig@pengutronix.de +Stable-dep-of: ca19808bc6fa ("mtd: docg3: fix use-after-free in docg3_release()") +Signed-off-by: Sasha Levin +--- + drivers/mtd/devices/docg3.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c +index a7714e3de887f..8cb25cfd9c10a 100644 +--- a/drivers/mtd/devices/docg3.c ++++ b/drivers/mtd/devices/docg3.c +@@ -2046,7 +2046,7 @@ static int __init docg3_probe(struct platform_device *pdev) + * + * Returns 0 + */ +-static int docg3_release(struct platform_device *pdev) ++static void docg3_release(struct platform_device *pdev) + { + struct docg3_cascade *cascade = platform_get_drvdata(pdev); + struct docg3 *docg3 = cascade->floors[0]->priv; +@@ -2058,7 +2058,6 @@ static int docg3_release(struct platform_device *pdev) + doc_release_device(cascade->floors[floor]); + + bch_free(docg3->cascade->bch); +- return 0; + } + + #ifdef CONFIG_OF +@@ -2076,7 +2075,7 @@ static struct platform_driver g3_driver = { + }, + .suspend = docg3_suspend, + .resume = docg3_resume, +- .remove = docg3_release, ++ .remove_new = docg3_release, + }; + + module_platform_driver_probe(g3_driver, docg3_probe); +-- +2.53.0 + diff --git a/queue-6.1/mtd-docg3-fix-use-after-free-in-docg3_release.patch b/queue-6.1/mtd-docg3-fix-use-after-free-in-docg3_release.patch new file mode 100644 index 0000000000..e5a28086c0 --- /dev/null +++ b/queue-6.1/mtd-docg3-fix-use-after-free-in-docg3_release.patch @@ -0,0 +1,53 @@ +From b1d9422f71c6a5b1c234355948483b696d4e95e2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 May 2026 19:41:36 -0400 +Subject: mtd: docg3: fix use-after-free in docg3_release() + +From: James Kim + +[ Upstream commit ca19808bc6fac7e29420d8508df569b346b3e339 ] + +In docg3_release(), the docg3 pointer is obtained from +cascade->floors[0]->priv before the loop that calls +doc_release_device() on each floor. doc_release_device() frees the +docg3 struct via kfree(docg3) at line 1881. After the loop, +docg3->cascade->bch dereferences the already-freed pointer. + +Fix this by accessing cascade->bch directly, which is equivalent +since docg3->cascade points back to the same cascade struct, and +is already available as a local variable. This also removes the +now-unused docg3 local variable. + +Fixes: c8ae3f744ddc ("lib/bch: Rework a little bit the exported function names") +Cc: stable@vger.kernel.org +Signed-off-by: James Kim +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/devices/docg3.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c +index 8cb25cfd9c10a..2f82bc7c07931 100644 +--- a/drivers/mtd/devices/docg3.c ++++ b/drivers/mtd/devices/docg3.c +@@ -2049,7 +2049,6 @@ static int __init docg3_probe(struct platform_device *pdev) + static void docg3_release(struct platform_device *pdev) + { + struct docg3_cascade *cascade = platform_get_drvdata(pdev); +- struct docg3 *docg3 = cascade->floors[0]->priv; + int floor; + + doc_unregister_sysfs(pdev, cascade); +@@ -2057,7 +2056,7 @@ static void docg3_release(struct platform_device *pdev) + if (cascade->floors[floor]) + doc_release_device(cascade->floors[floor]); + +- bch_free(docg3->cascade->bch); ++ bch_free(cascade->bch); + } + + #ifdef CONFIG_OF +-- +2.53.0 + diff --git a/queue-6.1/series b/queue-6.1/series index f43c6670fc..0c0979f9b8 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -241,3 +241,6 @@ kvm-nsvm-clear-gif-on-nested-vmexit-invalid.patch kvm-nsvm-clear-tracking-of-l1-l2-nmi-and-soft-irq-on-nested-vmexit.patch kvm-nsvm-add-missing-consistency-check-for-efer-cr0-cr4-and-cs.patch kvm-nsvm-add-missing-consistency-check-for-ncr3-validity.patch +mtd-docg3-convert-to-platform-remove-callback-return.patch +mtd-docg3-fix-use-after-free-in-docg3_release.patch +io_uring-poll-fix-multishot-recv-missing-eof-on-wake.patch diff --git a/queue-6.12/io_uring-poll-fix-multishot-recv-missing-eof-on-wake.patch b/queue-6.12/io_uring-poll-fix-multishot-recv-missing-eof-on-wake.patch new file mode 100644 index 0000000000..f5c42be9a2 --- /dev/null +++ b/queue-6.12/io_uring-poll-fix-multishot-recv-missing-eof-on-wake.patch @@ -0,0 +1,79 @@ +From 2841530afd2c3acb505c06a4f8b2d85a7007d084 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 2 May 2026 01:51:54 +0300 +Subject: io_uring/poll: fix multishot recv missing EOF on wakeup race + +From: Jens Axboe + +[ Upstream commit a68ed2df72131447d131531a08fe4dfcf4fa4653 ] + +When a socket send and shutdown() happen back-to-back, both fire +wake-ups before the receiver's task_work has a chance to run. The first +wake gets poll ownership (poll_refs=1), and the second bumps it to 2. +When io_poll_check_events() runs, it calls io_poll_issue() which does a +recv that reads the data and returns IOU_RETRY. The loop then drains all +accumulated refs (atomic_sub_return(2) -> 0) and exits, even though only +the first event was consumed. Since the shutdown is a persistent state +change, no further wakeups will happen, and the multishot recv can hang +forever. + +Check specifically for HUP in the poll loop, and ensure that another +loop is done to check for status if more than a single poll activation +is pending. This ensures we don't lose the shutdown event. + +Backport notes for linux-6.12.y: + - The do-while body in 6.12.y already places `v &= IO_POLL_REF_MASK;` + just before the while-condition; the upstream patch moves it + earlier so that `v != 1` in the HUP check refers to the ref-count + only. The backport does the same. + - io_poll_issue takes `ts` (struct io_tw_state *) here. + +CVE: CVE-2026-23473 +Cc: stable@vger.kernel.org # 6.12.y +Fixes: dbc2564cfe0f ("io_uring: let fast poll support multishot") +Reported-by: Francis Brosseau +Link: https://github.com/axboe/liburing/issues/1549 +Signed-off-by: Jens Axboe +[backport for linux-6.12.y, verified 2026-05-01] +Signed-off-by: Sasha Levin +--- + io_uring/poll.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/io_uring/poll.c b/io_uring/poll.c +index 63c3ce50cb83e..002f1ae830b8a 100644 +--- a/io_uring/poll.c ++++ b/io_uring/poll.c +@@ -295,6 +295,7 @@ static int io_poll_check_events(struct io_kiocb *req, struct io_tw_state *ts) + atomic_andnot(IO_POLL_RETRY_FLAG, &req->poll_refs); + v &= ~IO_POLL_RETRY_FLAG; + } ++ v &= IO_POLL_REF_MASK; + } + + /* the mask was stashed in __io_poll_execute */ +@@ -327,7 +328,12 @@ static int io_poll_check_events(struct io_kiocb *req, struct io_tw_state *ts) + return IOU_POLL_REMOVE_POLL_USE_RES; + } + } else { +- int ret = io_poll_issue(req, ts); ++ int ret; ++ ++ /* multiple refs and HUP, ensure we loop once more */ ++ if ((req->cqe.res & (POLLHUP | POLLRDHUP)) && v != 1) ++ v--; ++ ret = io_poll_issue(req, ts); + if (ret == IOU_STOP_MULTISHOT) + return IOU_POLL_REMOVE_POLL_USE_RES; + else if (ret == IOU_REQUEUE) +@@ -343,7 +349,6 @@ static int io_poll_check_events(struct io_kiocb *req, struct io_tw_state *ts) + * Release all references, retry if someone tried to restart + * task_work while we were executing it. + */ +- v &= IO_POLL_REF_MASK; + } while (atomic_sub_return(v, &req->poll_refs) & IO_POLL_REF_MASK); + + io_napi_add(req); +-- +2.53.0 + diff --git a/queue-6.12/perf-annotate-use-jump__delete-when-freeing-loongarc.patch b/queue-6.12/perf-annotate-use-jump__delete-when-freeing-loongarc.patch new file mode 100644 index 0000000000..3c98e64263 --- /dev/null +++ b/queue-6.12/perf-annotate-use-jump__delete-when-freeing-loongarc.patch @@ -0,0 +1,112 @@ +From 82fc2a93c6b975676df50cbaed5d561289f5e584 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 May 2026 20:37:17 +0800 +Subject: perf annotate: Use jump__delete when freeing LoongArch jumps + +From: Rong Bao + +[ Upstream commit a355eefc36c4481188249b067832b40a2c45fa5c ] + +Currently, the initialization of loongarch_jump_ops does not contain an +assignment to its .free field. This causes disasm_line__free() to fall +through to ins_ops__delete() for LoongArch jump instructions. + +ins_ops__delete() will free ins_operands.source.raw and +ins_operands.source.name, and these fields overlaps with +ins_operands.jump.raw_comment and ins_operands.jump.raw_func_start. +Since in loongarch_jump__parse(), these two fields are populated by +strchr()-ing the same buffer, trying to free them will lead to undefined +behavior. + +This invalid free usually leads to crashes: + + Process 1712902 (perf) of user 1000 dumped core. + Stack trace of thread 1712902: + #0 0x00007fffef155c58 n/a (libc.so.6 + 0x95c58) + #1 0x00007fffef0f7a94 raise (libc.so.6 + 0x37a94) + #2 0x00007fffef0dd6a8 abort (libc.so.6 + 0x1d6a8) + #3 0x00007fffef145490 n/a (libc.so.6 + 0x85490) + #4 0x00007fffef1646f4 n/a (libc.so.6 + 0xa46f4) + #5 0x00007fffef164718 n/a (libc.so.6 + 0xa4718) + #6 0x00005555583a6764 __zfree (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x106764) + #7 0x000055555854fb70 disasm_line__free (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x2afb70) + #8 0x000055555853d618 annotated_source__purge (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x29d618) + #9 0x000055555852300c __hist_entry__tui_annotate (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x28300c) + #10 0x0000555558526718 do_annotate (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x286718) + #11 0x000055555852ed94 evsel__hists_browse (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x28ed94) + #12 0x000055555831fdd0 cmd_report (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x7fdd0) + #13 0x000055555839b644 handle_internal_command (/home/csmantle/dist/linux-arch/tools/perf/perf + 0xfb644) + #14 0x00005555582fe6ac main (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x5e6ac) + #15 0x00007fffef0ddd90 n/a (libc.so.6 + 0x1dd90) + #16 0x00007fffef0ddf0c __libc_start_main (libc.so.6 + 0x1df0c) + #17 0x00005555582fed10 _start (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x5ed10) + ELF object binary architecture: LoongArch + +... and it can be confirmed with Valgrind: + + ==1721834== Invalid free() / delete / delete[] / realloc() + ==1721834== at 0x4EA9014: free (in /usr/lib/valgrind/vgpreload_memcheck-loongarch64-linux.so) + ==1721834== by 0x4106287: __zfree (zalloc.c:13) + ==1721834== by 0x42ADC8F: disasm_line__free (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x429B737: annotated_source__purge (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x42811EB: __hist_entry__tui_annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x42848D7: do_annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x428CF33: evsel__hists_browse (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== Address 0x7d34303 is 35 bytes inside a block of size 62 alloc'd + ==1721834== at 0x4EA59B8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-loongarch64-linux.so) + ==1721834== by 0x6B80B6F: strdup (strdup.c:42) + ==1721834== by 0x42AD917: disasm_line__new (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x42AE5A3: symbol__disassemble_objdump (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x42AF0A7: symbol__disassemble (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x429B3CF: symbol__annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x429C233: symbol__annotate2 (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x42804D3: __hist_entry__tui_annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x42848D7: do_annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x428CF33: evsel__hists_browse (in /home/csmantle/dist/linux-arch/tools/perf/perf) + +This patch adds the missing free() specialization in loongarch_jump_ops, +which prevents disasm_line__free() from invoking the default cleanup +function. + +Fixes: fb7fd2a14a503b9a ("perf annotate: Move raw_comment and raw_func_start fields out of 'struct ins_operands'") +Cc: stable@vger.kernel.org +Cc: WANG Rui +Cc: Huacai Chen +Cc: WANG Xuerui +Cc: loongarch@lists.linux.dev +Signed-off-by: Rong Bao +Tested-by: WANG Rui +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/arch/loongarch/annotate/instructions.c | 1 + + tools/perf/util/disasm.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/tools/perf/arch/loongarch/annotate/instructions.c b/tools/perf/arch/loongarch/annotate/instructions.c +index ab43b1ab51e3b..e16350155bf1d 100644 +--- a/tools/perf/arch/loongarch/annotate/instructions.c ++++ b/tools/perf/arch/loongarch/annotate/instructions.c +@@ -95,6 +95,7 @@ static int loongarch_jump__parse(struct arch *arch, struct ins_operands *ops, st + } + + static struct ins_ops loongarch_jump_ops = { ++ .free = jump__delete, + .parse = loongarch_jump__parse, + .scnprintf = jump__scnprintf, + }; +diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c +index 8a6f450c6f8e7..8f35232f7f22c 100644 +--- a/tools/perf/util/disasm.c ++++ b/tools/perf/util/disasm.c +@@ -44,6 +44,7 @@ static int jump__scnprintf(struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); + static int call__scnprintf(struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); ++static void jump__delete(struct ins_operands *ops); + + static void ins__sort(struct arch *arch); + static int disasm_line__parse(char *line, const char **namep, char **rawp); +-- +2.53.0 + diff --git a/queue-6.12/series b/queue-6.12/series index bc6d9da8f0..8645de2a46 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -131,3 +131,5 @@ kvm-nsvm-add-missing-consistency-check-for-efer-cr0-cr4-and-cs.patch kvm-nsvm-add-missing-consistency-check-for-ncr3-validity.patch kvm-nsvm-raise-ud-if-unhandled-vmmcall-isn-t-intercepted-by-l1.patch kvm-nsvm-always-intercept-vmmcall-when-l2-is-active.patch +io_uring-poll-fix-multishot-recv-missing-eof-on-wake.patch +perf-annotate-use-jump__delete-when-freeing-loongarc.patch diff --git a/queue-6.18/perf-annotate-use-jump__delete-when-freeing-loongarc.patch b/queue-6.18/perf-annotate-use-jump__delete-when-freeing-loongarc.patch new file mode 100644 index 0000000000..111111ee98 --- /dev/null +++ b/queue-6.18/perf-annotate-use-jump__delete-when-freeing-loongarc.patch @@ -0,0 +1,112 @@ +From 8d184530f4468ea073d678c4c81f1114b6da51d3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 May 2026 20:22:05 +0800 +Subject: perf annotate: Use jump__delete when freeing LoongArch jumps + +From: Rong Bao + +[ Upstream commit a355eefc36c4481188249b067832b40a2c45fa5c ] + +Currently, the initialization of loongarch_jump_ops does not contain an +assignment to its .free field. This causes disasm_line__free() to fall +through to ins_ops__delete() for LoongArch jump instructions. + +ins_ops__delete() will free ins_operands.source.raw and +ins_operands.source.name, and these fields overlaps with +ins_operands.jump.raw_comment and ins_operands.jump.raw_func_start. +Since in loongarch_jump__parse(), these two fields are populated by +strchr()-ing the same buffer, trying to free them will lead to undefined +behavior. + +This invalid free usually leads to crashes: + + Process 1712902 (perf) of user 1000 dumped core. + Stack trace of thread 1712902: + #0 0x00007fffef155c58 n/a (libc.so.6 + 0x95c58) + #1 0x00007fffef0f7a94 raise (libc.so.6 + 0x37a94) + #2 0x00007fffef0dd6a8 abort (libc.so.6 + 0x1d6a8) + #3 0x00007fffef145490 n/a (libc.so.6 + 0x85490) + #4 0x00007fffef1646f4 n/a (libc.so.6 + 0xa46f4) + #5 0x00007fffef164718 n/a (libc.so.6 + 0xa4718) + #6 0x00005555583a6764 __zfree (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x106764) + #7 0x000055555854fb70 disasm_line__free (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x2afb70) + #8 0x000055555853d618 annotated_source__purge (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x29d618) + #9 0x000055555852300c __hist_entry__tui_annotate (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x28300c) + #10 0x0000555558526718 do_annotate (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x286718) + #11 0x000055555852ed94 evsel__hists_browse (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x28ed94) + #12 0x000055555831fdd0 cmd_report (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x7fdd0) + #13 0x000055555839b644 handle_internal_command (/home/csmantle/dist/linux-arch/tools/perf/perf + 0xfb644) + #14 0x00005555582fe6ac main (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x5e6ac) + #15 0x00007fffef0ddd90 n/a (libc.so.6 + 0x1dd90) + #16 0x00007fffef0ddf0c __libc_start_main (libc.so.6 + 0x1df0c) + #17 0x00005555582fed10 _start (/home/csmantle/dist/linux-arch/tools/perf/perf + 0x5ed10) + ELF object binary architecture: LoongArch + +... and it can be confirmed with Valgrind: + + ==1721834== Invalid free() / delete / delete[] / realloc() + ==1721834== at 0x4EA9014: free (in /usr/lib/valgrind/vgpreload_memcheck-loongarch64-linux.so) + ==1721834== by 0x4106287: __zfree (zalloc.c:13) + ==1721834== by 0x42ADC8F: disasm_line__free (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x429B737: annotated_source__purge (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x42811EB: __hist_entry__tui_annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x42848D7: do_annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x428CF33: evsel__hists_browse (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== Address 0x7d34303 is 35 bytes inside a block of size 62 alloc'd + ==1721834== at 0x4EA59B8: malloc (in /usr/lib/valgrind/vgpreload_memcheck-loongarch64-linux.so) + ==1721834== by 0x6B80B6F: strdup (strdup.c:42) + ==1721834== by 0x42AD917: disasm_line__new (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x42AE5A3: symbol__disassemble_objdump (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x42AF0A7: symbol__disassemble (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x429B3CF: symbol__annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x429C233: symbol__annotate2 (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x42804D3: __hist_entry__tui_annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x42848D7: do_annotate (in /home/csmantle/dist/linux-arch/tools/perf/perf) + ==1721834== by 0x428CF33: evsel__hists_browse (in /home/csmantle/dist/linux-arch/tools/perf/perf) + +This patch adds the missing free() specialization in loongarch_jump_ops, +which prevents disasm_line__free() from invoking the default cleanup +function. + +Fixes: fb7fd2a14a503b9a ("perf annotate: Move raw_comment and raw_func_start fields out of 'struct ins_operands'") +Cc: stable@vger.kernel.org +Cc: WANG Rui +Cc: Huacai Chen +Cc: WANG Xuerui +Cc: loongarch@lists.linux.dev +Signed-off-by: Rong Bao +Tested-by: WANG Rui +Signed-off-by: Namhyung Kim +Signed-off-by: Sasha Levin +--- + tools/perf/arch/loongarch/annotate/instructions.c | 1 + + tools/perf/util/disasm.c | 1 + + 2 files changed, 2 insertions(+) + +diff --git a/tools/perf/arch/loongarch/annotate/instructions.c b/tools/perf/arch/loongarch/annotate/instructions.c +index 1c3abb43c8d72..1a0a1dacebc30 100644 +--- a/tools/perf/arch/loongarch/annotate/instructions.c ++++ b/tools/perf/arch/loongarch/annotate/instructions.c +@@ -97,6 +97,7 @@ static int loongarch_jump__parse(struct arch *arch, struct ins_operands *ops, st + } + + static struct ins_ops loongarch_jump_ops = { ++ .free = jump__delete, + .parse = loongarch_jump__parse, + .scnprintf = jump__scnprintf, + }; +diff --git a/tools/perf/util/disasm.c b/tools/perf/util/disasm.c +index b1be847446fea..c513db41137fa 100644 +--- a/tools/perf/util/disasm.c ++++ b/tools/perf/util/disasm.c +@@ -47,6 +47,7 @@ static int jump__scnprintf(struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); + static int call__scnprintf(struct ins *ins, char *bf, size_t size, + struct ins_operands *ops, int max_ins_name); ++static void jump__delete(struct ins_operands *ops); + + static void ins__sort(struct arch *arch); + static int disasm_line__parse(char *line, const char **namep, char **rawp); +-- +2.53.0 + diff --git a/queue-6.18/series b/queue-6.18/series index e00146668e..d3054f5ebb 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -191,3 +191,4 @@ kvm-nsvm-drop-the-non-architectural-consistency-check-for-np_enable.patch kvm-nsvm-add-missing-consistency-check-for-ncr3-validity.patch kvm-nsvm-raise-ud-if-unhandled-vmmcall-isn-t-intercepted-by-l1.patch kvm-nsvm-always-intercept-vmmcall-when-l2-is-active.patch +perf-annotate-use-jump__delete-when-freeing-loongarc.patch diff --git a/queue-6.6/io_uring-poll-fix-multishot-recv-missing-eof-on-wake.patch b/queue-6.6/io_uring-poll-fix-multishot-recv-missing-eof-on-wake.patch new file mode 100644 index 0000000000..b778640a67 --- /dev/null +++ b/queue-6.6/io_uring-poll-fix-multishot-recv-missing-eof-on-wake.patch @@ -0,0 +1,66 @@ +From d4ab1824d0fcf504fc518fc8b04abeecda43b716 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 2 May 2026 01:51:55 +0300 +Subject: io_uring/poll: fix multishot recv missing EOF on wakeup race + +From: Jens Axboe + +[ Upstream commit a68ed2df72131447d131531a08fe4dfcf4fa4653 ] + +When a socket send and shutdown() happen back-to-back, both fire +wake-ups before the receiver's task_work has a chance to run. The first +wake gets poll ownership (poll_refs=1), and the second bumps it to 2. +When io_poll_check_events() runs, it calls io_poll_issue() which does a +recv that reads the data and returns IOU_RETRY. The loop then drains all +accumulated refs (atomic_sub_return(2) -> 0) and exits, even though only +the first event was consumed. Since the shutdown is a persistent state +change, no further wakeups will happen, and the multishot recv can hang +forever. + +Check specifically for HUP in the poll loop, and ensure that another +loop is done to check for status if more than a single poll activation +is pending. This ensures we don't lose the shutdown event. + +Backport notes for linux-6.6.y: + - In 6.6.y the do-while masks v in the while-condition itself + (`atomic_sub_return(v & IO_POLL_REF_MASK, ...) & IO_POLL_REF_MASK`), + so v can carry IO_POLL_RETRY_FLAG / IO_POLL_CANCEL_FLAG bits when + we reach the multishot branch. The HUP check therefore compares + `(v & IO_POLL_REF_MASK) != 1` rather than the upstream + `v != 1`, to avoid reacting to flag bits. + - io_poll_issue takes `ts` (struct io_tw_state *) here. + +CVE: CVE-2026-23473 +Cc: stable@vger.kernel.org # 6.6.y +Fixes: dbc2564cfe0f ("io_uring: let fast poll support multishot") +Reported-by: Francis Brosseau +Link: https://github.com/axboe/liburing/issues/1549 +Signed-off-by: Jens Axboe +[backport for linux-6.6.y, verified 2026-05-01] +Signed-off-by: Sasha Levin +--- + io_uring/poll.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/io_uring/poll.c b/io_uring/poll.c +index a154df4d16204..66a0a9b9950b4 100644 +--- a/io_uring/poll.c ++++ b/io_uring/poll.c +@@ -321,7 +321,13 @@ static int io_poll_check_events(struct io_kiocb *req, struct io_tw_state *ts) + return IOU_POLL_REMOVE_POLL_USE_RES; + } + } else { +- int ret = io_poll_issue(req, ts); ++ int ret; ++ ++ /* multiple refs and HUP, ensure we loop once more */ ++ if ((req->cqe.res & (POLLHUP | POLLRDHUP)) && ++ (v & IO_POLL_REF_MASK) != 1) ++ v--; ++ ret = io_poll_issue(req, ts); + if (ret == IOU_STOP_MULTISHOT) + return IOU_POLL_REMOVE_POLL_USE_RES; + else if (ret == IOU_REQUEUE) +-- +2.53.0 + diff --git a/queue-6.6/mtd-docg3-convert-to-platform-remove-callback-return.patch b/queue-6.6/mtd-docg3-convert-to-platform-remove-callback-return.patch new file mode 100644 index 0000000000..627a7be634 --- /dev/null +++ b/queue-6.6/mtd-docg3-convert-to-platform-remove-callback-return.patch @@ -0,0 +1,68 @@ +From f310e3ad9993b62b234dbb749dfa462cc60d90ba Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 May 2026 19:27:35 -0400 +Subject: mtd: docg3: Convert to platform remove callback returning void +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit eb0cec77d534413a800ec20944a2b1e37cfecdcf ] + +The .remove() callback for a platform driver returns an int which makes +many driver authors wrongly assume it's possible to do error handling by +returning an error code. However the value returned is ignored (apart +from emitting a warning) and this typically results in resource leaks. + +To improve here there is a quest to make the remove callback return +void. In the first step of this quest all drivers are converted to +.remove_new(), which already returns void. Eventually after all drivers +are converted, .remove_new() will be renamed to .remove(). + +Trivially convert this driver from always returning zero in the remove +callback to the void returning variant. + +Signed-off-by: Uwe Kleine-König +Signed-off-by: Miquel Raynal +Acked-by: Tudor Ambarus +Link: https://lore.kernel.org/linux-mtd/20231008200143.196369-5-u.kleine-koenig@pengutronix.de +Stable-dep-of: ca19808bc6fa ("mtd: docg3: fix use-after-free in docg3_release()") +Signed-off-by: Sasha Levin +--- + drivers/mtd/devices/docg3.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c +index 22e73dd6118b9..a2b643af70194 100644 +--- a/drivers/mtd/devices/docg3.c ++++ b/drivers/mtd/devices/docg3.c +@@ -2046,7 +2046,7 @@ static int __init docg3_probe(struct platform_device *pdev) + * + * Returns 0 + */ +-static int docg3_release(struct platform_device *pdev) ++static void docg3_release(struct platform_device *pdev) + { + struct docg3_cascade *cascade = platform_get_drvdata(pdev); + struct docg3 *docg3 = cascade->floors[0]->priv; +@@ -2058,7 +2058,6 @@ static int docg3_release(struct platform_device *pdev) + doc_release_device(cascade->floors[floor]); + + bch_free(docg3->cascade->bch); +- return 0; + } + + #ifdef CONFIG_OF +@@ -2076,7 +2075,7 @@ static struct platform_driver g3_driver = { + }, + .suspend = docg3_suspend, + .resume = docg3_resume, +- .remove = docg3_release, ++ .remove_new = docg3_release, + }; + + module_platform_driver_probe(g3_driver, docg3_probe); +-- +2.53.0 + diff --git a/queue-6.6/mtd-docg3-fix-use-after-free-in-docg3_release.patch b/queue-6.6/mtd-docg3-fix-use-after-free-in-docg3_release.patch new file mode 100644 index 0000000000..41dd9caf48 --- /dev/null +++ b/queue-6.6/mtd-docg3-fix-use-after-free-in-docg3_release.patch @@ -0,0 +1,53 @@ +From 3e3cbc17059bdcc3fa41ea69927fa23b569879ea Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 1 May 2026 19:27:36 -0400 +Subject: mtd: docg3: fix use-after-free in docg3_release() + +From: James Kim + +[ Upstream commit ca19808bc6fac7e29420d8508df569b346b3e339 ] + +In docg3_release(), the docg3 pointer is obtained from +cascade->floors[0]->priv before the loop that calls +doc_release_device() on each floor. doc_release_device() frees the +docg3 struct via kfree(docg3) at line 1881. After the loop, +docg3->cascade->bch dereferences the already-freed pointer. + +Fix this by accessing cascade->bch directly, which is equivalent +since docg3->cascade points back to the same cascade struct, and +is already available as a local variable. This also removes the +now-unused docg3 local variable. + +Fixes: c8ae3f744ddc ("lib/bch: Rework a little bit the exported function names") +Cc: stable@vger.kernel.org +Signed-off-by: James Kim +Signed-off-by: Miquel Raynal +Signed-off-by: Sasha Levin +--- + drivers/mtd/devices/docg3.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c +index a2b643af70194..e37fb11556479 100644 +--- a/drivers/mtd/devices/docg3.c ++++ b/drivers/mtd/devices/docg3.c +@@ -2049,7 +2049,6 @@ static int __init docg3_probe(struct platform_device *pdev) + static void docg3_release(struct platform_device *pdev) + { + struct docg3_cascade *cascade = platform_get_drvdata(pdev); +- struct docg3 *docg3 = cascade->floors[0]->priv; + int floor; + + doc_unregister_sysfs(pdev, cascade); +@@ -2057,7 +2056,7 @@ static void docg3_release(struct platform_device *pdev) + if (cascade->floors[floor]) + doc_release_device(cascade->floors[floor]); + +- bch_free(docg3->cascade->bch); ++ bch_free(cascade->bch); + } + + #ifdef CONFIG_OF +-- +2.53.0 + diff --git a/queue-6.6/series b/queue-6.6/series index 304c4d0157..f6204dbeea 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -105,3 +105,6 @@ kvm-nsvm-clear-eventinj-fields-in-vmcb12-on-nested-vmexit.patch kvm-nsvm-clear-tracking-of-l1-l2-nmi-and-soft-irq-on-nested-vmexit.patch kvm-nsvm-add-missing-consistency-check-for-efer-cr0-cr4-and-cs.patch kvm-nsvm-add-missing-consistency-check-for-ncr3-validity.patch +mtd-docg3-convert-to-platform-remove-callback-return.patch +mtd-docg3-fix-use-after-free-in-docg3_release.patch +io_uring-poll-fix-multishot-recv-missing-eof-on-wake.patch