Re: [syzbot] [block?] general protection fault in bio_alloc_bioset
From: Edward Adam Davis
Date: Sat Mar 21 2026 - 02:10:30 EST
#syz test
diff --git a/block/bio.c b/block/bio.c
index 5057047194c4..bbbcd1d2f85d 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -530,11 +530,13 @@ struct bio *bio_alloc_bioset(struct block_device *bdev, unsigned short nr_vecs,
struct bio *bio = NULL;
gfp_t saved_gfp = gfp;
void *p;
+ static DEFINE_MUTEX(bio_alloc_lock);
/* should not use nobvec bioset for nr_vecs > 0 */
if (WARN_ON_ONCE(!mempool_initialized(&bs->bvec_pool) && nr_vecs > 0))
return NULL;
+ mutex_lock(&bio_alloc_lock);
gfp = try_alloc_gfp(gfp);
if (bs->cache && nr_vecs <= BIO_INLINE_VECS) {
/*
@@ -570,8 +572,10 @@ struct bio *bio_alloc_bioset(struct block_device *bdev, unsigned short nr_vecs,
* Give up if we are not allow to sleep as non-blocking mempool
* allocations just go back to the slab allocation.
*/
- if (!(saved_gfp & __GFP_DIRECT_RECLAIM))
+ if (!(saved_gfp & __GFP_DIRECT_RECLAIM)) {
+ mutex_unlock(&bio_alloc_lock);
return NULL;
+ }
punt_bios_to_rescuer(bs);
@@ -594,6 +598,7 @@ struct bio *bio_alloc_bioset(struct block_device *bdev, unsigned short nr_vecs,
else
bio_init(bio, bdev, bvecs, nr_vecs, opf);
bio->bi_pool = bs;
+ mutex_unlock(&bio_alloc_lock);
return bio;
}
EXPORT_SYMBOL(bio_alloc_bioset);