Ensure that the ERR_STATE is left in a consistent state
authorMatt Caswell <matt@openssl.org>
Thu, 12 Oct 2023 11:38:22 +0000 (12:38 +0100)
committerMatt Caswell <matt@openssl.org>
Mon, 23 Oct 2023 09:08:12 +0000 (10:08 +0100)
We shouldn't ever have the case where the data flags indicate that
err_data has been malloc'd, but the err_data field is NULL.

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Hugo Landau <hlandau@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22368)

crypto/err/err.c
crypto/err/err_save.c

index 7b7f309951554ca586273966a236253883b3da51..b95182d7029a2433081deaa1cd650e761534e070 100644 (file)
@@ -834,7 +834,8 @@ void ERR_add_error_vdata(int num, va_list args)
      * If err_data is allocated already, reuse the space.
      * Otherwise, allocate a small new buffer.
      */
-    if ((es->err_data_flags[i] & flags) == flags) {
+    if ((es->err_data_flags[i] & flags) == flags
+            && ossl_assert(es->err_data[i] != NULL)) {
         str = es->err_data[i];
         size = es->err_data_size[i];
 
index 3ca059adc336b0dbf9cf61f80ab95bd086b8b629..1994c26ceef0c15cee128b3a63e09be55fb3fbce 100644 (file)
@@ -85,16 +85,18 @@ void OSSL_ERR_STATE_save_to_mark(ERR_STATE *es)
         es->err_line[i]         = thread_es->err_line[j];
         es->err_func[i]         = thread_es->err_func[j];
 
-        thread_es->err_flags[j]     = 0;
-        thread_es->err_buffer[j]    = 0;
-        thread_es->err_data[j]      = NULL;
-        thread_es->err_data_size[j] = 0;
-        thread_es->err_file[j]      = NULL;
-        thread_es->err_line[j]      = 0;
-        thread_es->err_func[j]      = NULL;
+        thread_es->err_flags[j]      = 0;
+        thread_es->err_buffer[j]     = 0;
+        thread_es->err_data[j]       = NULL;
+        thread_es->err_data_size[j]  = 0;
+        thread_es->err_data_flags[j] = 0;
+        thread_es->err_file[j]       = NULL;
+        thread_es->err_line[j]       = 0;
+        thread_es->err_func[j]       = NULL;
     }
 
     if (i > 0) {
+        thread_es->top = top;
         /* If we moved anything, es's stack always starts at [0]. */
         es->top     = i - 1;
         es->bottom  = ERR_NUM_ERRORS - 1;