diff options
| author | Ben Cressey <ben@cressey.dev> | 2026-08-20 21:44:58 +0000 |
|---|---|---|
| committer | Mikulas Patocka <mpatocka@redhat.com> | 2026-09-01 13:45:10 +0200 |
| commit | 18d80c77b4c7dd20699e81cedfbbff4e9d198f28 (patch) | |
| tree | ccefe224444ca685314bc4c4a9b14ef8a7c649c4 | |
| parent | 59e6f919d77d72ec79cbf171256f2f7819737580 (diff) | |
| download | linux-next-18d80c77b4c7dd20699e81cedfbbff4e9d198f28.tar.gz linux-next-18d80c77b4c7dd20699e81cedfbbff4e9d198f28.zip | |
dm-integrity: fix infinite loop on discard with large tag size
When integrity_metadata handles a discard, it fills a buffer with
DISCARD_FILLER and writes it over the tags, max_blocks blocks at a
time. If the kmalloc fails, the buffer is the on-stack array
checksums_onstack and max_size is set to HASH_MAX_DIGESTSIZE. So if the
tag size is larger than HASH_MAX_DIGESTSIZE, max_blocks is zero, bi_size
is never decremented and the loop never terminates.
Fix this by using sizeof(checksums_onstack) as max_size. The array has
MAX_TAG_SIZE bytes since commit b93b6643e9b5 ("dm integrity: fix a
crash with unusually large tag size"), so max_blocks is at least 1.
Fixes: 84597a44a9d8 ("dm integrity: add optional discard support")
Cc: stable@vger.kernel.org
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.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c index d4fe85d61d33..5327d7c6a71c 100644 --- a/drivers/md/dm-integrity.c +++ b/drivers/md/dm-integrity.c @@ -1979,7 +1979,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_size = likely(checksums != checksums_onstack) ? PAGE_SIZE : sizeof(checksums_onstack); unsigned int max_blocks = (max_size - extra_space) / ic->tag_size; sector_t sector = dio->range.logical_sector; |
