X-Git-Url: https://git.openssl.org/?p=openssl.git;a=blobdiff_plain;f=test%2Fshlibloadtest.c;h=a8cf8e7fde10e21a087c28a2e565526d04f7cdd3;hp=c57ca8f202209c576a800747389296fa5a696f89;hb=c6d38183d6754b0a7b90527d085a500680e7d2ea;hpb=5511101ad86fdd5bc3ad4f27143e93ae14737bfe diff --git a/test/shlibloadtest.c b/test/shlibloadtest.c index c57ca8f202..a8cf8e7fde 100644 --- a/test/shlibloadtest.c +++ b/test/shlibloadtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2016-2018 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 @@ -13,18 +13,24 @@ #include #include #include +#include "internal/dso_conf.h" #include "testutil.h" +typedef void DSO; + typedef const SSL_METHOD * (*TLS_method_t)(void); typedef SSL_CTX * (*SSL_CTX_new_t)(const SSL_METHOD *meth); typedef void (*SSL_CTX_free_t)(SSL_CTX *); typedef unsigned long (*ERR_get_error_t)(void); typedef unsigned long (*OpenSSL_version_num_t)(void); +typedef DSO * (*DSO_dsobyaddr_t)(void (*addr)(), int flags); +typedef int (*DSO_free_t)(DSO *dso); typedef enum test_types_en { CRYPTO_FIRST, SSL_FIRST, - JUST_CRYPTO + JUST_CRYPTO, + DSO_REFTEST } TEST_TYPE; static TEST_TYPE test_type; @@ -52,12 +58,10 @@ static int shlib_sym(SHLIB lib, const char *symname, SHLIB_SYM *sym) return *sym != NULL; } -# ifdef OPENSSL_USE_NODELETE static int shlib_close(SHLIB lib) { return dlclose(lib) != 0 ? 0 : 1; } -# endif #endif #ifdef DSO_WIN32 @@ -81,12 +85,10 @@ static int shlib_sym(SHLIB lib, const char *symname, SHLIB_SYM *sym) return *sym != NULL; } -# ifdef OPENSSL_USE_NODELETE static int shlib_close(SHLIB lib) { return FreeLibrary(lib) == 0 ? 0 : 1; } -# endif #endif @@ -123,9 +125,13 @@ static int test_lib(void) || !TEST_true(shlib_load(path_crypto, &cryptolib))) goto end; break; + case DSO_REFTEST: + if (!TEST_true(shlib_load(path_crypto, &cryptolib))) + goto end; + break; } - if (test_type != JUST_CRYPTO) { + if (test_type != JUST_CRYPTO && test_type != DSO_REFTEST) { if (!TEST_true(shlib_sym(ssllib, "TLS_method", &symbols[0].sym)) || !TEST_true(shlib_sym(ssllib, "SSL_CTX_new", &symbols[1].sym)) || !TEST_true(shlib_sym(ssllib, "SSL_CTX_free", &symbols[2].sym))) @@ -145,11 +151,53 @@ static int test_lib(void) myERR_get_error = (ERR_get_error_t)symbols[0].func; if (!TEST_int_eq(myERR_get_error(), 0)) goto end; + + /* + * The bits that COMPATIBILITY_MASK lets through MUST be the same in + * the library and in the application. + * The bits that are masked away MUST be a larger or equal number in + * the library compared to the application. + */ +# define COMPATIBILITY_MASK 0xfff00000L myOpenSSL_version_num = (OpenSSL_version_num_t)symbols[1].func; - if (!TEST_int_eq(myOpenSSL_version_num(), OPENSSL_VERSION_NUMBER)) + if (!TEST_int_eq(myOpenSSL_version_num() & COMPATIBILITY_MASK, + OPENSSL_VERSION_NUMBER & COMPATIBILITY_MASK)) + goto end; + if (!TEST_int_ge(myOpenSSL_version_num() & ~COMPATIBILITY_MASK, + OPENSSL_VERSION_NUMBER & ~COMPATIBILITY_MASK)) goto end; -#ifdef OPENSSL_USE_NODELETE + if (test_type == DSO_REFTEST) { +# ifdef DSO_DLFCN + DSO_dsobyaddr_t myDSO_dsobyaddr; + DSO_free_t myDSO_free; + + /* + * This is resembling the code used in ossl_init_base() and + * OPENSSL_atexit() to block unloading the library after dlclose(). + * We are not testing this on Windows, because it is done there in a + * completely different way. Especially as a call to DSO_dsobyaddr() + * will always return an error, because DSO_pathbyaddr() is not + * implemented there. + */ + if (!TEST_true(shlib_sym(cryptolib, "DSO_dsobyaddr", &symbols[0].sym)) + || !TEST_true(shlib_sym(cryptolib, "DSO_free", + &symbols[1].sym))) + goto end; + + myDSO_dsobyaddr = (DSO_dsobyaddr_t)symbols[0].func; + myDSO_free = (DSO_free_t)symbols[1].func; + + { + DSO *hndl; + /* use known symbol from crypto module */ + if (!TEST_ptr(hndl = myDSO_dsobyaddr((void (*)())ERR_get_error, 0))) + goto end; + myDSO_free(hndl); + } +# endif /* DSO_DLFCN */ + } + switch (test_type) { case JUST_CRYPTO: if (!TEST_true(shlib_close(cryptolib))) @@ -165,8 +213,11 @@ static int test_lib(void) || !TEST_true(shlib_close(cryptolib))) goto end; break; + case DSO_REFTEST: + if (!TEST_true(shlib_close(cryptolib))) + goto end; + break; } -#endif result = 1; end: @@ -175,28 +226,28 @@ end: #endif -int test_main(int argc, char **argv) +int setup_tests(void) { - if (argc != 4) { - TEST_error("Unexpected number of arguments"); - return EXIT_FAILURE; - } + const char *p = test_get_argument(0); - if (strcmp(argv[1], "-crypto_first") == 0) { + if (strcmp(p, "-crypto_first") == 0) { test_type = CRYPTO_FIRST; - } else if (strcmp(argv[1], "-ssl_first") == 0) { + } else if (strcmp(p, "-ssl_first") == 0) { test_type = SSL_FIRST; - } else if (strcmp(argv[1], "-just_crypto") == 0) { + } else if (strcmp(p, "-just_crypto") == 0) { + test_type = JUST_CRYPTO; + } else if (strcmp(p, "-dso_ref") == 0) { test_type = JUST_CRYPTO; } else { TEST_error("Unrecognised argument"); - return EXIT_FAILURE; + return 0; } - path_crypto = argv[2]; - path_ssl = argv[3]; + if (!TEST_ptr(path_crypto = test_get_argument(1)) + || !TEST_ptr(path_ssl = test_get_argument(2))) + return 0; #if defined(DSO_DLFCN) || defined(DSO_WIN32) ADD_TEST(test_lib); #endif - return run_tests(argv[0]); + return 1; }