If we use bio_for_each_folio_all on an empty bio, it will access the first bio vector unconditionally (it is uninitialized) and it may crash depending on the uninitialized data. This patch fixes it by checking the parameter "i" against "bio->bi_vcnt" and returning NULL fi->folio if it is out of range. The patch also drops the test "if (fi->_i + 1 < bio->bi_vcnt)" from bio_next_folio because the same condition is already being checked in bio_first_folio. Signed-off-by: Mikulas Patocka <mpatocka@xxxxxxxxxx> --- include/linux/bio.h | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) Index: linux-2.6/include/linux/bio.h =================================================================== --- linux-2.6.orig/include/linux/bio.h +++ linux-2.6/include/linux/bio.h @@ -279,15 +279,19 @@ struct folio_iter { static inline void bio_first_folio(struct folio_iter *fi, struct bio *bio, int i) { - struct bio_vec *bvec = bio_first_bvec_all(bio) + i; + if (i < bio->bi_vcnt) { + struct bio_vec *bvec = bio_first_bvec_all(bio) + i; - fi->folio = page_folio(bvec->bv_page); - fi->offset = bvec->bv_offset + - PAGE_SIZE * (bvec->bv_page - &fi->folio->page); - fi->_seg_count = bvec->bv_len; - fi->length = min(folio_size(fi->folio) - fi->offset, fi->_seg_count); - fi->_next = folio_next(fi->folio); - fi->_i = i; + fi->folio = page_folio(bvec->bv_page); + fi->offset = bvec->bv_offset + + PAGE_SIZE * (bvec->bv_page - &fi->folio->page); + fi->_seg_count = bvec->bv_len; + fi->length = min(folio_size(fi->folio) - fi->offset, fi->_seg_count); + fi->_next = folio_next(fi->folio); + fi->_i = i; + } else { + fi->folio = NULL; + } } static inline void bio_next_folio(struct folio_iter *fi, struct bio *bio) @@ -298,10 +302,8 @@ static inline void bio_next_folio(struct fi->offset = 0; fi->length = min(folio_size(fi->folio), fi->_seg_count); fi->_next = folio_next(fi->folio); - } else if (fi->_i + 1 < bio->bi_vcnt) { - bio_first_folio(fi, bio, fi->_i + 1); } else { - fi->folio = NULL; + bio_first_folio(fi, bio, fi->_i + 1); } }