[PATCH] block: initialize auto integrity buffer opaque

Caleb Sander Mateos posted 1 patch 1 month ago
block/bio-integrity-auto.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
[PATCH] block: initialize auto integrity buffer opaque
Posted by Caleb Sander Mateos 1 month ago
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 <csander@purestorage.com>
Fixes: c546d6f43833 ("block: only zero non-PI metadata tuples in bio_integrity_prep")
---
 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 9850c338548d..605403b52c90 100644
--- a/block/bio-integrity-auto.c
+++ b/block/bio-integrity-auto.c
@@ -107,11 +107,11 @@ bool __bio_integrity_endio(struct bio *bio)
 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;
 
 	if (!bio_sectors(bio))
@@ -137,13 +137,14 @@ bool bio_integrity_prep(struct bio *bio)
 		 */
 		if (bi->flags & BLK_INTEGRITY_NOGENERATE) {
 			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;
 	}
 
@@ -152,11 +153,11 @@ bool bio_integrity_prep(struct bio *bio)
 
 	bid = mempool_alloc(&bid_pool, GFP_NOIO);
 	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);
 
 	if (set_flags) {
 		if (bi->csum_type == BLK_INTEGRITY_CSUM_IP)
-- 
2.45.2
Re: [PATCH] block: initialize auto integrity buffer opaque
Posted by Christoph Hellwig 1 month ago
The subject sounds a little weird.  From looking at the commit
message and the code change I'd expect it to be something like:

block: zero auto integrity buffer when not fully occupied by PI tuple

does that make sense?

> 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().

Yeah, that also makes total sense now.  But maybe split it into a
separate cleanup patch to not detract from the bug fix?
Re: [PATCH] block: initialize auto integrity buffer opaque
Posted by Caleb Sander Mateos 1 month ago
On Thu, Jan 8, 2026 at 5:58 AM Christoph Hellwig <hch@lst.de> wrote:
>
> The subject sounds a little weird.  From looking at the commit
> message and the code change I'd expect it to be something like:
>
> block: zero auto integrity buffer when not fully occupied by PI tuple
>
> does that make sense?

Yes, that sounds fine. "opaque" is how the FS_IOC_GETLBMD_CAP ioctl
refers to the non-PI metadata, but I guess it's not widely used
terminology?

>
> > 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().
>
> Yeah, that also makes total sense now.  But maybe split it into a
> separate cleanup patch to not detract from the bug fix?

Sure.

Thanks,
Caleb
Re: [PATCH] block: initialize auto integrity buffer opaque
Posted by Anuj gupta 1 month ago
> 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 <csander@purestorage.com>
> Fixes: c546d6f43833 ("block: only zero non-PI metadata tuples in bio_integrity_prep")

Makes sense. Thanks for posting the fix.
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>