Fix an endless loop in BN_generate_prime_ex
[oweals/openssl.git] / crypto / dso / dso_win32.c
index 0bbf5b5189ce2ecda5ccb50e4edb2ecf2cf7ea7a..6631d517f4c317c8bdee896c9e8581a73316eb18 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -64,6 +64,7 @@ static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname);
 static char *win32_name_converter(DSO *dso, const char *filename);
 static char *win32_merger(DSO *dso, const char *filespec1,
                           const char *filespec2);
+static int win32_pathbyaddr(void *addr, char *path, int sz);
 static void *win32_globallookup(const char *name);
 
 static const char *openssl_strnchr(const char *string, int c, size_t len);
@@ -78,7 +79,7 @@ static DSO_METHOD dso_meth_win32 = {
     win32_merger,
     NULL,                       /* init */
     NULL,                       /* finish */
-    NULL,                       /* pathbyaddr */
+    win32_pathbyaddr,           /* pathbyaddr */
     win32_globallookup
 };
 
@@ -500,6 +501,111 @@ typedef HANDLE(WINAPI *CREATETOOLHELP32SNAPSHOT) (DWORD, DWORD);
 typedef BOOL(WINAPI *CLOSETOOLHELP32SNAPSHOT) (HANDLE);
 typedef BOOL(WINAPI *MODULE32) (HANDLE, MODULEENTRY32 *);
 
+static int win32_pathbyaddr(void *addr, char *path, int sz)
+{
+    HMODULE dll;
+    HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
+    MODULEENTRY32 me32;
+    CREATETOOLHELP32SNAPSHOT create_snap;
+    CLOSETOOLHELP32SNAPSHOT close_snap;
+    MODULE32 module_first, module_next;
+
+    if (addr == NULL) {
+        union {
+            int (*f) (void *, char *, int);
+            void *p;
+        } t = {
+            win32_pathbyaddr
+        };
+        addr = t.p;
+    }
+
+    dll = LoadLibrary(TEXT(DLLNAME));
+    if (dll == NULL) {
+        DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED);
+        return -1;
+    }
+
+    create_snap = (CREATETOOLHELP32SNAPSHOT)
+        GetProcAddress(dll, "CreateToolhelp32Snapshot");
+    if (create_snap == NULL) {
+        FreeLibrary(dll);
+        DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED);
+        return -1;
+    }
+    /* We take the rest for granted... */
+# ifdef _WIN32_WCE
+    close_snap = (CLOSETOOLHELP32SNAPSHOT)
+        GetProcAddress(dll, "CloseToolhelp32Snapshot");
+# else
+    close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle;
+# endif
+    module_first = (MODULE32) GetProcAddress(dll, "Module32First");
+    module_next = (MODULE32) GetProcAddress(dll, "Module32Next");
+
+    /*
+     * Take a snapshot of current process which includes
+     * list of all involved modules.
+     */
+    hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0);
+    if (hModuleSnap == INVALID_HANDLE_VALUE) {
+        FreeLibrary(dll);
+        DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED);
+        return -1;
+    }
+
+    me32.dwSize = sizeof(me32);
+
+    if (!(*module_first) (hModuleSnap, &me32)) {
+        (*close_snap) (hModuleSnap);
+        FreeLibrary(dll);
+        DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_FAILURE);
+        return -1;
+    }
+
+    /* Enumerate the modules to find one which includes me. */
+    do {
+        if ((uintptr_t) addr >= (uintptr_t) me32.modBaseAddr &&
+            (uintptr_t) addr < (uintptr_t) (me32.modBaseAddr + me32.modBaseSize)) {
+            (*close_snap) (hModuleSnap);
+            FreeLibrary(dll);
+# ifdef _WIN32_WCE
+#  if _WIN32_WCE >= 101
+            return WideCharToMultiByte(CP_ACP, 0, me32.szExePath, -1,
+                                       path, sz, NULL, NULL);
+#  else
+            {
+                int i, len = (int)wcslen(me32.szExePath);
+                if (sz <= 0)
+                    return len + 1;
+                if (len >= sz)
+                    len = sz - 1;
+                for (i = 0; i < len; i++)
+                    path[i] = (char)me32.szExePath[i];
+                path[len++] = '\0';
+                return len;
+            }
+#  endif
+# else
+            {
+                int len = (int)strlen(me32.szExePath);
+                if (sz <= 0)
+                    return len + 1;
+                if (len >= sz)
+                    len = sz - 1;
+                memcpy(path, me32.szExePath, len);
+                path[len++] = '\0';
+                return len;
+            }
+# endif
+        }
+    } while ((*module_next) (hModuleSnap, &me32));
+
+    (*close_snap) (hModuleSnap);
+    FreeLibrary(dll);
+    return 0;
+}
+
 static void *win32_globallookup(const char *name)
 {
     HMODULE dll;