diff options
Diffstat (limited to 'test/p_test.c')
-rw-r--r-- | test/p_test.c | 73 |
1 files changed, 68 insertions, 5 deletions
diff --git a/test/p_test.c b/test/p_test.c index dfd62ebd83..57597086aa 100644 --- a/test/p_test.c +++ b/test/p_test.c @@ -26,11 +26,22 @@ # define OSSL_provider_init PROVIDER_INIT_FUNCTION_NAME #endif +#include "e_os.h" #include <openssl/core.h> #include <openssl/core_dispatch.h> +#include <openssl/err.h> + +typedef struct p_test_ctx { + char *thisfile; + char *thisfunc; + const OSSL_CORE_HANDLE *handle; +} P_TEST_CTX; static OSSL_FUNC_core_gettable_params_fn *c_gettable_params = NULL; static OSSL_FUNC_core_get_params_fn *c_get_params = NULL; +static OSSL_FUNC_core_new_error_fn *c_new_error; +static OSSL_FUNC_core_set_error_debug_fn *c_set_error_debug; +static OSSL_FUNC_core_vset_error_fn *c_vset_error; /* Tell the core what params we provide and what type they are */ static const OSSL_PARAM p_param_types[] = { @@ -42,15 +53,17 @@ static const OSSL_PARAM p_param_types[] = { static OSSL_FUNC_provider_gettable_params_fn p_gettable_params; static OSSL_FUNC_provider_get_params_fn p_get_params; static OSSL_FUNC_provider_get_reason_strings_fn p_get_reason_strings; +static OSSL_FUNC_provider_teardown_fn p_teardown; static const OSSL_PARAM *p_gettable_params(void *_) { return p_param_types; } -static int p_get_params(void *vhand, OSSL_PARAM params[]) +static int p_get_params(void *provctx, OSSL_PARAM params[]) { - const OSSL_CORE_HANDLE *hand = vhand; + P_TEST_CTX *ctx = (P_TEST_CTX *)provctx; + const OSSL_CORE_HANDLE *hand = ctx->handle; OSSL_PARAM *p = params; int ok = 1; @@ -101,6 +114,14 @@ static int p_get_params(void *vhand, OSSL_PARAM params[]) return ok; } +static void p_set_error(int lib, int reason, const char *file, int line, + const char *func) +{ + c_new_error(NULL); + c_set_error_debug(NULL, file, line, func); + c_vset_error(NULL, ERR_PACK(lib, 0, reason), NULL, NULL); +} + static const OSSL_ITEM *p_get_reason_strings(void *_) { static const OSSL_ITEM reason_strings[] = { @@ -116,6 +137,7 @@ static const OSSL_DISPATCH p_test_table[] = { { OSSL_FUNC_PROVIDER_GET_PARAMS, (void (*)(void))p_get_params }, { OSSL_FUNC_PROVIDER_GET_REASON_STRINGS, (void (*)(void))p_get_reason_strings}, + { OSSL_FUNC_PROVIDER_TEARDOWN, (void (*)(void))p_teardown }, { 0, NULL } }; @@ -124,6 +146,8 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, const OSSL_DISPATCH **out, void **provctx) { + P_TEST_CTX *ctx; + for (; in->function_id != 0; in++) { switch (in->function_id) { case OSSL_FUNC_CORE_GETTABLE_PARAMS: @@ -132,15 +156,54 @@ int OSSL_provider_init(const OSSL_CORE_HANDLE *handle, case OSSL_FUNC_CORE_GET_PARAMS: c_get_params = OSSL_FUNC_core_get_params(in); break; + case OSSL_FUNC_CORE_NEW_ERROR: + c_new_error = OSSL_FUNC_core_new_error(in); + break; + case OSSL_FUNC_CORE_SET_ERROR_DEBUG: + c_set_error_debug = OSSL_FUNC_core_set_error_debug(in); + break; + case OSSL_FUNC_CORE_VSET_ERROR: + c_vset_error = OSSL_FUNC_core_vset_error(in); + break; default: /* Just ignore anything we don't understand */ break; } } - /* Because we use this in get_params, we need to pass it back */ - *provctx = (void *)handle; - + /* + * We want to test that libcrypto doesn't use the file and func pointers + * that we provide to it via c_set_error_debug beyond the time that they + * are valid for. Therefore we dynamically allocate these strings now and + * free them again when the provider is torn down. If anything tries to + * use those strings after that point there will be a use-after-free and + * asan will complain (and hence the tests will fail). + * This file isn't linked against libcrypto, so we use malloc and strdup + * instead of OPENSSL_malloc and OPENSSL_strdup + */ + ctx = malloc(sizeof(*ctx)); + if (ctx == NULL) + return 0; + ctx->thisfile = strdup(OPENSSL_FILE); + ctx->thisfunc = strdup(OPENSSL_FUNC); + ctx->handle = handle; + + /* + * Set a spurious error to check error handling works correctly. This will + * be ignored + */ + p_set_error(ERR_LIB_PROV, 1, ctx->thisfile, OPENSSL_LINE, ctx->thisfunc); + + *provctx = (void *)ctx; *out = p_test_table; return 1; } + +static void p_teardown(void *provctx) +{ + P_TEST_CTX *ctx = (P_TEST_CTX *)provctx; + + free(ctx->thisfile); + free(ctx->thisfunc); + free(ctx); +} |