diff options
author | Matt Caswell <matt@openssl.org> | 2021-02-15 16:59:43 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2021-02-24 12:13:38 +0000 |
commit | de4a88a979193e1f28c65c1f902828dd91d10ba5 (patch) | |
tree | 3209c5536fc6c849eb83d61385746b15dc08f190 /crypto/err | |
parent | b0001d0cf2539b9309712e3e04f407dcbb04352c (diff) |
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 <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14213)
Diffstat (limited to 'crypto/err')
-rw-r--r-- | crypto/err/err.c | 2 | ||||
-rw-r--r-- | crypto/err/err_local.h | 21 |
2 files changed, 19 insertions, 4 deletions
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); |