]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix bad length computation in HT_COPY_RAW_KEY_CASE
authorNeil Horman <nhorman@openssl.org>
Tue, 3 Mar 2026 19:47:00 +0000 (14:47 -0500)
committerNikola Pajkovsky <nikolap@openssl.org>
Wed, 4 Mar 2026 07:04:05 +0000 (08:04 +0100)
The new HT_KEY_COPY_RAW fails to account for copy lengths that exceed
the size of the configured buffer in a key, leading to stack overruns on
read.

Rectify that by claming the COPY macro to limit copies to the size of
the buffer

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Nikola Pajkovsky <nikolap@openssl.org>
MergeDate: Wed Mar  4 07:04:07 2026
(Merged from https://github.com/openssl/openssl/pull/30257)

crypto/core_namemap.c
include/internal/hashtable.h

index 32e11e6ab9f0c72d9b45a408ef772a73b9d6b914..cf6f363a51a238f145dd7b2796bbc1e4660a7835 100644 (file)
@@ -154,7 +154,7 @@ int ossl_namemap_name2num(const OSSL_NAMEMAP *namemap, const char *name)
         return 0;
 
     HT_INIT_RAW_KEY(&key);
-    HT_COPY_RAW_KEY_CASE(TO_HT_KEY(&key), name, (int)strlen(name));
+    HT_COPY_RAW_KEY_CASE(TO_HT_KEY(&key), name, strlen(name));
 
     val = ossl_ht_get(namemap->namenum_ht, TO_HT_KEY(&key));
 
@@ -184,7 +184,7 @@ int ossl_namemap_name2num_n(const OSSL_NAMEMAP *namemap,
         name_len = NAMEMAP_NAME_LEN;
 
     HT_INIT_RAW_KEY(&key);
-    HT_COPY_RAW_KEY_CASE(TO_HT_KEY(&key), name, (int)name_len);
+    HT_COPY_RAW_KEY_CASE(TO_HT_KEY(&key), name, name_len);
 
     val = ossl_ht_get(namemap->namenum_ht, TO_HT_KEY(&key));
 
@@ -276,7 +276,7 @@ static int namemap_add_name(OSSL_NAMEMAP *namemap, int number,
     tsan_store(&namemap->max_number, number);
 
     HT_INIT_RAW_KEY(&key);
-    HT_COPY_RAW_KEY_CASE(TO_HT_KEY(&key), name, (int)strlen(name));
+    HT_COPY_RAW_KEY_CASE(TO_HT_KEY(&key), name, strlen(name));
 
     val.value = (void *)(intptr_t)number;
     ret = ossl_ht_insert(namemap->namenum_ht, TO_HT_KEY(&key), &val, NULL);
index 5147aa374e421919a6d98c2b25f5eb994a71233d..75b5c66b067ab4e60d362b27bbb3cb442b933127 100644 (file)
@@ -160,10 +160,13 @@ static ossl_inline ossl_unused int ossl_key_raw_copy(HT_KEY *key, const uint8_t
  * Similar to HT_COPY_RAW_KEY but accepts a character buffer, and copies
  * data while converting case for case insensitive matches
  */
-#define HT_COPY_RAW_KEY_CASE(key, buf, len)                                         \
-    do {                                                                            \
-        ossl_ht_strcase((key), (char *)&((key)->keybuf[(key)->keysize]), buf, len); \
-        (key)->keysize += len;                                                      \
+#define HT_COPY_RAW_KEY_CASE(key, buf, len)                                            \
+    do {                                                                               \
+        size_t tmplen = (size_t)(len);                                                 \
+        if (tmplen > (key)->bufsize - (key)->keysize)                                  \
+            tmplen = (key)->bufsize - (key)->keysize;                                  \
+        ossl_ht_strcase((key), (char *)&((key)->keybuf[(key)->keysize]), buf, tmplen); \
+        (key)->keysize += tmplen;                                                      \
     } while (0)
 
 /*
@@ -313,9 +316,9 @@ static ossl_inline ossl_unused int ossl_key_raw_copy(HT_KEY *key, const uint8_t
 /*
  * Helper function to construct case insensitive keys
  */
-static ossl_inline ossl_unused void ossl_ht_strcase(HT_KEY *key, char *tgt, const char *src, int len)
+static ossl_inline ossl_unused void ossl_ht_strcase(HT_KEY *key, char *tgt, const char *src, size_t len)
 {
-    int i;
+    size_t i;
 #if defined(CHARSET_EBCDIC) && !defined(CHARSET_EBCDIC_TEST)
     const long int case_adjust = ~0x40;
 #else
@@ -331,7 +334,7 @@ static ossl_inline ossl_unused void ossl_ht_strcase(HT_KEY *key, char *tgt, cons
      * we copy more space than we have available
      */
     if (key != NULL && key->keysize + len > key->bufsize)
-        len = (int)(key->bufsize - key->keysize);
+        len = (size_t)(key->bufsize - key->keysize);
 
     for (i = 0; src[i] != '\0' && i < len; i++)
         tgt[i] = case_adjust & src[i];