Skip to content

Commit 34b47e3

Browse files
author
Kent Overstreet
committed
bcachefs: Fix UAF in bchfs_read()
Commit 3ba0240 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: 3ba0240 ("bcachefs: Fix silent short reads in data read retry path") Reported-by: [email protected] Signed-off-by: Kent Overstreet <[email protected]>
1 parent 4a22a73 commit 34b47e3

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

fs/bcachefs/fs-io-buffered.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,11 +225,26 @@ static void bchfs_read(struct btree_trans *trans,
225225

226226
bch2_read_extent(trans, rbio, iter.pos,
227227
data_btree, k, offset_into_extent, flags);
228-
swap(rbio->bio.bi_iter.bi_size, bytes);
228+
/*
229+
* Careful there's a landmine here if bch2_read_extent() ever
230+
* starts returning transaction restarts here.
231+
*
232+
* We've changed rbio->bi_iter.bi_size to be "bytes we can read
233+
* from this extent" with the swap call, and we restore it
234+
* below. That restore needs to come before checking for
235+
* errors.
236+
*
237+
* But unlike __bch2_read(), we use the rbio bvec iter, not one
238+
* on the stack, so we can't do the restore right after the
239+
* bch2_read_extent() call: we don't own that iterator anymore
240+
* if BCH_READ_last_fragment is set, since we may have submitted
241+
* that rbio instead of cloning it.
242+
*/
229243

230244
if (flags & BCH_READ_last_fragment)
231245
break;
232246

247+
swap(rbio->bio.bi_iter.bi_size, bytes);
233248
bio_advance(&rbio->bio, bytes);
234249
err:
235250
if (ret &&

0 commit comments

Comments
 (0)