[RFC PATCH 02/10] btrfs: Don't copy encoded read data to user memory when canceled

From: James Houghton

Date: Mon Oct 26 2026 - 18:02:33 EST


btrfs_uring_read_finished() copies the data of an io_uring encoded read
to the submitter's buffers with copy_page_to_iter(). It runs as io_uring
task work, but io_uring may also run it with tw.cancel set from other
contexts when the submitting task can't run it: from a kworker when the
submitting task has exited (io_tctx_fallback_work()), or from
io_cancel_local_task_work() when a DEFER_TASKRUN ring is torn down.

In a kworker, current->mm is NULL, and the copy does not reliably fail:
the user half of the address space belongs to whatever mm happens to be
lazily loaded, if any, so the data may be written into an unrelated
process.

Don't copy the data when the task work is canceled, and complete the
command with -ECANCELED.

Fixes: 34310c442e17 ("btrfs: add io_uring command for encoded reads (ENCODED_READ ioctl)")
Signed-off-by: James Houghton <jthoughton@xxxxxxxxxx>
---
fs/btrfs/ioctl.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index f3e2afe221be..d9044fbd9547 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -4609,6 +4609,16 @@ static void btrfs_uring_read_finished(struct io_tw_req tw_req, io_tw_token_t tw)
goto out;
}

+ /*
+ * If the request is being canceled, e.g. because the submitting task
+ * has exited, this may run from a kworker or in a different task, so
+ * don't copy the data to the submitter's buffers.
+ */
+ if (unlikely(tw.cancel)) {
+ ret = -ECANCELED;
+ goto out;
+ }
+
if (priv->compressed) {
index = 0;
page_offset = 0;
--
2.56.0.307.g5fe7bd680c-goog