Modernise the ERR functionality further (new functions and deprecations)

ERR_func_error_string() essentially returns NULL, and since all
function codes are now removed for all intents and purposes, this
function has fallen out of use and cannot be modified to suit the
data, since its only function is to interpret an error code.

To compensate for the loss of error code, we instead provide new
functions that extracts the function name strings from an error
record:

- ERR_get_error_func()
- ERR_peek_error_func()
- ERR_peek_last_error_func()

Similarly, the once all encompasing functions
ERR_peek_last_error_line_data(), ERR_peek_error_line_data() and
ERR_get_error_line_data() lack the capability of getting the function
name string, so we deprecate those and add these functions to replace
them:

- ERR_get_error_all()
- ERR_peek_error_all()
- ERR_peek_last_error_all()

Finally, we adjust a few lines of code that used the now deprecated
functions.

Fixes #9756

Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9756)
This commit is contained in:
Richard Levitte 2019-09-04 22:04:08 +02:00
parent 06ff79bd77
commit b13342e933
6 changed files with 198 additions and 43 deletions

View File

@ -126,8 +126,8 @@ static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL;
static int int_err_library_number = ERR_LIB_USER;
static unsigned long get_error_values(int inc, int top, const char **file,
int *line, const char **data,
int *flags);
int *line, const char **func,
const char **data, int *flags);
static unsigned long err_string_data_hash(const ERR_STRING_DATA *a)
{
@ -371,55 +371,112 @@ void ERR_clear_error(void)
unsigned long ERR_get_error(void)
{
return get_error_values(1, 0, NULL, NULL, NULL, NULL);
return get_error_values(1, 0, NULL, NULL, NULL, NULL, NULL);
}
unsigned long ERR_get_error_line(const char **file, int *line)
{
return get_error_values(1, 0, file, line, NULL, NULL);
return get_error_values(1, 0, file, line, NULL, NULL, NULL);
}
unsigned long ERR_get_error_func(const char **func)
{
return get_error_values(1, 0, NULL, NULL, func, NULL, NULL);
}
unsigned long ERR_get_error_data(const char **data, int *flags)
{
return get_error_values(1, 0, NULL, NULL, NULL, data, flags);
}
unsigned long ERR_get_error_all(const char **file, int *line,
const char **func,
const char **data, int *flags)
{
return get_error_values(1, 0, file, line, func, data, flags);
}
#if !OPENSSL_API_3
unsigned long ERR_get_error_line_data(const char **file, int *line,
const char **data, int *flags)
{
return get_error_values(1, 0, file, line, data, flags);
return get_error_values(1, 0, file, line, NULL, data, flags);
}
#endif
unsigned long ERR_peek_error(void)
{
return get_error_values(0, 0, NULL, NULL, NULL, NULL);
return get_error_values(0, 0, NULL, NULL, NULL, NULL, NULL);
}
unsigned long ERR_peek_error_line(const char **file, int *line)
{
return get_error_values(0, 0, file, line, NULL, NULL);
return get_error_values(0, 0, file, line, NULL, NULL, NULL);
}
unsigned long ERR_peek_error_func(const char **func)
{
return get_error_values(0, 0, NULL, NULL, func, NULL, NULL);
}
unsigned long ERR_peek_error_data(const char **data, int *flags)
{
return get_error_values(0, 0, NULL, NULL, NULL, data, flags);
}
unsigned long ERR_peek_error_all(const char **file, int *line,
const char **func,
const char **data, int *flags)
{
return get_error_values(0, 0, file, line, func, data, flags);
}
#if !OPENSSL_API_3
unsigned long ERR_peek_error_line_data(const char **file, int *line,
const char **data, int *flags)
{
return get_error_values(0, 0, file, line, data, flags);
return get_error_values(0, 0, file, line, NULL, data, flags);
}
#endif
unsigned long ERR_peek_last_error(void)
{
return get_error_values(0, 1, NULL, NULL, NULL, NULL);
return get_error_values(0, 1, NULL, NULL, NULL, NULL, NULL);
}
unsigned long ERR_peek_last_error_line(const char **file, int *line)
{
return get_error_values(0, 1, file, line, NULL, NULL);
return get_error_values(0, 1, file, line, NULL, NULL, NULL);
}
unsigned long ERR_peek_last_error_func(const char **func)
{
return get_error_values(0, 1, NULL, NULL, func, NULL, NULL);
}
unsigned long ERR_peek_last_error_data(const char **data, int *flags)
{
return get_error_values(0, 1, NULL, NULL, NULL, data, flags);
}
unsigned long ERR_peek_last_error_all(const char **file, int *line,
const char **func,
const char **data, int *flags)
{
return get_error_values(0, 1, file, line, func, data, flags);
}
#if !OPENSSL_API_3
unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
const char **data, int *flags)
{
return get_error_values(0, 1, file, line, data, flags);
return get_error_values(0, 1, file, line, NULL, data, flags);
}
#endif
static unsigned long get_error_values(int inc, int top, const char **file,
int *line, const char **data,
int *flags)
int *line, const char **func,
const char **data, int *flags)
{
int i = 0;
ERR_STATE *es;
@ -430,13 +487,15 @@ static unsigned long get_error_values(int inc, int top, const char **file,
return 0;
if (inc && top) {
if (file)
if (file != NULL)
*file = "";
if (line)
if (line != NULL)
*line = 0;
if (data)
if (func != NULL)
*func = "";
if (data != NULL)
*data = "";
if (flags)
if (flags != NULL)
*flags = 0;
return ERR_R_INTERNAL_ERROR;
@ -481,6 +540,12 @@ static unsigned long get_error_values(int inc, int top, const char **file,
}
}
if (func != NULL) {
*func = es->err_func[i];
if (*func == NULL)
*func = "N/A";
}
if (data == NULL) {
if (inc) {
err_clear_data(es, i, 0);
@ -558,12 +623,12 @@ const char *ERR_lib_error_string(unsigned long e)
return ((p == NULL) ? NULL : p->string);
}
#if !OPENSSL_API_3
const char *ERR_func_error_string(unsigned long e)
{
if (!RUN_ONCE(&err_string_init, do_err_strings_init))
return NULL;
return ERR_GET_LIB(e) == ERR_LIB_SYS ? "system library" : NULL;
return NULL;
}
#endif
const char *ERR_reason_error_string(unsigned long e)
{

View File

@ -4,8 +4,11 @@
ERR_get_error, ERR_peek_error, ERR_peek_last_error,
ERR_get_error_line, ERR_peek_error_line, ERR_peek_last_error_line,
ERR_get_error_line_data, ERR_peek_error_line_data,
ERR_peek_last_error_line_data - obtain error code and data
ERR_get_error_func, ERR_peek_error_func, ERR_peek_last_error_func,
ERR_get_error_data, ERR_peek_error_data, ERR_peek_last_error_data,
ERR_get_error_all, ERR_peek_error_all, ERR_peek_last_error_all,
ERR_get_error_line_data, ERR_peek_error_line_data, ERR_peek_last_error_line_data
- obtain error code and data
=head1 SYNOPSIS
@ -19,6 +22,26 @@ ERR_peek_last_error_line_data - obtain error code and data
unsigned long ERR_peek_error_line(const char **file, int *line);
unsigned long ERR_peek_last_error_line(const char **file, int *line);
unsigned long ERR_get_error_func(const char **func);
unsigned long ERR_peek_error_func(const char **func);
unsigned long ERR_peek_last_error_func(const char **func);
unsigned long ERR_get_error_data(const char **data, int *flags);
unsigned long ERR_peek_error_data(const char **data, int *flags);
unsigned long ERR_peek_last_error_data(const char **data, int *flags);
unsigned long ERR_get_error_all(const char **file, int *line,
const char *func,
const char **data, int *flags);
unsigned long ERR_peek_error_all(const char **file, int *line,
const char *func,
const char **data, int *flags);
unsigned long ERR_peek_last_error_all(const char **file, int *line,
const char *func,
const char **data, int *flags);
Deprecated since OpenSSL 3.0:
unsigned long ERR_get_error_line_data(const char **file, int *line,
const char **data, int *flags);
unsigned long ERR_peek_error_line_data(const char **file, int *line,
@ -44,15 +67,31 @@ L<ERR_error_string(3)> for human-readable error
messages.
ERR_get_error_line(), ERR_peek_error_line() and
ERR_peek_last_error_line() are the same as the above, but they
ERR_peek_last_error_line() are the same as ERR_get_error(),
ERR_peek_error() and ERR_peek_last_error(), but they
additionally store the file name and line number where
the error occurred in *B<file> and *B<line>, unless these are B<NULL>.
ERR_get_error_func(), ERR_peek_error_func() and
ERR_peek_last_error_func() are the same as ERR_get_error(),
ERR_peek_error() and ERR_peek_last_error(), but they
additionally store the name of the function where the error in *B<func>,
unless it is B<NULL>.
ERR_get_error_data(), ERR_peek_error_data() and
ERR_peek_last_error_data() are the same as ERR_get_error(),
ERR_peek_error() and ERR_peek_last_error(), but they
additionally store additional data and flags associated with the error
code in *B<data> and *B<flags>, unless these are B<NULL>.
*B<data> contains a string if *B<flags>&B<ERR_TXT_STRING> is true.
ERR_get_error_all(), ERR_peek_error_all() and
ERR_peek_last_error_all() are combinations of all of the above.
ERR_get_error_line_data(), ERR_peek_error_line_data() and
ERR_peek_last_error_line_data() store additional data and flags
associated with the error code in *B<data>
and *B<flags>, unless these are B<NULL>. *B<data> contains a string
if *B<flags>&B<ERR_TXT_STRING> is true.
ERR_peek_last_error_line_data() are older variants of ERR_get_error_all(),
ERR_peek_error_all() and ERR_peek_last_error_all(), and should no longer
be used.
An application B<MUST NOT> free the *B<data> pointer (or any other pointers
returned by these functions) with OPENSSL_free() as freeing is handled
@ -67,6 +106,17 @@ The error code, or 0 if there is no error in the queue.
L<ERR_error_string(3)>,
L<ERR_GET_LIB(3)>
=head1 HISTORY
ERR_get_error_func(), ERR_peek_error_func(), ERR_peek_last_error_func(),
ERR_get_error_data(), ERR_peek_error_data(), ERR_peek_last_error_data(),
ERR_get_error_all(), ERR_peek_error_all() and ERR_peek_last_error_all()
were added in OpenSSL 3.0.
ERR_get_error_line_data(), ERR_peek_error_line_data() and
ERR_peek_last_error_line_data() became deprecated in OpenSSL 3.0.
=head1 COPYRIGHT
Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved.

View File

@ -260,31 +260,64 @@ void ERR_vset_error(int lib, int reason, const char *fmt, va_list args);
void ERR_set_error_data(char *data, int flags);
unsigned long ERR_get_error(void);
/*
* TODO(3.0) consider if the following three functions should be deprecated.
* They all drop the error record from the error queue, so regardless of which
* one is used, the rest of the information is lost, making them not so useful.
* The recommendation should be to use the peek functions to extract all the
* additional data.
*/
unsigned long ERR_get_error_line(const char **file, int *line);
unsigned long ERR_get_error_line_data(const char **file, int *line,
const char **data, int *flags);
unsigned long ERR_get_error_func(const char **func);
unsigned long ERR_get_error_data(const char **data, int *flags);
unsigned long ERR_get_error_all(const char **file, int *line,
const char **func,
const char **data, int *flags);
DEPRECATEDIN_3(unsigned long ERR_get_error_line_data(const char **file,
int *line,
const char **data,
int *flags))
unsigned long ERR_peek_error(void);
unsigned long ERR_peek_error_line(const char **file, int *line);
unsigned long ERR_peek_error_line_data(const char **file, int *line,
const char **data, int *flags);
unsigned long ERR_peek_error_func(const char **func);
unsigned long ERR_peek_error_data(const char **data, int *flags);
unsigned long ERR_peek_error_all(const char **file, int *line,
const char **func,
const char **data, int *flags);
DEPRECATEDIN_3(unsigned long ERR_peek_error_line_data(const char **file,
int *line,
const char **data,
int *flags))
unsigned long ERR_peek_last_error(void);
unsigned long ERR_peek_last_error_line(const char **file, int *line);
unsigned long ERR_peek_last_error_line_data(const char **file, int *line,
const char **data, int *flags);
unsigned long ERR_peek_last_error_func(const char **func);
unsigned long ERR_peek_last_error_data(const char **data, int *flags);
unsigned long ERR_peek_last_error_all(const char **file, int *line,
const char **func,
const char **data, int *flags);
DEPRECATEDIN_3(unsigned long ERR_peek_last_error_line_data(const char **file,
int *line,
const char **data,
int *flags))
void ERR_clear_error(void);
char *ERR_error_string(unsigned long e, char *buf);
void ERR_error_string_n(unsigned long e, char *buf, size_t len);
const char *ERR_lib_error_string(unsigned long e);
const char *ERR_func_error_string(unsigned long e);
DEPRECATEDIN_3(const char *ERR_func_error_string(unsigned long e))
const char *ERR_reason_error_string(unsigned long e);
void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u),
void *u);
# ifndef OPENSSL_NO_STDIO
void ERR_print_errors_fp(FILE *fp);
# endif
void ERR_print_errors(BIO *bp);
void ERR_add_error_data(int num, ...);
void ERR_add_error_vdata(int num, va_list args);
int ERR_load_strings(int lib, ERR_STRING_DATA *str);
int ERR_load_strings_const(const ERR_STRING_DATA *str);
int ERR_unload_strings(int lib, ERR_STRING_DATA *str);

View File

@ -40,7 +40,7 @@ static int vdata_appends(void)
CRYPTOerr(0, ERR_R_MALLOC_FAILURE);
ERR_add_error_data(1, "hello ");
ERR_add_error_data(1, "world");
ERR_get_error_line_data(NULL, NULL, &data, NULL);
ERR_peek_error_data(&data, NULL);
return TEST_str_eq(data, "hello world");
}
@ -63,7 +63,7 @@ static int raised_error(void)
#endif
ERR_raise_data(ERR_LIB_SYS, ERR_R_INTERNAL_ERROR,
"calling exit()");
if (!TEST_ulong_ne(e = ERR_get_error_line_data(&f, &l, &data, NULL), 0)
if (!TEST_ulong_ne(e = ERR_get_error_all(&f, &l, NULL, &data, NULL), 0)
|| !TEST_int_eq(ERR_GET_REASON(e), ERR_R_INTERNAL_ERROR)
#if !defined(OPENSSL_NO_FILENAMES) && !defined(OPENSSL_NO_ERR)
|| !TEST_int_eq(l, line)

View File

@ -2799,7 +2799,6 @@ static void clear_test(EVP_TEST *t)
static int check_test_error(EVP_TEST *t)
{
unsigned long err;
const char *func;
const char *reason;
if (t->err == NULL && t->expected_err == NULL)
@ -2842,9 +2841,8 @@ static int check_test_error(EVP_TEST *t)
return 0;
}
func = ERR_func_error_string(err);
reason = ERR_reason_error_string(err);
if (func == NULL && reason == NULL) {
if (reason == NULL) {
TEST_info("%s:%d: Expected error \"%s\", no strings available."
" Assuming ok.",
t->s.test_file, t->s.start, t->reason);

View File

@ -515,7 +515,7 @@ DH_generate_parameters 526 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_0
BN_set_negative 527 3_0_0 EXIST::FUNCTION:
i2d_TS_RESP_bio 528 3_0_0 EXIST::FUNCTION:TS
ASYNC_WAIT_CTX_set_wait_fd 529 3_0_0 EXIST::FUNCTION:
ERR_func_error_string 530 3_0_0 EXIST::FUNCTION:
ERR_func_error_string 530 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3
ASN1_STRING_data 531 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_1_1_0
X509_CRL_add1_ext_i2d 532 3_0_0 EXIST::FUNCTION:
i2d_TS_TST_INFO 533 3_0_0 EXIST::FUNCTION:TS
@ -757,7 +757,7 @@ EVP_rc5_32_12_16_cfb64 775 3_0_0 EXIST::FUNCTION:RC5
PKCS7_dataVerify 776 3_0_0 EXIST::FUNCTION:
PKCS7_SIGNER_INFO_free 777 3_0_0 EXIST::FUNCTION:
PKCS7_add_attrib_smimecap 778 3_0_0 EXIST::FUNCTION:
ERR_peek_last_error_line_data 779 3_0_0 EXIST::FUNCTION:
ERR_peek_last_error_line_data 779 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3
EVP_PKEY_meth_set_sign 780 3_0_0 EXIST::FUNCTION:
ASN1_i2d_bio 781 3_0_0 EXIST::FUNCTION:
DSA_verify 782 3_0_0 EXIST::FUNCTION:DSA
@ -969,7 +969,7 @@ DH_get_default_method 993 3_0_0 EXIST::FUNCTION:DH
PEM_proc_type 994 3_0_0 EXIST::FUNCTION:
BIO_printf 995 3_0_0 EXIST::FUNCTION:
a2i_IPADDRESS 996 3_0_0 EXIST::FUNCTION:
ERR_peek_error_line_data 997 3_0_0 EXIST::FUNCTION:
ERR_peek_error_line_data 997 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3
ERR_unload_strings 998 3_0_0 EXIST::FUNCTION:
SEED_cfb128_encrypt 999 3_0_0 EXIST::FUNCTION:SEED
ASN1_BIT_STRING_it 1000 3_0_0 EXIST::FUNCTION:
@ -1554,7 +1554,7 @@ SRP_VBASE_free 1588 3_0_0 EXIST::FUNCTION:SRP
PKCS7_add0_attrib_signing_time 1589 3_0_0 EXIST::FUNCTION:
X509_STORE_set_flags 1590 3_0_0 EXIST::FUNCTION:
UI_get0_output_string 1591 3_0_0 EXIST::FUNCTION:
ERR_get_error_line_data 1592 3_0_0 EXIST::FUNCTION:
ERR_get_error_line_data 1592 3_0_0 EXIST::FUNCTION:DEPRECATEDIN_3
CTLOG_get0_name 1593 3_0_0 EXIST::FUNCTION:CT
ASN1_TBOOLEAN_it 1594 3_0_0 EXIST::FUNCTION:
RC2_set_key 1595 3_0_0 EXIST::FUNCTION:RC2
@ -4753,3 +4753,12 @@ EVP_PKEY_CTX_get_params 4869 3_0_0 EXIST::FUNCTION:
EVP_PKEY_CTX_gettable_params 4870 3_0_0 EXIST::FUNCTION:
EVP_PKEY_CTX_settable_params 4871 3_0_0 EXIST::FUNCTION:
EVP_CIPHER_CTX_tag_length 4872 3_0_0 EXIST::FUNCTION:
ERR_get_error_func 4873 3_0_0 EXIST::FUNCTION:
ERR_get_error_data 4874 3_0_0 EXIST::FUNCTION:
ERR_get_error_all 4875 3_0_0 EXIST::FUNCTION:
ERR_peek_error_func 4876 3_0_0 EXIST::FUNCTION:
ERR_peek_error_data 4877 3_0_0 EXIST::FUNCTION:
ERR_peek_error_all 4878 3_0_0 EXIST::FUNCTION:
ERR_peek_last_error_func 4879 3_0_0 EXIST::FUNCTION:
ERR_peek_last_error_data 4880 3_0_0 EXIST::FUNCTION:
ERR_peek_last_error_all 4881 3_0_0 EXIST::FUNCTION: