On Thu, Jun 19, 2025 at 11:17:37PM +0200, Milan Broz wrote:
>
> : Call Trace:
> :  crypto_shash_export+0x65/0xc0
> :  crypt_iv_lmk_one+0x106/0x1a0 [dm_crypt]

Thanks for the report.  The problem is that crypt_iv_lmk_one is
calling crypto_shash_export using a buffer that is less than the
size as returned by crypto_shash_statesize.

The easiest fix is to expand the buffer to HASH_MAX_STATESIZE:

---8<---
The output buffer size of of crypto_shash_export is returned by
crypto_shash_statesize.  Alternatively HASH_MAX_STATESIZE may be
used for stack buffers.

Fixes: 8cf4c341f193 ("crypto: md5-generic - Use API partial block handling")
Reported-by: Milan Broz <gmazyl...@gmail.com>
Signed-off-by: Herbert Xu <herb...@gondor.apana.org.au>

diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 9dfdb63220d7..cb4617df7356 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -517,7 +517,10 @@ static int crypt_iv_lmk_one(struct crypt_config *cc, u8 
*iv,
 {
        struct iv_lmk_private *lmk = &cc->iv_gen_private.lmk;
        SHASH_DESC_ON_STACK(desc, lmk->hash_tfm);
-       struct md5_state md5state;
+       union {
+               struct md5_state md5state;
+               u8 state[HASH_MAX_STATESIZE];
+       } u;
        __le32 buf[4];
        int i, r;
 
@@ -548,13 +551,13 @@ static int crypt_iv_lmk_one(struct crypt_config *cc, u8 
*iv,
                return r;
 
        /* No MD5 padding here */
-       r = crypto_shash_export(desc, &md5state);
+       r = crypto_shash_export(desc, &u.md5state);
        if (r)
                return r;
 
        for (i = 0; i < MD5_HASH_WORDS; i++)
-               __cpu_to_le32s(&md5state.hash[i]);
-       memcpy(iv, &md5state.hash, cc->iv_size);
+               __cpu_to_le32s(&u.md5state.hash[i]);
+       memcpy(iv, &u.md5state.hash, cc->iv_size);
 
        return 0;
 }
-- 
Email: Herbert Xu <herb...@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

Reply via email to