From 3bb881bdd72c2e14f4f8635493d476ed9fbfb34f Mon Sep 17 00:00:00 2001 From: Caleb Sander Mateos Date: Thu, 8 Jan 2026 10:22:10 -0700 Subject: [PATCH 1/3] block: zero non-PI portion of auto integrity buffer 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 is already initialized. The integrity data is also zeroed if PI generation is disabled via sysfs or the PI tuple size is 0. However, this misses the case where 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. Signed-off-by: Caleb Sander Mateos Fixes: c546d6f43833 ("block: only zero non-PI metadata tuples in bio_integrity_prep") Reviewed-by: Anuj Gupta Reviewed-by: Christoph Hellwig --- block/bio-integrity-auto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/bio-integrity-auto.c b/block/bio-integrity-auto.c index 9850c338548d3..cff025b06be18 100644 --- a/block/bio-integrity-auto.c +++ b/block/bio-integrity-auto.c @@ -140,7 +140,7 @@ bool bio_integrity_prep(struct bio *bio) return true; set_flags = false; gfp |= __GFP_ZERO; - } else if (bi->csum_type == BLK_INTEGRITY_CSUM_NONE) + } else if (bi->metadata_size > bi->pi_tuple_size) gfp |= __GFP_ZERO; break; default: From b1295ad3afc002e1d4052165384c31200fe8f2ba Mon Sep 17 00:00:00 2001 From: Caleb Sander Mateos Date: Thu, 8 Jan 2026 10:22:11 -0700 Subject: [PATCH 2/3] block: replace gfp_t with bool in bio_integrity_prep() Since commit ec7f31b2a2d3 ("block: make bio auto-integrity deadlock safe"), the gfp_t gfp variable in bio_integrity_prep() is no longer passed to an allocation function. It's only used to compute the zero_buffer argument to bio_integrity_alloc_buf(). So change the variable to bool zero_buffer to simplify the code. Signed-off-by: Caleb Sander Mateos Reviewed-by: Anuj Gupta Reviewed-by: Christoph Hellwig --- 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 cff025b06be18..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->metadata_size > bi->pi_tuple_size) - 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); From a4ab1f0c6c89b632df4d2cf302ea1673be127f0e Mon Sep 17 00:00:00 2001 From: Caleb Sander Mateos Date: Thu, 8 Jan 2026 10:22:12 -0700 Subject: [PATCH 3/3] block: use pi_tuple_size in bi_offload_capable() bi_offload_capable() returns whether a block device's metadata size matches its PI tuple size. Use pi_tuple_size instead of switching on csum_type. This makes the code considerably simpler and less branchy. Signed-off-by: Caleb Sander Mateos Reviewed-by: Anuj Gupta Reviewed-by: Christoph Hellwig --- block/bio-integrity-auto.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/block/bio-integrity-auto.c b/block/bio-integrity-auto.c index 605403b52c904..626bbe17eb23b 100644 --- a/block/bio-integrity-auto.c +++ b/block/bio-integrity-auto.c @@ -52,19 +52,7 @@ static bool bip_should_check(struct bio_integrity_payload *bip) static bool bi_offload_capable(struct blk_integrity *bi) { - switch (bi->csum_type) { - case BLK_INTEGRITY_CSUM_CRC64: - return bi->metadata_size == sizeof(struct crc64_pi_tuple); - case BLK_INTEGRITY_CSUM_CRC: - case BLK_INTEGRITY_CSUM_IP: - return bi->metadata_size == sizeof(struct t10_pi_tuple); - default: - pr_warn_once("%s: unknown integrity checksum type:%d\n", - __func__, bi->csum_type); - fallthrough; - case BLK_INTEGRITY_CSUM_NONE: - return false; - } + return bi->metadata_size == bi->pi_tuple_size; } /**