Commit 13bcff0ab2 for openssl.org

commit 13bcff0ab2f5c55696c92cc6b3480d94f80e8e3b
Author: Daniel Kubec <kubec@openssl.foundation>
Date:   Thu Jul 23 03:04:33 2026 +0200

    Fix heap buffer overflow (8-byte OOB write) in AES-WRAP-PAD unwrap

    On its integrity-failure paths that primitive writes and cleanses up to inlen
    bytes of the output buffer. Size the buffer for that worst case so a failed
    unwrap cannot write past the allocation.

    Fixes CVE-2026-63072

    Reviewed-by: Milan Broz <mbroz@openssl.org>
    Reviewed-by: Norbert Pocs <norbertp@openssl.org>
    Merge-date: Mon Aug 24 14:37:11 2026

diff --git a/crypto/cms/cms_kari.c b/crypto/cms/cms_kari.c
index bae78b45da..c1ad315224 100644
--- a/crypto/cms/cms_kari.c
+++ b/crypto/cms/cms_kari.c
@@ -212,6 +212,7 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
     unsigned char *out = NULL;
     size_t out_alloc_len = 0;
     int outlen;
+    size_t outsize;

     keklen = EVP_CIPHER_CTX_get_key_length(kari->ctx);
     if (keklen > EVP_MAX_KEY_LENGTH || inlen > INT_MAX)
@@ -225,7 +226,13 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
     /* obtain output length of ciphered key */
     if (!EVP_CipherUpdate(kari->ctx, NULL, &outlen, in, (int)inlen))
         goto err;
-    out = OPENSSL_malloc(outlen);
+    /*
+     * On its integrity-failure paths that primitive writes and cleanses up to
+     * inlen bytes of the output buffer. Size the buffer for that worst case so
+     * a failed unwrap cannot write past the allocation.
+     */
+    outsize = (size_t)outlen < inlen ? inlen : (size_t)outlen;
+    out = OPENSSL_malloc(outsize);
     if (out == NULL)
         goto err;
     out_alloc_len = (size_t)outlen;
diff --git a/crypto/cms/cms_kemri.c b/crypto/cms/cms_kemri.c
index 419ce3e437..1a3ec8ddf4 100644
--- a/crypto/cms/cms_kemri.c
+++ b/crypto/cms/cms_kemri.c
@@ -264,6 +264,7 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
     unsigned char *out = NULL;
     int outlen = 0;
     int rv = 0;
+    size_t outsize;

     if (keklen > sizeof(kek)) {
         ERR_raise(ERR_LIB_CMS, CMS_R_INVALID_KEY_LENGTH);
@@ -282,7 +283,13 @@ static int cms_kek_cipher(unsigned char **pout, size_t *poutlen,
     /* obtain output length of ciphered key */
     if (!EVP_CipherUpdate(kemri->ctx, NULL, &outlen, in, (int)inlen))
         goto err;
-    out = OPENSSL_malloc(outlen);
+    /*
+     * On its integrity-failure paths that primitive writes and cleanses up to
+     * inlen bytes of the output buffer. Size the buffer for that worst case so
+     * a failed unwrap cannot write past the allocation.
+     */
+    outsize = (size_t)outlen < inlen ? inlen : (size_t)outlen;
+    out = OPENSSL_malloc(outsize);
     if (out == NULL)
         goto err;
     if (!EVP_CipherUpdate(kemri->ctx, out, &outlen, in, (int)inlen))