1 /* 2 * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #define OSSL_FORCE_ERR_STATE 11 12 #include <openssl/err.h> 13 #include "err_local.h" 14 15 /* 16 * Save and restore error state. 17 * We are using CRYPTO_zalloc(.., NULL, 0) instead of OPENSSL_malloc() in 18 * these functions to prevent mem alloc error loop. 19 */ 20 21 ERR_STATE *OSSL_ERR_STATE_new(void) 22 { 23 return CRYPTO_zalloc(sizeof(ERR_STATE), NULL, 0); 24 } 25 26 void OSSL_ERR_STATE_save(ERR_STATE *es) 27 { 28 size_t i; 29 ERR_STATE *thread_es; 30 31 if (es == NULL) 32 return; 33 34 for (i = 0; i < ERR_NUM_ERRORS; i++) 35 err_clear(es, i, 1); 36 37 thread_es = ossl_err_get_state_int(); 38 if (thread_es == NULL) 39 return; 40 41 memcpy(es, thread_es, sizeof(*es)); 42 /* Taking over the pointers, just clear the thread state. */ 43 memset(thread_es, 0, sizeof(*thread_es)); 44 } 45 46 void OSSL_ERR_STATE_save_to_mark(ERR_STATE *es) 47 { 48 size_t i, j, count; 49 int top; 50 ERR_STATE *thread_es; 51 52 if (es == NULL) 53 return; 54 55 thread_es = ossl_err_get_state_int(); 56 if (thread_es == NULL) { 57 for (i = 0; i < ERR_NUM_ERRORS; ++i) 58 err_clear(es, i, 1); 59 60 es->top = es->bottom = 0; 61 return; 62 } 63 64 /* Determine number of errors we are going to move. */ 65 for (count = 0, top = thread_es->top; 66 thread_es->bottom != top 67 && thread_es->err_marks[top] == 0; 68 ++count) 69 top = top > 0 ? top - 1 : ERR_NUM_ERRORS - 1; 70 71 /* Move the errors, preserving order. */ 72 for (i = 0, j = top; i < count; ++i) { 73 j = (j + 1) % ERR_NUM_ERRORS; 74 75 err_clear(es, i, 1); 76 77 /* Move the error entry to the given ERR_STATE. */ 78 es->err_flags[i] = thread_es->err_flags[j]; 79 es->err_marks[i] = 0; 80 es->err_buffer[i] = thread_es->err_buffer[j]; 81 es->err_data[i] = thread_es->err_data[j]; 82 es->err_data_size[i] = thread_es->err_data_size[j]; 83 es->err_data_flags[i] = thread_es->err_data_flags[j]; 84 es->err_file[i] = thread_es->err_file[j]; 85 es->err_line[i] = thread_es->err_line[j]; 86 es->err_func[i] = thread_es->err_func[j]; 87 88 thread_es->err_flags[j] = 0; 89 thread_es->err_buffer[j] = 0; 90 thread_es->err_data[j] = NULL; 91 thread_es->err_data_size[j] = 0; 92 thread_es->err_data_flags[j] = 0; 93 thread_es->err_file[j] = NULL; 94 thread_es->err_line[j] = 0; 95 thread_es->err_func[j] = NULL; 96 } 97 98 if (i > 0) { 99 thread_es->top = top; 100 /* If we moved anything, es's stack always starts at [0]. */ 101 es->top = i - 1; 102 es->bottom = ERR_NUM_ERRORS - 1; 103 } else { 104 /* Didn't move anything - empty stack */ 105 es->top = es->bottom = 0; 106 } 107 108 /* Erase extra space as a precaution. */ 109 for (; i < ERR_NUM_ERRORS; ++i) 110 err_clear(es, i, 1); 111 } 112 113 void OSSL_ERR_STATE_restore(const ERR_STATE *es) 114 { 115 size_t i; 116 ERR_STATE *thread_es; 117 118 if (es == NULL || es->bottom == es->top) 119 return; 120 121 thread_es = ossl_err_get_state_int(); 122 if (thread_es == NULL) 123 return; 124 125 for (i = (size_t)es->bottom; i != (size_t)es->top;) { 126 size_t top; 127 128 i = (i + 1) % ERR_NUM_ERRORS; 129 if ((es->err_flags[i] & ERR_FLAG_CLEAR) != 0) 130 continue; 131 132 err_get_slot(thread_es); 133 top = thread_es->top; 134 err_clear(thread_es, top, 0); 135 136 thread_es->err_flags[top] = es->err_flags[i]; 137 thread_es->err_buffer[top] = es->err_buffer[i]; 138 139 err_set_debug(thread_es, top, es->err_file[i], es->err_line[i], 140 es->err_func[i]); 141 142 if (es->err_data[i] != NULL && es->err_data_size[i] != 0) { 143 void *data; 144 size_t data_sz = es->err_data_size[i]; 145 146 data = CRYPTO_malloc(data_sz, NULL, 0); 147 if (data != NULL) { 148 memcpy(data, es->err_data[i], data_sz); 149 err_set_data(thread_es, top, data, data_sz, 150 es->err_data_flags[i] | ERR_TXT_MALLOCED); 151 } 152 } else { 153 err_clear_data(thread_es, top, 0); 154 } 155 } 156 } 157