This is a note to let you know that I've just added the patch titled

    dm-integrity: fix buffer overflow with keyed discard

to the 6.12-stable tree which can be found at:
    
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     dm-integrity-fix-buffer-overflow-with-keyed-discard.patch
and it can be found in the queue-6.12 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.



commit c5b48bc3fbf4f6a8b1c26f32dca0bd9cf27ae5bc
Author: Ben Cressey <[email protected]>
Date:   Thu Aug 20 21:44:57 2026 +0000

    dm-integrity: fix buffer overflow with keyed discard
    
    [ Upstream commit 59e6f919d77d72ec79cbf171256f2f7819737580 ]
    
    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) <[email protected]>
    Signed-off-by: Ben Cressey <[email protected]>
    Assisted-by: Claude:unspecified
    Signed-off-by: Mikulas Patocka <[email protected]>
    Signed-off-by: Sasha Levin <[email protected]>

diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
index 513c6d5fd74e1..b1313077de7ab 100644
--- a/drivers/md/dm-integrity.c
+++ b/drivers/md/dm-integrity.c
@@ -1857,7 +1857,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)

Reply via email to