From df515b2c79117232988b9f1bb9600c8b4637b4c4 Mon Sep 17 00:00:00 2001 From: Caleb Sander Mateos Date: Thu, 8 Jan 2026 02:03:59 -0700 Subject: [PATCH] block: initialize auto integrity buffer opaque The auto-generated integrity buffer for writes needs to be fully initialized before being passed to the underlying block device, otherwise the uninitialized memory can be read back by userspace or anyone with physical access to the storage device. If protection information is generated, that portion of the integrity buffer will be initialized. The integrity buffer is also zeroed if PI generation is disabled via sysfs or the PI tuple size is 0. However, this misses the case where the PI is generated and the PI tuple size is nonzero, but the metadata size is larger than the PI tuple. In this case, the remainder ("opaque") of the metadata is left uninitialized. Generalize the BLK_INTEGRITY_CSUM_NONE check to cover any case when the metadata is larger than just the PI tuple. Switch the gfp_t variable to bool zero_buffer since it's only used to compute the zero_buffer argument to bio_integrity_alloc_buf(). Signed-off-by: Caleb Sander Mateos Fixes: c546d6f43833 ("block: only zero non-PI metadata tuples in bio_integrity_prep") Reviewed-by: Anuj Gupta --- block/bio-integrity-auto.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/block/bio-integrity-auto.c b/block/bio-integrity-auto.c index 9850c338548d3..605403b52c904 100644 --- a/block/bio-integrity-auto.c +++ b/block/bio-integrity-auto.c @@ -109,7 +109,7 @@ bool bio_integrity_prep(struct bio *bio) struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk); struct bio_integrity_data *bid; bool set_flags = true; - gfp_t gfp = GFP_NOIO; + bool zero_buffer = false; if (!bi) return true; @@ -139,9 +139,10 @@ bool bio_integrity_prep(struct bio *bio) if (bi_offload_capable(bi)) return true; set_flags = false; - gfp |= __GFP_ZERO; - } else if (bi->csum_type == BLK_INTEGRITY_CSUM_NONE) - gfp |= __GFP_ZERO; + zero_buffer = true; + } else { + zero_buffer = bi->metadata_size > bi->pi_tuple_size; + } break; default: return true; @@ -154,7 +155,7 @@ bool bio_integrity_prep(struct bio *bio) bio_integrity_init(bio, &bid->bip, &bid->bvec, 1); bid->bio = bio; bid->bip.bip_flags |= BIP_BLOCK_INTEGRITY; - bio_integrity_alloc_buf(bio, gfp & __GFP_ZERO); + bio_integrity_alloc_buf(bio, zero_buffer); bip_set_seed(&bid->bip, bio->bi_iter.bi_sector);