diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index a8c95eee91b7..aea28e5a5665 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -423,8 +423,14 @@ static void io_submit_init_bio(struct ext4_io_submit *io, /* * bio_alloc will _always_ be able to allocate a bio if * __GFP_DIRECT_RECLAIM is set, see comments for bio_alloc_bioset(). - */ - bio = bio_alloc(bh->b_bdev, BIO_MAX_VECS, REQ_OP_WRITE, GFP_NOIO); + * We must use __GFP_DIRECT_RECLAIM to guarantee the bvec array + * allocation succeeds - BIO_MAX_VECS exceeds BIO_INLINE_VECS so + * bio_alloc_bioset() allocates the bvec array separately, which + * can fail under GFP_NOIO memory pressure, leaving bi_io_vec NULL + * and causing a null-ptr-deref in bio_add_folio(). + */ + bio = bio_alloc(bh->b_bdev, BIO_MAX_VECS, REQ_OP_WRITE, + GFP_NOIO | __GFP_DIRECT_RECLAIM); fscrypt_set_bio_crypt_ctx_bh(bio, bh, GFP_NOIO); bio->bi_iter.bi_sector = bh->b_blocknr * (bh->b_size >> 9); bio->bi_end_io = ext4_end_bio;