From: Matt Caswell Date: Mon, 15 Feb 2021 16:59:43 +0000 (+0000) Subject: Duplicate the file and func error strings X-Git-Tag: openssl-3.0.0-alpha13~202 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=de4a88a979193e1f28c65c1f902828dd91d10ba5;p=thirdparty%2Fopenssl.git Duplicate the file and func error strings Errors raised from a provider that is subsequently unloaded from memory may have references to strings representing the file and function that are no longer present because the provider is no longer in memory. This can cause crashes. To avoid this we duplicate the file and func strings. Fixes #13623 Reviewed-by: Paul Dale Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/14213) --- diff --git a/crypto/err/err.c b/crypto/err/err.c index fe91ca7b5d7..e5f98668131 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -190,7 +190,7 @@ static void ERR_STATE_free(ERR_STATE *s) if (s == NULL) return; for (i = 0; i < ERR_NUM_ERRORS; i++) { - err_clear_data(s, i, 1); + err_clear(s, i, 1); } OPENSSL_free(s); } diff --git a/crypto/err/err_local.h b/crypto/err/err_local.h index 03e05b7a1cf..abb6996e138 100644 --- a/crypto/err/err_local.h +++ b/crypto/err/err_local.h @@ -48,9 +48,21 @@ static ossl_inline void err_set_debug(ERR_STATE *es, size_t i, const char *file, int line, const char *fn) { - es->err_file[i] = file; + /* + * We dup the file and fn strings because they may be provider owned. If the + * provider gets unloaded, they may not be valid anymore. + */ + OPENSSL_free(es->err_file[i]); + if (file == NULL || file[0] == '\0') + es->err_file[i] = NULL; + else + es->err_file[i] = OPENSSL_strdup(file); es->err_line[i] = line; - es->err_func[i] = fn; + OPENSSL_free(es->err_func[i]); + if (fn == NULL || fn[0] == '\0') + es->err_func[i] = NULL; + else + es->err_func[i] = OPENSSL_strdup(fn); } static ossl_inline void err_set_data(ERR_STATE *es, size_t i, @@ -67,8 +79,11 @@ static ossl_inline void err_clear(ERR_STATE *es, size_t i, int deall) es->err_marks[i] = 0; es->err_flags[i] = 0; es->err_buffer[i] = 0; - es->err_file[i] = NULL; es->err_line[i] = -1; + OPENSSL_free(es->err_file[i]); + es->err_file[i] = NULL; + OPENSSL_free(es->err_func[i]); + es->err_func[i] = NULL; } ERR_STATE *err_get_state_int(void); diff --git a/include/openssl/err.h.in b/include/openssl/err.h.in index c012f65d08b..f7d5c174a17 100644 --- a/include/openssl/err.h.in +++ b/include/openssl/err.h.in @@ -62,9 +62,9 @@ struct err_state_st { char *err_data[ERR_NUM_ERRORS]; size_t err_data_size[ERR_NUM_ERRORS]; int err_data_flags[ERR_NUM_ERRORS]; - const char *err_file[ERR_NUM_ERRORS]; + char *err_file[ERR_NUM_ERRORS]; int err_line[ERR_NUM_ERRORS]; - const char *err_func[ERR_NUM_ERRORS]; + char *err_func[ERR_NUM_ERRORS]; int top, bottom; }; # endif