]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Fix probing the registry for configuration
authorBranden Clark <branden.clark@datadoghq.com>
Tue, 28 Jan 2025 15:50:10 +0000 (16:50 +0100)
committerTomas Mraz <tomas@openssl.org>
Mon, 31 Mar 2025 11:58:47 +0000 (13:58 +0200)
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26566)

(cherry picked from commit 908e0f37288b76132c166364c75cbac9f46deb9f)

crypto/defaults.c

index 09ac5a879990dfc86d101ac2df08feea36c85101..1a4da0f05fc0ef806d30a257fa3714b27fc4841f 100644 (file)
@@ -60,16 +60,16 @@ static char *modulesdirptr = NULL;
  *
  * @return A pointer to a char array containing the registry directories.
  */
-static char *get_windows_regdirs(char *dst, LPCTSTR valuename)
+static char *get_windows_regdirs(char *dst, DWORD dstsizebytes, LPCWSTR valuename)
 {
     char *retval = NULL;
 # ifdef REGISTRY_KEY
-    DWORD keysize;
+    DWORD keysizebytes;
     DWORD ktype;
     HKEY hkey;
     LSTATUS ret;
     DWORD index = 0;
-    LPCTSTR tempstr = NULL;
+    LPCWSTR tempstr = NULL;
 
     ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
                        TEXT(REGISTRY_KEY), KEY_WOW64_32KEY,
@@ -77,26 +77,30 @@ static char *get_windows_regdirs(char *dst, LPCTSTR valuename)
     if (ret != ERROR_SUCCESS)
         goto out;
 
-    ret = RegQueryValueEx(hkey, valuename, NULL, &ktype, NULL,
-                          &keysize);
+    /* Always use wide call so we can avoid extra encoding conversions on the output */
+    ret = RegQueryValueExW(hkey, valuename, NULL, &ktype, NULL,
+                           &keysizebytes);
     if (ret != ERROR_SUCCESS)
         goto out;
-    if (ktype != REG_EXPAND_SZ)
+    if (ktype != REG_EXPAND_SZ && ktype != REG_SZ)
         goto out;
-    if (keysize > MAX_PATH)
+    if (keysizebytes > MAX_PATH * sizeof(WCHAR))
         goto out;
 
-    keysize++;
-    tempstr = OPENSSL_zalloc(keysize * sizeof(TCHAR));
+    /*
+     * RegQueryValueExW does not guarantee the buffer is null terminated,
+     * so we make space for one in the allocation
+     */
+    tempstr = OPENSSL_zalloc(keysizebytes + sizeof(WCHAR));
 
     if (tempstr == NULL)
         goto out;
 
-    if (RegQueryValueEx(hkey, valuename,
-                        NULL, &ktype, (LPBYTE)tempstr, &keysize) != ERROR_SUCCESS)
+    if (RegQueryValueExW(hkey, valuename,
+                         NULL, &ktype, (LPBYTE)tempstr, &keysizebytes) != ERROR_SUCCESS)
         goto out;
 
-    if (!WideCharToMultiByte(CP_UTF8, 0, tempstr, -1, dst, keysize,
+    if (!WideCharToMultiByte(CP_UTF8, 0, tempstr, -1, dst, dstsizebytes,
                              NULL, NULL))
         goto out;
 
@@ -117,9 +121,9 @@ static CRYPTO_ONCE defaults_setup_init = CRYPTO_ONCE_STATIC_INIT;
  */
 DEFINE_RUN_ONCE_STATIC(do_defaults_setup)
 {
-    get_windows_regdirs(openssldir, TEXT("OPENSSLDIR"));
-    get_windows_regdirs(enginesdir, TEXT("ENGINESDIR"));
-    get_windows_regdirs(modulesdir, TEXT("MODULESDIR"));
+    get_windows_regdirs(openssldir, sizeof(openssldir), L"OPENSSLDIR");
+    get_windows_regdirs(enginesdir, sizeof(enginesdir), L"ENGINESDIR");
+    get_windows_regdirs(modulesdir, sizeof(modulesdir), L"MODULESDIR");
 
     /*
      * Set our pointers only if the directories are fetched properly