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)
This commit is contained in:
Matt Caswell 2021-02-15 16:59:43 +00:00
parent b0001d0cf2
commit de4a88a979
3 changed files with 21 additions and 6 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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