X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=test%2Fshlibloadtest.c;h=aad90e6533e2f532c94d858925a4c290f4b5307a;hp=0a4d5f7cd662a18b62cf5c5a19ed933b2dbac7f3;hb=12bd4e141eac30543a790156154deca195ace1b7;hpb=bdd07c78a08bba9e006749bf0ee20dc4a553ab83 diff --git a/test/shlibloadtest.c b/test/shlibloadtest.c index 0a4d5f7cd6..aad90e6533 100644 --- a/test/shlibloadtest.c +++ b/test/shlibloadtest.c @@ -1,5 +1,5 @@ /* - * Copyright 2016 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,30 +13,38 @@ #include #include #include +#include "internal/dso_conf.h" #include "testutil.h" -#if !defined(DSO_DLFCN) && !defined(DSO_WIN32) -int main(void) -{ - TEST_info("Not implemented on this platform\n"); - return 0; -} - -#else +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)(void), int flags); +typedef int (*DSO_free_t)(DSO *dso); + +typedef enum test_types_en { + CRYPTO_FIRST, + SSL_FIRST, + JUST_CRYPTO, + DSO_REFTEST +} TEST_TYPE; + +static TEST_TYPE test_type; +static const char *path_crypto; +static const char *path_ssl; #ifdef DSO_DLFCN # include +# define SHLIB_INIT NULL + typedef void *SHLIB; typedef void *SHLIB_SYM; -# define SHLIB_INIT NULL static int shlib_load(const char *filename, SHLIB *lib) { @@ -60,9 +68,10 @@ static int shlib_close(SHLIB lib) # include +# define SHLIB_INIT 0 + typedef HINSTANCE SHLIB; typedef void *SHLIB_SYM; -# define SHLIB_INIT 0 static int shlib_load(const char *filename, SHLIB *lib) { @@ -82,15 +91,8 @@ static int shlib_close(SHLIB lib) } #endif -typedef enum test_types_en { - CRYPTO_FIRST, - SSL_FIRST, - JUST_CRYPTO -} TEST_TYPE; -static TEST_TYPE test_type; -static const char *path_crypto; -static const char *path_ssl; +#if defined(DSO_DLFCN) || defined(DSO_WIN32) static int test_lib(void) { @@ -117,14 +119,19 @@ static int test_lib(void) if (!TEST_true(shlib_load(path_crypto, &cryptolib)) || !TEST_true(shlib_load(path_ssl, &ssllib))) goto end; + break; case SSL_FIRST: if (!TEST_true(shlib_load(path_ssl, &ssllib)) || !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))) @@ -144,10 +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; + 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 (*)(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))) @@ -157,39 +207,47 @@ static int test_lib(void) if (!TEST_true(shlib_close(cryptolib)) || !TEST_true(shlib_close(ssllib))) goto end; + break; case SSL_FIRST: if (!TEST_true(shlib_close(ssllib)) || !TEST_true(shlib_close(cryptolib))) goto end; break; + case DSO_REFTEST: + if (!TEST_true(shlib_close(cryptolib))) + goto end; + break; } result = 1; end: return result; } +#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); - return run_tests(argv[0]); -} #endif + return 1; +}