From: Tomas Mraz Date: Wed, 25 Feb 2026 17:15:47 +0000 (+0100) Subject: ossl_err_get_state_int(): Avoid saving the last sys error if not needed X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=faa5318c654d8444312aa0703cbdd7518550a053;p=thirdparty%2Fopenssl.git ossl_err_get_state_int(): Avoid saving the last sys error if not needed In calls like ERR_set_mark(), ERR_clear_last_mark() and others, there is no point in saving the last sys error. It can be potentially expensive (on Windows). Reviewed-by: Simo Sorce Reviewed-by: Paul Dale Reviewed-by: Neil Horman MergeDate: Thu Apr 16 18:12:49 2026 (Merged from https://github.com/openssl/openssl/pull/30179) --- diff --git a/crypto/err/err.c b/crypto/err/err.c index b3e15196f67..bf637e1d45e 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -25,9 +25,6 @@ #include "internal/e_os.h" #include "err_local.h" -/* Forward declaration in case it's not published because of configuration */ -ERR_STATE *ERR_get_state(void); - #ifndef OPENSSL_NO_ERR static int err_load_strings(const ERR_STRING_DATA *str); #endif @@ -331,7 +328,7 @@ void ERR_clear_error(void) int i; ERR_STATE *es; - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(0); if (es == NULL) return; @@ -445,7 +442,7 @@ static unsigned long get_error_values(ERR_GET_ACTION g, ERR_STATE *es; unsigned long ret; - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(1); if (es == NULL) return 0; @@ -648,10 +645,13 @@ static void err_delete_thread_state(void *unused) OSSL_ERR_STATE_free(state); } -ERR_STATE *ossl_err_get_state_int(void) +ERR_STATE *ossl_err_get_state_int(int save_sys_error) { ERR_STATE *state; - int saveerrno = get_last_sys_error(); + int saveerrno = 0; + + if (save_sys_error) + saveerrno = get_last_sys_error(); if (!OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL)) return NULL; @@ -686,7 +686,8 @@ ERR_STATE *ossl_err_get_state_int(void) OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); } - set_sys_error(saveerrno); + if (save_sys_error) + set_sys_error(saveerrno); return state; } @@ -753,7 +754,7 @@ static int err_set_error_data_int(char *data, size_t size, int flags, { ERR_STATE *es; - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(1); if (es == NULL) return 0; @@ -799,7 +800,7 @@ void ERR_add_error_vdata(int num, va_list args) ERR_STATE *es; /* Get the current error data; if an allocated string get it. */ - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(1); if (es == NULL) return; i = es->top; @@ -856,7 +857,7 @@ void err_clear_last_constant_time(int clear) ERR_STATE *es; int top; - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(0); if (es == NULL) return; diff --git a/crypto/err/err_blocks.c b/crypto/err/err_blocks.c index cc0fce04196..90451ea880a 100644 --- a/crypto/err/err_blocks.c +++ b/crypto/err/err_blocks.c @@ -15,7 +15,7 @@ void ERR_new(void) { ERR_STATE *es; - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(1); if (es == NULL) return; @@ -28,7 +28,7 @@ void ERR_set_debug(const char *file, int line, const char *func) { ERR_STATE *es; - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(1); if (es == NULL) return; @@ -52,7 +52,7 @@ void ERR_vset_error(int lib, int reason, const char *fmt, va_list args) unsigned long flags = 0; size_t i; - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(1); if (es == NULL) return; i = es->top; diff --git a/crypto/err/err_local.h b/crypto/err/err_local.h index 775d8e6bdff..4ddf7f7664c 100644 --- a/crypto/err/err_local.h +++ b/crypto/err/err_local.h @@ -112,6 +112,6 @@ static ossl_inline void err_clear(ERR_STATE *es, size_t i, int deall) es->err_func[i] = NULL; } -ERR_STATE *ossl_err_get_state_int(void); +ERR_STATE *ossl_err_get_state_int(int save_sys_error); void ossl_err_string_int(unsigned long e, const char *func, char *buf, size_t len); diff --git a/crypto/err/err_mark.c b/crypto/err/err_mark.c index 2ebe86b9de5..29aef24a129 100644 --- a/crypto/err/err_mark.c +++ b/crypto/err/err_mark.c @@ -14,7 +14,7 @@ int ERR_set_mark(void) { ERR_STATE *es; - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(0); if (es == NULL) return 0; @@ -28,7 +28,7 @@ int ERR_pop(void) { ERR_STATE *es; - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(0); if (es == NULL || es->bottom == es->top) return 0; @@ -41,7 +41,7 @@ int ERR_pop_to_mark(void) { ERR_STATE *es; - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(0); if (es == NULL) return 0; @@ -62,7 +62,7 @@ int ERR_count_to_mark(void) ERR_STATE *es; int count = 0, top; - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(1); if (es == NULL) return 0; @@ -81,7 +81,7 @@ int ERR_clear_last_mark(void) ERR_STATE *es; int top; - es = ossl_err_get_state_int(); + es = ossl_err_get_state_int(0); if (es == NULL) return 0; diff --git a/crypto/err/err_save.c b/crypto/err/err_save.c index 37980c88455..62f5d752dc7 100644 --- a/crypto/err/err_save.c +++ b/crypto/err/err_save.c @@ -32,7 +32,7 @@ void OSSL_ERR_STATE_save(ERR_STATE *es) for (i = 0; i < ERR_NUM_ERRORS; i++) err_clear(es, i, 1); - thread_es = ossl_err_get_state_int(); + thread_es = ossl_err_get_state_int(1); if (thread_es == NULL) return; @@ -50,7 +50,7 @@ void OSSL_ERR_STATE_save_to_mark(ERR_STATE *es) if (es == NULL) return; - thread_es = ossl_err_get_state_int(); + thread_es = ossl_err_get_state_int(1); if (thread_es == NULL) { for (i = 0; i < ERR_NUM_ERRORS; ++i) err_clear(es, i, 1); @@ -116,7 +116,7 @@ void OSSL_ERR_STATE_restore(const ERR_STATE *es) if (es == NULL || es->bottom == es->top) return; - thread_es = ossl_err_get_state_int(); + thread_es = ossl_err_get_state_int(0); if (thread_es == NULL) return;