lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <ic4vadw4umsgdkx7mopnq2gxf33eoglf3ln6kfs4n7kihr6jz3@zmq2iyakast4>
Date: Sat, 5 Apr 2025 12:45:04 -0400
From: Kent Overstreet <kent.overstreet@...ux.dev>
To: syzbot <syzbot+2deb10b8dc9aae6fab67@...kaller.appspotmail.com>
Cc: linux-bcachefs@...r.kernel.org, linux-kernel@...r.kernel.org, 
	syzkaller-bugs@...glegroups.com
Subject: Re: [syzbot] [bcachefs?] KASAN: slab-use-after-free Read in
 bchfs_read

#syz test

commit 7dbcd51dd047c38515b76a626f6db911b360383b
Author: Kent Overstreet <kent.overstreet@...ux.dev>
Date:   Sat Apr 5 12:26:43 2025 -0400

    bcachefs: Fix UAF in bchfs_read()
    
    Commit 3ba0240a8789 fixed a bug in the read retry path in __bch2_read(),
    and changed bchfs_read() to match - to avoid a landmine if
    bch2_read_extent() ever starts returning transaction restarts.
    
    But that was incorrect, because bchfs_read() doesn't use a separate
    stack allocated bvec_iter, it uses the one in the rbio being submitted.
    
    Add a comment explaining the issue, and revert the buggy change.
    
    Fixes: 3ba0240a8789 ("bcachefs: Fix silent short reads in data read retry path")
    Reported-by: syzbot+2deb10b8dc9aae6fab67@...kaller.appspotmail.com
    Signed-off-by: Kent Overstreet <kent.overstreet@...ux.dev>

diff --git a/fs/bcachefs/fs-io-buffered.c b/fs/bcachefs/fs-io-buffered.c
index 19d4599918dc..e3a75dcca60c 100644
--- a/fs/bcachefs/fs-io-buffered.c
+++ b/fs/bcachefs/fs-io-buffered.c
@@ -225,11 +225,26 @@ static void bchfs_read(struct btree_trans *trans,
 
 		bch2_read_extent(trans, rbio, iter.pos,
 				 data_btree, k, offset_into_extent, flags);
-		swap(rbio->bio.bi_iter.bi_size, bytes);
+		/*
+		 * Careful there's a landmine here if bch2_read_extent() ever
+		 * starts returning transaction restarts here.
+		 *
+		 * We've changed rbio->bi_iter.bi_size to be "bytes we can read
+		 * from this extent" with the swap call, and we restore it
+		 * below. That restore needs to come before checking for
+		 * errors.
+		 *
+		 * But unlike __bch2_read(), we use the rbio bvec iter, not one
+		 * on the stack, so we can't do the restore right after the
+		 * bch2_read_extent() call: we don't own that iterator anymore
+		 * if BCH_READ_last_fragment is set, since we may have submitted
+		 * that rbio instead of cloning it.
+		 */
 
 		if (flags & BCH_READ_last_fragment)
 			break;
 
+		swap(rbio->bio.bi_iter.bi_size, bytes);
 		bio_advance(&rbio->bio, bytes);
 err:
 		if (ret &&

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ