summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Cressey <ben@cressey.dev>2026-08-20 21:44:57 +0000
committerMikulas Patocka <mpatocka@redhat.com>2026-09-01 13:44:42 +0200
commit59e6f919d77d72ec79cbf171256f2f7819737580 (patch)
tree7210f5d05ea8f9d41befe87ca198ac06521a0d5b
parentb2fd92f016e9d692fd3c8c08d0ee014e9212279d (diff)
dm-integrity: fix buffer overflow with keyed discard
Since commit 68c5c42567bc ("dm-integrity: replace forgeable discard filler with a keyed sector marker"), integrity_metadata computes a checksum for every discarded block into the "checksums" buffer. integrity_sector_checksum always writes the whole digest. So if the tag size is smaller than the digest size, the checksum of the last block that fits into the buffer is written past the end of it. For example, with hmac(sha256) and tag size 16, a 4MiB discard writes 16 bytes past the kmalloc'ed page. Fix this by subtracting extra_space from the buffer size when computing max_blocks, like we do for writes. Fixes: 68c5c42567bc ("dm-integrity: replace forgeable discard filler with a keyed sector marker") Reviewed-by: Jose Fernandez (Anthropic) <jose.fernandez@linux.dev> Signed-off-by: Ben Cressey <ben@cressey.dev> Assisted-by: Claude:unspecified Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
-rw-r--r--drivers/md/dm-integrity.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
index 0370d7d7ce72..d4fe85d61d33 100644
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -1980,7 +1980,7 @@ static void integrity_metadata(struct work_struct *w)
if (unlikely(dio->op == REQ_OP_DISCARD)) {
unsigned int bi_size = dio->bio_details.bi_iter.bi_size;
unsigned int max_size = likely(checksums != checksums_onstack) ? PAGE_SIZE : HASH_MAX_DIGESTSIZE;
- unsigned int max_blocks = max_size / ic->tag_size;
+ unsigned int max_blocks = (max_size - extra_space) / ic->tag_size;
sector_t sector = dio->range.logical_sector;
if (!ic->discard_keyed)