FAILED: patch "[PATCH] btrfs: fix use-after-free waiting for encoded read endios" failed to apply to 6.6-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x d29662695ed7c015521e5fc9387df25aab192a2e
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024123055-unholy-vice-e16b@gregkh' --subject-prefix 'PATCH 6.6.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From d29662695ed7c015521e5fc9387df25aab192a2e Mon Sep 17 00:00:00 2001
From: Johannes Thumshirn <[email protected]>
Date: Wed, 13 Nov 2024 18:16:49 +0100
Subject: [PATCH] btrfs: fix use-after-free waiting for encoded read endios
Fix a use-after-free in the I/O completion path for encoded reads by using a completion instead of a wait_queue for synchronizing the destruction of 'struct btrfs_encoded_read_private'.
fs/btrfs/inode.c +11 -11
@@ -9078,9 +9078,9 @@ static ssize_t btrfs_encoded_read_inline( }struct btrfs_encoded_read_private { -wait_queue_head_t wait; +struct completion done;void *uring_ctx; -atomic_t pending; +refcount_t pending_refs;blk_status_t status; };
@@ -9099,14 +9099,14 @@ static void btrfs_encoded_read_endio(struct btrfs_bio *bbio)*/ WRITE_ONCE (priv->status, bbio->bio.bi_status); } -if (atomic_dec_and_test (&priv->pending)) { +if (refcount_dec_and_test (&priv->pending_refs)) {int err =blk_status_to_errno (READ_ONCE (priv->status));if (priv->uring_ctx) {btrfs_uring_read_extent_endio (priv->uring_ctx, err);kfree (priv); }else { -wake_up (&priv->wait); +complete (&priv->done); } }bio_put (&bbio->bio);
@@ -9126,8 +9126,8 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode,if (!priv)return -ENOMEM ; -init_waitqueue_head (&priv->wait); -atomic_set (&priv->pending,1 ); +init_completion (&priv->done); +refcount_set (&priv->pending_refs,1 ); priv->status =0 ; priv->uring_ctx = uring_ctx;
@@ -9140,7 +9140,7 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode,size_t bytes =min_t (u64, disk_io_size,PAGE_SIZE );if (bio_add_page (&bbio->bio, pages[i], bytes,0 ) < bytes) { -atomic_inc (&priv->pending); +refcount_inc (&priv->pending_refs);btrfs_submit_bbio (bbio,0 ); bbio = btrfs_bio_alloc(BIO_MAX_VECS, REQ_OP_READ, fs_info,
@@ -9155,11 +9155,11 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode, disk_io_size -= bytes; }while (disk_io_size); -atomic_inc (&priv->pending); +refcount_inc (&priv->pending_refs);btrfs_submit_bbio (bbio,0 );if (uring_ctx) { -if (atomic_dec_return (&priv->pending) ==0 ) { +if (refcount_dec_and_test (&priv->pending_refs)) { ret =blk_status_to_errno (READ_ONCE (priv->status));btrfs_uring_read_extent_endio (uring_ctx, ret);kfree (priv);
@@ -9168,8 +9168,8 @@ int btrfs_encoded_read_regular_fill_pages(struct btrfs_inode *inode,return -EIOCBQUEUED ; }else { -if (atomic_dec_return (&priv->pending) !=0 ) -io_wait_event (priv->wait, !atomic_read (&priv->pending)); +if (!refcount_dec_and_test (&priv->pending_refs)) +wait_for_completion_io (&priv->done);/* See btrfs_encoded_read_endio() for ordering. */ ret =blk_status_to_errno (READ_ONCE (priv->status));kfree (priv);