diff --git a/crypto/err/err.c b/crypto/err/err.c index fe91ca7b5d..e5f9866813 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 03e05b7a1c..abb6996e13 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 c012f65d08..f7d5c174a1 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