diff mbox series

btrfs: send: initialize backref cache earlier

Message ID 25b5197a1d0b81c12acdb79ac0f6d82df287c3c7.1669630263.git.fdmanana@suse.com (mailing list archive)
State New, archived
Headers show
Series btrfs: send: initialize backref cache earlier | expand

Commit Message

Filipe Manana Nov. 28, 2022, 10:12 a.m. UTC
From: Filipe Manana <fdmanana@suse.com>

If we successfully allocated the send context object but ran into an error
after it and before initializing the backref cache, then under the 'out'
label we'll end up calling empty_backref_cache(), which will iterate over
a the backref cache's lru list which was not initialized, triggering
invalid memory accesses.

Fix this by initializing the backref cache immediately after a successful
allocation of the send context.

This fixes a recent patch not yet in Linus' tree, only in misc-next and
linux-next, which has the subject:

  "btrfs: send: cache leaf to roots mapping during backref walking"

Reported-by: syzbot+c423003741c992ccf56b@syzkaller.appspotmail.com
Signed-off-by: Filipe Manana <fdmanana@suse.com>
---
 fs/btrfs/send.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Comments

David Sterba Nov. 28, 2022, 5:05 p.m. UTC | #1
On Mon, Nov 28, 2022 at 10:12:13AM +0000, fdmanana@kernel.org wrote:
> From: Filipe Manana <fdmanana@suse.com>
> 
> If we successfully allocated the send context object but ran into an error
> after it and before initializing the backref cache, then under the 'out'
> label we'll end up calling empty_backref_cache(), which will iterate over
> a the backref cache's lru list which was not initialized, triggering
> invalid memory accesses.
> 
> Fix this by initializing the backref cache immediately after a successful
> allocation of the send context.
> 
> This fixes a recent patch not yet in Linus' tree, only in misc-next and
> linux-next, which has the subject:
> 
>   "btrfs: send: cache leaf to roots mapping during backref walking"

Folded to the patch, thanks.
diff mbox series

Patch

diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 5a00d08c8300..67f7c698ade3 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -8096,6 +8096,9 @@  long btrfs_ioctl_send(struct inode *inode, struct btrfs_ioctl_send_args *arg)
 	INIT_RADIX_TREE(&sctx->name_cache, GFP_KERNEL);
 	INIT_LIST_HEAD(&sctx->name_cache_list);
 
+	INIT_LIST_HEAD(&sctx->backref_cache.lru_list);
+	mt_init(&sctx->backref_cache.entries);
+
 	sctx->flags = arg->flags;
 
 	if (arg->flags & BTRFS_SEND_FLAG_VERSION) {
@@ -8167,9 +8170,6 @@  long btrfs_ioctl_send(struct inode *inode, struct btrfs_ioctl_send_args *arg)
 	sctx->rbtree_new_refs = RB_ROOT;
 	sctx->rbtree_deleted_refs = RB_ROOT;
 
-	INIT_LIST_HEAD(&sctx->backref_cache.lru_list);
-	mt_init(&sctx->backref_cache.entries);
-
 	sctx->clone_roots = kvcalloc(sizeof(*sctx->clone_roots),
 				     arg->clone_sources_count + 1,
 				     GFP_KERNEL);