TEST: Break out the local dynamic loading code from shlibloadtest.c
authorRichard Levitte <levitte@openssl.org>
Wed, 25 Nov 2020 06:56:08 +0000 (07:56 +0100)
committerRichard Levitte <levitte@openssl.org>
Tue, 1 Dec 2020 10:06:03 +0000 (11:06 +0100)
The result is "simpledynamic.c", or "sd" for short.

Reviewed-by: Tomas Mraz <tmraz@fedoraproject.org>
(Merged from https://github.com/openssl/openssl/pull/13507)

test/build.info
test/shlibloadtest.c
test/simpledynamic.c [new file with mode: 0644]
test/simpledynamic.h [new file with mode: 0644]

index 463e3cd2620e5f35c42264dcba65863d39cc5464..3468be069113e58667df01a3cafbf80eb9521ddf 100644 (file)
@@ -432,7 +432,7 @@ IF[{- !$disabled{tests} -}]
 
   IF[{- !$disabled{shared} -}]
     PROGRAMS{noinst}=shlibloadtest
-    SOURCE[shlibloadtest]=shlibloadtest.c
+    SOURCE[shlibloadtest]=shlibloadtest.c simpledynamic.c
     INCLUDE[shlibloadtest]=../include ../apps/include
   ENDIF
 
index bbac99674e41ea13772e0ae2286b15d5391f0bdd..c879e9a01e62f2821340bdf95e6de64ec0719e49 100644 (file)
@@ -13,7 +13,7 @@
 #include <openssl/opensslv.h>
 #include <openssl/ssl.h>
 #include <openssl/types.h>
-#include "crypto/dso_conf.h"
+#include "simpledynamic.h"
 
 typedef void DSO;
 
@@ -42,67 +42,7 @@ static const char *path_crypto;
 static const char *path_ssl;
 static const char *path_atexit;
 
-#ifdef DSO_DLFCN
-
-# include <dlfcn.h>
-
-# define SHLIB_INIT NULL
-
-typedef void *SHLIB;
-typedef void *SHLIB_SYM;
-
-static int shlib_load(const char *filename, SHLIB *lib)
-{
-    int dl_flags = (RTLD_GLOBAL|RTLD_LAZY);
-#ifdef _AIX
-    if (filename[strlen(filename) - 1] == ')')
-        dl_flags |= RTLD_MEMBER;
-#endif
-    *lib = dlopen(filename, dl_flags);
-    return *lib == NULL ? 0 : 1;
-}
-
-static int shlib_sym(SHLIB lib, const char *symname, SHLIB_SYM *sym)
-{
-    *sym = dlsym(lib, symname);
-    return *sym != NULL;
-}
-
-static int shlib_close(SHLIB lib)
-{
-    return dlclose(lib) != 0 ? 0 : 1;
-}
-#endif
-
-#ifdef DSO_WIN32
-
-# include <windows.h>
-
-# define SHLIB_INIT 0
-
-typedef HINSTANCE SHLIB;
-typedef void *SHLIB_SYM;
-
-static int shlib_load(const char *filename, SHLIB *lib)
-{
-    *lib = LoadLibraryA(filename);
-    return *lib == NULL ? 0 : 1;
-}
-
-static int shlib_sym(SHLIB lib, const char *symname, SHLIB_SYM *sym)
-{
-    *sym = (SHLIB_SYM)GetProcAddress(lib, symname);
-    return *sym != NULL;
-}
-
-static int shlib_close(SHLIB lib)
-{
-    return FreeLibrary(lib) == 0 ? 0 : 1;
-}
-#endif
-
-
-#if defined(DSO_DLFCN) || defined(DSO_WIN32)
+#ifdef SD_INIT
 
 static int atexit_handler_done = 0;
 
@@ -120,12 +60,12 @@ static void atexit_handler(void)
 
 static int test_lib(void)
 {
-    SHLIB ssllib = SHLIB_INIT;
-    SHLIB cryptolib = SHLIB_INIT;
+    SD ssllib = SD_INIT;
+    SD cryptolib = SD_INIT;
     SSL_CTX *ctx;
     union {
         void (*func)(void);
-        SHLIB_SYM sym;
+        SD_SYM sym;
     } symbols[5];
     TLS_method_t myTLS_method;
     SSL_CTX_new_t mySSL_CTX_new;
@@ -142,7 +82,7 @@ static int test_lib(void)
     case DSO_REFTEST:
     case NO_ATEXIT:
     case CRYPTO_FIRST:
-        if (!shlib_load(path_crypto, &cryptolib)) {
+        if (!sd_load(path_crypto, &cryptolib, SD_SHLIB)) {
             fprintf(stderr, "Failed to load libcrypto\n");
             goto end;
         }
@@ -151,13 +91,13 @@ static int test_lib(void)
         /* Fall through */
 
     case SSL_FIRST:
-        if (!shlib_load(path_ssl, &ssllib)) {
+        if (!sd_load(path_ssl, &ssllib, SD_SHLIB)) {
             fprintf(stderr, "Failed to load libssl\n");
             goto end;
         }
         if (test_type != SSL_FIRST)
             break;
-        if (!shlib_load(path_crypto, &cryptolib)) {
+        if (!sd_load(path_crypto, &cryptolib, SD_SHLIB)) {
             fprintf(stderr, "Failed to load libcrypto\n");
             goto end;
         }
@@ -167,7 +107,7 @@ static int test_lib(void)
     if (test_type == NO_ATEXIT) {
         OPENSSL_init_crypto_t myOPENSSL_init_crypto;
 
-        if (!shlib_sym(cryptolib, "OPENSSL_init_crypto", &symbols[0].sym)) {
+        if (!sd_sym(cryptolib, "OPENSSL_init_crypto", &symbols[0].sym)) {
             fprintf(stderr, "Failed to load OPENSSL_init_crypto symbol\n");
             goto end;
         }
@@ -181,9 +121,9 @@ static int test_lib(void)
     if (test_type != JUST_CRYPTO
             && test_type != DSO_REFTEST
             && test_type != NO_ATEXIT) {
-        if (!shlib_sym(ssllib, "TLS_method", &symbols[0].sym)
-                || !shlib_sym(ssllib, "SSL_CTX_new", &symbols[1].sym)
-                || !shlib_sym(ssllib, "SSL_CTX_free", &symbols[2].sym)) {
+        if (!sd_sym(ssllib, "TLS_method", &symbols[0].sym)
+                || !sd_sym(ssllib, "SSL_CTX_new", &symbols[1].sym)
+                || !sd_sym(ssllib, "SSL_CTX_free", &symbols[2].sym)) {
             fprintf(stderr, "Failed to load libssl symbols\n");
             goto end;
         }
@@ -198,11 +138,11 @@ static int test_lib(void)
         mySSL_CTX_free(ctx);
     }
 
-    if (!shlib_sym(cryptolib, "ERR_get_error", &symbols[0].sym)
-           || !shlib_sym(cryptolib, "OPENSSL_version_major", &symbols[1].sym)
-           || !shlib_sym(cryptolib, "OPENSSL_version_minor", &symbols[2].sym)
-           || !shlib_sym(cryptolib, "OPENSSL_version_patch", &symbols[3].sym)
-           || !shlib_sym(cryptolib, "OPENSSL_atexit", &symbols[4].sym)) {
+    if (!sd_sym(cryptolib, "ERR_get_error", &symbols[0].sym)
+           || !sd_sym(cryptolib, "OPENSSL_version_major", &symbols[1].sym)
+           || !sd_sym(cryptolib, "OPENSSL_version_minor", &symbols[2].sym)
+           || !sd_sym(cryptolib, "OPENSSL_version_patch", &symbols[3].sym)
+           || !sd_sym(cryptolib, "OPENSSL_atexit", &symbols[4].sym)) {
         fprintf(stderr, "Failed to load libcrypto symbols\n");
         goto end;
     }
@@ -242,8 +182,8 @@ static int test_lib(void)
          * will always return an error, because DSO_pathbyaddr() is not
          * implemented there.
          */
-        if (!shlib_sym(cryptolib, "DSO_dsobyaddr", &symbols[0].sym)
-                || !shlib_sym(cryptolib, "DSO_free", &symbols[1].sym)) {
+        if (!sd_sym(cryptolib, "DSO_dsobyaddr", &symbols[0].sym)
+                || !sd_sym(cryptolib, "DSO_free", &symbols[1].sym)) {
             fprintf(stderr, "Unable to load DSO symbols\n");
             goto end;
         }
@@ -264,13 +204,13 @@ static int test_lib(void)
 # endif /* DSO_DLFCN */
     }
 
-    if (!shlib_close(cryptolib)) {
+    if (!sd_close(cryptolib)) {
         fprintf(stderr, "Failed to close libcrypto\n");
         goto end;
     }
 
     if (test_type == CRYPTO_FIRST || test_type == SSL_FIRST) {
-        if (!shlib_close(ssllib)) {
+        if (!sd_close(ssllib)) {
             fprintf(stderr, "Failed to close libssl\n");
             goto end;
         }
@@ -338,7 +278,7 @@ int main(int argc, char *argv[])
         return 1;
     }
 
-#if defined(DSO_DLFCN) || defined(DSO_WIN32)
+#ifdef SD_INIT
     if (!test_lib())
         return 1;
 #endif
diff --git a/test/simpledynamic.c b/test/simpledynamic.c
new file mode 100644 (file)
index 0000000..41a910c
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <stdlib.h>              /* For NULL */
+#include <openssl/macros.h>      /* For NON_EMPTY_TRANSLATION_UNIT */
+#include "simpledynamic.h"
+
+#if defined(DSO_DLFCN)
+
+int sd_load(const char *filename, SD *lib, int type)
+{
+    int dl_flags = type;
+#ifdef _AIX
+    if (filename[strlen(filename) - 1] == ')')
+        dl_flags |= RTLD_MEMBER;
+#endif
+    *lib = dlopen(filename, dl_flags);
+    return *lib == NULL ? 0 : 1;
+}
+
+int sd_sym(SD lib, const char *symname, SD_SYM *sym)
+{
+    *sym = dlsym(lib, symname);
+    return *sym != NULL;
+}
+
+int sd_close(SD lib)
+{
+    return dlclose(lib) != 0 ? 0 : 1;
+}
+
+const char *sd_error(void)
+{
+    return dlerror();
+}
+
+#elif defined(DSO_WIN32)
+
+nt sd_load(const char *filename, SD *lib, ossl_unused int type)
+{
+    *lib = LoadLibraryA(filename);
+    return *lib == NULL ? 0 : 1;
+}
+
+int sd_sym(SD lib, const char *symname, SD_SYM *sym)
+{
+    *sym = (SD_SYM)GetProcAddress(lib, symname);
+    return *sym != NULL;
+}
+
+int sd_close(SD lib)
+{
+    return FreeLibrary(lib) == 0 ? 0 : 1;
+}
+
+const char *sd_error(void)
+{
+    static char buffer[255];
+
+    buffer[0] = '\0';
+    FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0,
+                   buffer, sizeof(buffer), NULL);
+    return buffer;
+}
+
+#else
+
+NON_EMPTY_TRANSLATION_UNIT
+
+#endif
diff --git a/test/simpledynamic.h b/test/simpledynamic.h
new file mode 100644 (file)
index 0000000..cc4aed5
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef OSSL_TEST_SIMPLEDYNAMIC_H
+# define OSSL_TEST_SIMPLEDYNAMIC_H
+
+# include "crypto/dso_conf.h"
+
+# if defined(DSO_DLFCN)
+
+#  include <dlfcn.h>
+
+#  define SD_INIT       NULL
+#  define SD_SHLIB      (RTLD_GLOBAL|RTLD_LAZY)
+#  define SD_MODULE     (RTLD_LOCAL|RTLD_NOW)
+
+typedef void *SD;
+typedef void *SD_SYM;
+
+# elif defined(DSO_WIN32)
+
+#  include <windows.h>
+
+#  define SD_INIT       0
+#  define SD_SHLIB      0
+#  define SD_MODULE     0
+
+typedef HINSTANCE SD;
+typedef void *SD_SYM;
+
+# endif
+
+int sd_load(const char *filename, SD *sd, int type);
+int sd_sym(SD sd, const char *symname, SD_SYM *sym);
+int sd_close(SD lib);
+const char *sd_error(void);
+
+#endif