1 1.1 christos /* 2 1.1.1.3 christos * Copyright 2018-2021 The OpenSSL Project Authors. All Rights Reserved. 3 1.1 christos * 4 1.1.1.3 christos * Licensed under the Apache License 2.0 (the "License"). You may not use 5 1.1 christos * this file except in compliance with the License. You can obtain a copy 6 1.1 christos * in the file LICENSE in the source distribution or at 7 1.1 christos * https://www.openssl.org/source/license.html 8 1.1 christos */ 9 1.1 christos 10 1.1.1.3 christos #include <string.h> 11 1.1 christos #include <openssl/opensslconf.h> 12 1.1 christos #include <openssl/err.h> 13 1.1.1.3 christos #include <openssl/macros.h> 14 1.1 christos 15 1.1 christos #include "testutil.h" 16 1.1 christos 17 1.1 christos #if defined(OPENSSL_SYS_WINDOWS) 18 1.1 christos # include <windows.h> 19 1.1 christos #else 20 1.1 christos # include <errno.h> 21 1.1 christos #endif 22 1.1 christos 23 1.1.1.3 christos #ifndef OPENSSL_NO_DEPRECATED_3_0 24 1.1.1.3 christos # define IS_HEX(ch) ((ch >= '0' && ch <='9') || (ch >= 'A' && ch <='F')) 25 1.1.1.3 christos 26 1.1.1.3 christos static int test_print_error_format(void) 27 1.1.1.3 christos { 28 1.1.1.3 christos /* Variables used to construct an error line */ 29 1.1.1.3 christos char *lib; 30 1.1.1.3 christos const char *func = OPENSSL_FUNC; 31 1.1.1.3 christos char *reason; 32 1.1.1.3 christos # ifdef OPENSSL_NO_ERR 33 1.1.1.3 christos char reasonbuf[255]; 34 1.1.1.3 christos # endif 35 1.1.1.3 christos # ifndef OPENSSL_NO_FILENAMES 36 1.1.1.3 christos const char *file = OPENSSL_FILE; 37 1.1.1.3 christos const int line = OPENSSL_LINE; 38 1.1.1.3 christos # else 39 1.1.1.3 christos const char *file = ""; 40 1.1.1.3 christos const int line = 0; 41 1.1.1.3 christos # endif 42 1.1.1.3 christos /* The format for OpenSSL error lines */ 43 1.1.1.3 christos const char *expected_format = ":error:%08lX:%s:%s:%s:%s:%d"; 44 1.1.1.3 christos /*- 45 1.1.1.3 christos * ^^ ^^ ^^ ^^ ^^ 46 1.1.1.3 christos * "library" name --------------------------++ || || || || 47 1.1.1.3 christos * function name ------------------------------++ || || || 48 1.1.1.3 christos * reason string (system error string) -----------++ || || 49 1.1.1.3 christos * file name ----------------------------------------++ || 50 1.1.1.3 christos * line number -----------------------------------------++ 51 1.1.1.3 christos */ 52 1.1.1.3 christos char expected[512]; 53 1.1.1.3 christos 54 1.1.1.3 christos char *out = NULL, *p = NULL; 55 1.1.1.3 christos int ret = 0, len; 56 1.1.1.3 christos BIO *bio = NULL; 57 1.1.1.3 christos const int syserr = EPERM; 58 1.1.1.3 christos unsigned long errorcode; 59 1.1.1.3 christos unsigned long reasoncode; 60 1.1.1.3 christos 61 1.1.1.3 christos /* 62 1.1.1.3 christos * We set a mark here so we can clear the system error that we generate 63 1.1.1.3 christos * with ERR_PUT_error(). That is, after all, just a simulation to verify 64 1.1.1.3 christos * ERR_print_errors() output, not a real error. 65 1.1.1.3 christos */ 66 1.1.1.3 christos ERR_set_mark(); 67 1.1.1.3 christos 68 1.1.1.3 christos ERR_PUT_error(ERR_LIB_SYS, 0, syserr, file, line); 69 1.1.1.3 christos errorcode = ERR_peek_error(); 70 1.1.1.3 christos reasoncode = ERR_GET_REASON(errorcode); 71 1.1.1.3 christos 72 1.1.1.3 christos if (!TEST_int_eq(reasoncode, syserr)) { 73 1.1.1.3 christos ERR_pop_to_mark(); 74 1.1.1.3 christos goto err; 75 1.1.1.3 christos } 76 1.1.1.3 christos 77 1.1.1.3 christos # if !defined(OPENSSL_NO_ERR) 78 1.1.1.3 christos # if defined(OPENSSL_NO_AUTOERRINIT) 79 1.1.1.3 christos lib = "lib(2)"; 80 1.1.1.3 christos # else 81 1.1.1.3 christos lib = "system library"; 82 1.1.1.3 christos # endif 83 1.1.1.3 christos reason = strerror(syserr); 84 1.1.1.3 christos # else 85 1.1.1.3 christos lib = "lib(2)"; 86 1.1.1.3 christos BIO_snprintf(reasonbuf, sizeof(reasonbuf), "reason(%lu)", reasoncode); 87 1.1.1.3 christos reason = reasonbuf; 88 1.1.1.3 christos # endif 89 1.1.1.3 christos 90 1.1.1.3 christos BIO_snprintf(expected, sizeof(expected), expected_format, 91 1.1.1.3 christos errorcode, lib, func, reason, file, line); 92 1.1.1.3 christos 93 1.1.1.3 christos if (!TEST_ptr(bio = BIO_new(BIO_s_mem()))) 94 1.1.1.3 christos goto err; 95 1.1.1.3 christos 96 1.1.1.3 christos ERR_print_errors(bio); 97 1.1.1.3 christos 98 1.1.1.3 christos if (!TEST_int_gt(len = BIO_get_mem_data(bio, &out), 0)) 99 1.1.1.3 christos goto err; 100 1.1.1.3 christos /* Skip over the variable thread id at the start of the string */ 101 1.1.1.3 christos for (p = out; *p != ':' && *p != 0; ++p) { 102 1.1.1.3 christos if (!TEST_true(IS_HEX(*p))) 103 1.1.1.3 christos goto err; 104 1.1.1.3 christos } 105 1.1.1.3 christos if (!TEST_true(*p != 0) 106 1.1.1.3 christos || !TEST_strn_eq(expected, p, strlen(expected))) 107 1.1.1.3 christos goto err; 108 1.1.1.3 christos 109 1.1.1.3 christos ret = 1; 110 1.1.1.3 christos err: 111 1.1.1.3 christos BIO_free(bio); 112 1.1.1.3 christos return ret; 113 1.1.1.3 christos } 114 1.1.1.3 christos #endif 115 1.1.1.3 christos 116 1.1 christos /* Test that querying the error queue preserves the OS error. */ 117 1.1 christos static int preserves_system_error(void) 118 1.1 christos { 119 1.1 christos #if defined(OPENSSL_SYS_WINDOWS) 120 1.1 christos SetLastError(ERROR_INVALID_FUNCTION); 121 1.1 christos ERR_get_error(); 122 1.1.1.2 christos return TEST_int_eq(GetLastError(), ERROR_INVALID_FUNCTION); 123 1.1 christos #else 124 1.1 christos errno = EINVAL; 125 1.1 christos ERR_get_error(); 126 1.1.1.2 christos return TEST_int_eq(errno, EINVAL); 127 1.1 christos #endif 128 1.1 christos } 129 1.1 christos 130 1.1.1.3 christos /* Test that calls to ERR_add_error_[v]data append */ 131 1.1.1.3 christos static int vdata_appends(void) 132 1.1.1.3 christos { 133 1.1.1.3 christos const char *data; 134 1.1.1.3 christos 135 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 136 1.1.1.3 christos ERR_add_error_data(1, "hello "); 137 1.1.1.3 christos ERR_add_error_data(1, "world"); 138 1.1.1.3 christos ERR_peek_error_data(&data, NULL); 139 1.1.1.3 christos return TEST_str_eq(data, "hello world"); 140 1.1.1.3 christos } 141 1.1.1.3 christos 142 1.1.1.3 christos static int raised_error(void) 143 1.1.1.3 christos { 144 1.1.1.3 christos const char *f, *data; 145 1.1.1.3 christos int l; 146 1.1.1.3 christos unsigned long e; 147 1.1.1.3 christos 148 1.1.1.3 christos /* 149 1.1.1.3 christos * When OPENSSL_NO_ERR or OPENSSL_NO_FILENAMES, no file name or line 150 1.1.1.3 christos * number is saved, so no point checking them. 151 1.1.1.3 christos */ 152 1.1.1.3 christos #if !defined(OPENSSL_NO_FILENAMES) && !defined(OPENSSL_NO_ERR) 153 1.1.1.3 christos const char *file; 154 1.1.1.3 christos int line; 155 1.1.1.3 christos 156 1.1.1.3 christos file = __FILE__; 157 1.1.1.3 christos line = __LINE__ + 2; /* The error is generated on the ERR_raise_data line */ 158 1.1.1.3 christos #endif 159 1.1.1.3 christos ERR_raise_data(ERR_LIB_NONE, ERR_R_INTERNAL_ERROR, 160 1.1.1.3 christos "calling exit()"); 161 1.1.1.3 christos if (!TEST_ulong_ne(e = ERR_get_error_all(&f, &l, NULL, &data, NULL), 0) 162 1.1.1.3 christos || !TEST_int_eq(ERR_GET_REASON(e), ERR_R_INTERNAL_ERROR) 163 1.1.1.3 christos #if !defined(OPENSSL_NO_FILENAMES) && !defined(OPENSSL_NO_ERR) 164 1.1.1.3 christos || !TEST_int_eq(l, line) 165 1.1.1.3 christos || !TEST_str_eq(f, file) 166 1.1.1.3 christos #endif 167 1.1.1.3 christos || !TEST_str_eq(data, "calling exit()")) 168 1.1.1.3 christos return 0; 169 1.1.1.3 christos return 1; 170 1.1.1.3 christos } 171 1.1.1.3 christos 172 1.1.1.3 christos static int test_marks(void) 173 1.1.1.3 christos { 174 1.1.1.3 christos unsigned long mallocfail, shouldnot; 175 1.1.1.3 christos 176 1.1.1.3 christos /* Set an initial error */ 177 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 178 1.1.1.3 christos mallocfail = ERR_peek_last_error(); 179 1.1.1.3 christos if (!TEST_ulong_gt(mallocfail, 0)) 180 1.1.1.3 christos return 0; 181 1.1.1.3 christos 182 1.1.1.3 christos /* Setting and clearing a mark should not affect the error */ 183 1.1.1.3 christos if (!TEST_true(ERR_set_mark()) 184 1.1.1.3 christos || !TEST_true(ERR_pop_to_mark()) 185 1.1.1.3 christos || !TEST_ulong_eq(mallocfail, ERR_peek_last_error()) 186 1.1.1.3 christos || !TEST_true(ERR_set_mark()) 187 1.1.1.3 christos || !TEST_true(ERR_clear_last_mark()) 188 1.1.1.3 christos || !TEST_ulong_eq(mallocfail, ERR_peek_last_error())) 189 1.1.1.3 christos return 0; 190 1.1.1.3 christos 191 1.1.1.3 christos /* Test popping errors */ 192 1.1.1.3 christos if (!TEST_true(ERR_set_mark())) 193 1.1.1.3 christos return 0; 194 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); 195 1.1.1.3 christos if (!TEST_ulong_ne(mallocfail, ERR_peek_last_error()) 196 1.1.1.3 christos || !TEST_true(ERR_pop_to_mark()) 197 1.1.1.3 christos || !TEST_ulong_eq(mallocfail, ERR_peek_last_error())) 198 1.1.1.3 christos return 0; 199 1.1.1.3 christos 200 1.1.1.3 christos /* Nested marks should also work */ 201 1.1.1.3 christos if (!TEST_true(ERR_set_mark()) 202 1.1.1.3 christos || !TEST_true(ERR_set_mark())) 203 1.1.1.3 christos return 0; 204 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); 205 1.1.1.3 christos if (!TEST_ulong_ne(mallocfail, ERR_peek_last_error()) 206 1.1.1.3 christos || !TEST_true(ERR_pop_to_mark()) 207 1.1.1.3 christos || !TEST_true(ERR_pop_to_mark()) 208 1.1.1.3 christos || !TEST_ulong_eq(mallocfail, ERR_peek_last_error())) 209 1.1.1.3 christos return 0; 210 1.1.1.3 christos 211 1.1.1.3 christos if (!TEST_true(ERR_set_mark())) 212 1.1.1.3 christos return 0; 213 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 214 1.1.1.3 christos shouldnot = ERR_peek_last_error(); 215 1.1.1.3 christos if (!TEST_ulong_ne(mallocfail, shouldnot) 216 1.1.1.3 christos || !TEST_true(ERR_set_mark())) 217 1.1.1.3 christos return 0; 218 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); 219 1.1.1.3 christos if (!TEST_ulong_ne(shouldnot, ERR_peek_last_error()) 220 1.1.1.3 christos || !TEST_true(ERR_pop_to_mark()) 221 1.1.1.3 christos || !TEST_ulong_eq(shouldnot, ERR_peek_last_error()) 222 1.1.1.3 christos || !TEST_true(ERR_pop_to_mark()) 223 1.1.1.3 christos || !TEST_ulong_eq(mallocfail, ERR_peek_last_error())) 224 1.1.1.3 christos return 0; 225 1.1.1.3 christos 226 1.1.1.3 christos /* Setting and clearing a mark should not affect the errors on the stack */ 227 1.1.1.3 christos if (!TEST_true(ERR_set_mark())) 228 1.1.1.3 christos return 0; 229 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 230 1.1.1.3 christos if (!TEST_true(ERR_clear_last_mark()) 231 1.1.1.3 christos || !TEST_ulong_eq(shouldnot, ERR_peek_last_error())) 232 1.1.1.3 christos return 0; 233 1.1.1.3 christos 234 1.1.1.3 christos /* 235 1.1.1.3 christos * Popping where no mark has been set should pop everything - but return 236 1.1.1.3 christos * a failure result 237 1.1.1.3 christos */ 238 1.1.1.3 christos if (!TEST_false(ERR_pop_to_mark()) 239 1.1.1.3 christos || !TEST_ulong_eq(0, ERR_peek_last_error())) 240 1.1.1.3 christos return 0; 241 1.1.1.3 christos 242 1.1.1.3 christos /* Clearing where there is no mark should fail */ 243 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 244 1.1.1.3 christos if (!TEST_false(ERR_clear_last_mark()) 245 1.1.1.3 christos /* "get" the last error to remove it */ 246 1.1.1.3 christos || !TEST_ulong_eq(mallocfail, ERR_get_error()) 247 1.1.1.3 christos || !TEST_ulong_eq(0, ERR_peek_last_error())) 248 1.1.1.3 christos return 0; 249 1.1.1.3 christos 250 1.1.1.3 christos /* 251 1.1.1.3 christos * Setting a mark where there are no errors in the stack should fail. 252 1.1.1.3 christos * NOTE: This is somewhat surprising behaviour but is historically how this 253 1.1.1.3 christos * function behaves. In practice we typically set marks without first 254 1.1.1.3 christos * checking whether there is anything on the stack - but we also don't 255 1.1.1.3 christos * tend to check the success of this function. It turns out to work anyway 256 1.1.1.3 christos * because although setting a mark with no errors fails, a subsequent call 257 1.1.1.3 christos * to ERR_pop_to_mark() or ERR_clear_last_mark() will do the right thing 258 1.1.1.3 christos * anyway (even though they will report a failure result). 259 1.1.1.3 christos */ 260 1.1.1.3 christos if (!TEST_false(ERR_set_mark())) 261 1.1.1.3 christos return 0; 262 1.1.1.3 christos 263 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); 264 1.1.1.3 christos if (!TEST_true(ERR_set_mark())) 265 1.1.1.3 christos return 0; 266 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); 267 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 268 1.1.1.3 christos 269 1.1.1.3 christos /* Should be able to "pop" past 2 errors */ 270 1.1.1.3 christos if (!TEST_true(ERR_pop_to_mark()) 271 1.1.1.3 christos || !TEST_ulong_eq(mallocfail, ERR_peek_last_error())) 272 1.1.1.3 christos return 0; 273 1.1.1.3 christos 274 1.1.1.3 christos if (!TEST_true(ERR_set_mark())) 275 1.1.1.3 christos return 0; 276 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_INTERNAL_ERROR); 277 1.1.1.3 christos ERR_raise(ERR_LIB_CRYPTO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); 278 1.1.1.3 christos 279 1.1.1.3 christos /* Should be able to "clear" past 2 errors */ 280 1.1.1.3 christos if (!TEST_true(ERR_clear_last_mark()) 281 1.1.1.3 christos || !TEST_ulong_eq(shouldnot, ERR_peek_last_error())) 282 1.1.1.3 christos return 0; 283 1.1.1.3 christos 284 1.1.1.3 christos /* Clear remaining errors from last test */ 285 1.1.1.3 christos ERR_clear_error(); 286 1.1.1.3 christos 287 1.1.1.3 christos return 1; 288 1.1.1.3 christos } 289 1.1.1.3 christos 290 1.1.1.3 christos static int test_clear_error(void) 291 1.1.1.3 christos { 292 1.1.1.3 christos int flags = -1; 293 1.1.1.3 christos const char *data = NULL; 294 1.1.1.3 christos int res = 0; 295 1.1.1.3 christos 296 1.1.1.3 christos /* Raise an error with data and clear it */ 297 1.1.1.3 christos ERR_raise_data(0, 0, "hello %s", "world"); 298 1.1.1.3 christos ERR_peek_error_data(&data, &flags); 299 1.1.1.3 christos if (!TEST_str_eq(data, "hello world") 300 1.1.1.3 christos || !TEST_int_eq(flags, ERR_TXT_STRING | ERR_TXT_MALLOCED)) 301 1.1.1.3 christos goto err; 302 1.1.1.3 christos ERR_clear_error(); 303 1.1.1.3 christos 304 1.1.1.3 christos /* Raise a new error without data */ 305 1.1.1.3 christos ERR_raise(0, 0); 306 1.1.1.3 christos ERR_peek_error_data(&data, &flags); 307 1.1.1.3 christos if (!TEST_str_eq(data, "") 308 1.1.1.3 christos || !TEST_int_eq(flags, ERR_TXT_MALLOCED)) 309 1.1.1.3 christos goto err; 310 1.1.1.3 christos ERR_clear_error(); 311 1.1.1.3 christos 312 1.1.1.3 christos /* Raise a new error with data */ 313 1.1.1.3 christos ERR_raise_data(0, 0, "goodbye %s world", "cruel"); 314 1.1.1.3 christos ERR_peek_error_data(&data, &flags); 315 1.1.1.3 christos if (!TEST_str_eq(data, "goodbye cruel world") 316 1.1.1.3 christos || !TEST_int_eq(flags, ERR_TXT_STRING | ERR_TXT_MALLOCED)) 317 1.1.1.3 christos goto err; 318 1.1.1.3 christos ERR_clear_error(); 319 1.1.1.3 christos 320 1.1.1.3 christos /* 321 1.1.1.3 christos * Raise a new error without data to check that the malloced storage 322 1.1.1.3 christos * is freed properly 323 1.1.1.3 christos */ 324 1.1.1.3 christos ERR_raise(0, 0); 325 1.1.1.3 christos ERR_peek_error_data(&data, &flags); 326 1.1.1.3 christos if (!TEST_str_eq(data, "") 327 1.1.1.3 christos || !TEST_int_eq(flags, ERR_TXT_MALLOCED)) 328 1.1.1.3 christos goto err; 329 1.1.1.3 christos ERR_clear_error(); 330 1.1.1.3 christos 331 1.1.1.3 christos res = 1; 332 1.1.1.3 christos err: 333 1.1.1.3 christos ERR_clear_error(); 334 1.1.1.3 christos return res; 335 1.1.1.3 christos } 336 1.1.1.3 christos 337 1.1.1.2 christos int setup_tests(void) 338 1.1 christos { 339 1.1 christos ADD_TEST(preserves_system_error); 340 1.1.1.3 christos ADD_TEST(vdata_appends); 341 1.1.1.3 christos ADD_TEST(raised_error); 342 1.1.1.3 christos #ifndef OPENSSL_NO_DEPRECATED_3_0 343 1.1.1.3 christos ADD_TEST(test_print_error_format); 344 1.1.1.3 christos #endif 345 1.1.1.3 christos ADD_TEST(test_marks); 346 1.1.1.3 christos ADD_TEST(test_clear_error); 347 1.1.1.2 christos return 1; 348 1.1 christos } 349