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