1 /* 2 * Copyright 2016-2017 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (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 #include <internal/cryptlib_int.h> 11 #include <openssl/err.h> 12 #include <internal/rand.h> 13 #include <internal/bio.h> 14 #include <openssl/evp.h> 15 #include <internal/evp_int.h> 16 #include <internal/conf.h> 17 #include <internal/async.h> 18 #include <internal/engine.h> 19 #include <internal/comp.h> 20 #include <internal/err.h> 21 #include <internal/err_int.h> 22 #include <internal/objects.h> 23 #include <stdlib.h> 24 #include <assert.h> 25 #include <internal/thread_once.h> 26 #include <internal/dso.h> 27 28 static int stopped = 0; 29 30 static void ossl_init_thread_stop(struct thread_local_inits_st *locals); 31 32 static CRYPTO_THREAD_LOCAL threadstopkey; 33 34 static void ossl_init_thread_stop_wrap(void *local) 35 { 36 ossl_init_thread_stop((struct thread_local_inits_st *)local); 37 } 38 39 static struct thread_local_inits_st *ossl_init_get_thread_local(int alloc) 40 { 41 struct thread_local_inits_st *local = 42 CRYPTO_THREAD_get_local(&threadstopkey); 43 44 if (local == NULL && alloc) { 45 local = OPENSSL_zalloc(sizeof(*local)); 46 if (local != NULL && !CRYPTO_THREAD_set_local(&threadstopkey, local)) { 47 OPENSSL_free(local); 48 return NULL; 49 } 50 } 51 if (!alloc) { 52 CRYPTO_THREAD_set_local(&threadstopkey, NULL); 53 } 54 55 return local; 56 } 57 58 typedef struct ossl_init_stop_st OPENSSL_INIT_STOP; 59 struct ossl_init_stop_st { 60 void (*handler)(void); 61 OPENSSL_INIT_STOP *next; 62 }; 63 64 static OPENSSL_INIT_STOP *stop_handlers = NULL; 65 static CRYPTO_RWLOCK *init_lock = NULL; 66 67 static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT; 68 static int base_inited = 0; 69 DEFINE_RUN_ONCE_STATIC(ossl_init_base) 70 { 71 #ifdef OPENSSL_INIT_DEBUG 72 fprintf(stderr, "OPENSSL_INIT: ossl_init_base: Setting up stop handlers\n"); 73 #endif 74 /* 75 * We use a dummy thread local key here. We use the destructor to detect 76 * when the thread is going to stop (where that feature is available) 77 */ 78 CRYPTO_THREAD_init_local(&threadstopkey, ossl_init_thread_stop_wrap); 79 #ifndef OPENSSL_SYS_UEFI 80 atexit(OPENSSL_cleanup); 81 #endif 82 if ((init_lock = CRYPTO_THREAD_lock_new()) == NULL) 83 return 0; 84 OPENSSL_cpuid_setup(); 85 86 /* 87 * BIG FAT WARNING! 88 * Everything needed to be initialized in this function before threads 89 * come along MUST happen before base_inited is set to 1, or we will 90 * see race conditions. 91 */ 92 base_inited = 1; 93 94 #if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE) 95 # ifdef DSO_WIN32 96 { 97 HMODULE handle = NULL; 98 BOOL ret; 99 100 /* We don't use the DSO route for WIN32 because there is a better way */ 101 ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 102 | GET_MODULE_HANDLE_EX_FLAG_PIN, 103 (void *)&base_inited, &handle); 104 105 return (ret == TRUE) ? 1 : 0; 106 } 107 # else 108 /* 109 * Deliberately leak a reference to ourselves. This will force the library 110 * to remain loaded until the atexit() handler is run at process exit. 111 */ 112 { 113 DSO *dso = NULL; 114 115 ERR_set_mark(); 116 dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE); 117 DSO_free(dso); 118 ERR_pop_to_mark(); 119 } 120 # endif 121 #endif 122 123 return 1; 124 } 125 126 static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT; 127 static int load_crypto_strings_inited = 0; 128 DEFINE_RUN_ONCE_STATIC(ossl_init_no_load_crypto_strings) 129 { 130 /* Do nothing in this case */ 131 return 1; 132 } 133 134 DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings) 135 { 136 int ret = 1; 137 /* 138 * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time 139 * pulling in all the error strings during static linking 140 */ 141 #if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT) 142 # ifdef OPENSSL_INIT_DEBUG 143 fprintf(stderr, "OPENSSL_INIT: ossl_init_load_crypto_strings: " 144 "err_load_crypto_strings_int()\n"); 145 # endif 146 ret = err_load_crypto_strings_int(); 147 load_crypto_strings_inited = 1; 148 #endif 149 return ret; 150 } 151 152 static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT; 153 DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers) 154 { 155 /* 156 * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time 157 * pulling in all the ciphers during static linking 158 */ 159 #ifndef OPENSSL_NO_AUTOALGINIT 160 # ifdef OPENSSL_INIT_DEBUG 161 fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_ciphers: " 162 "openssl_add_all_ciphers_int()\n"); 163 # endif 164 openssl_add_all_ciphers_int(); 165 #endif 166 return 1; 167 } 168 169 static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT; 170 DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests) 171 { 172 /* 173 * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time 174 * pulling in all the ciphers during static linking 175 */ 176 #ifndef OPENSSL_NO_AUTOALGINIT 177 # ifdef OPENSSL_INIT_DEBUG 178 fprintf(stderr, "OPENSSL_INIT: ossl_init_add_all_digests: " 179 "openssl_add_all_digests()\n"); 180 # endif 181 openssl_add_all_digests_int(); 182 #endif 183 return 1; 184 } 185 186 DEFINE_RUN_ONCE_STATIC(ossl_init_no_add_algs) 187 { 188 /* Do nothing */ 189 return 1; 190 } 191 192 static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT; 193 static int config_inited = 0; 194 static const char *appname; 195 DEFINE_RUN_ONCE_STATIC(ossl_init_config) 196 { 197 #ifdef OPENSSL_INIT_DEBUG 198 fprintf(stderr, 199 "OPENSSL_INIT: ossl_init_config: openssl_config(%s)\n", 200 appname == NULL ? "NULL" : appname); 201 #endif 202 openssl_config_int(appname); 203 config_inited = 1; 204 return 1; 205 } 206 DEFINE_RUN_ONCE_STATIC(ossl_init_no_config) 207 { 208 #ifdef OPENSSL_INIT_DEBUG 209 fprintf(stderr, 210 "OPENSSL_INIT: ossl_init_config: openssl_no_config_int()\n"); 211 #endif 212 openssl_no_config_int(); 213 config_inited = 1; 214 return 1; 215 } 216 217 static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT; 218 static int async_inited = 0; 219 DEFINE_RUN_ONCE_STATIC(ossl_init_async) 220 { 221 #ifdef OPENSSL_INIT_DEBUG 222 fprintf(stderr, "OPENSSL_INIT: ossl_init_async: async_init()\n"); 223 #endif 224 if (!async_init()) 225 return 0; 226 async_inited = 1; 227 return 1; 228 } 229 230 #ifndef OPENSSL_NO_ENGINE 231 static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT; 232 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl) 233 { 234 # ifdef OPENSSL_INIT_DEBUG 235 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_openssl: " 236 "engine_load_openssl_int()\n"); 237 # endif 238 engine_load_openssl_int(); 239 return 1; 240 } 241 # if !defined(OPENSSL_NO_HW) && \ 242 (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)) 243 static CRYPTO_ONCE engine_cryptodev = CRYPTO_ONCE_STATIC_INIT; 244 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_cryptodev) 245 { 246 # ifdef OPENSSL_INIT_DEBUG 247 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_cryptodev: " 248 "engine_load_cryptodev_int()\n"); 249 # endif 250 engine_load_cryptodev_int(); 251 return 1; 252 } 253 # endif 254 255 # ifndef OPENSSL_NO_RDRAND 256 static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT; 257 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand) 258 { 259 # ifdef OPENSSL_INIT_DEBUG 260 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_rdrand: " 261 "engine_load_rdrand_int()\n"); 262 # endif 263 engine_load_rdrand_int(); 264 return 1; 265 } 266 # endif 267 static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT; 268 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic) 269 { 270 # ifdef OPENSSL_INIT_DEBUG 271 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_dynamic: " 272 "engine_load_dynamic_int()\n"); 273 # endif 274 engine_load_dynamic_int(); 275 return 1; 276 } 277 # ifndef OPENSSL_NO_STATIC_ENGINE 278 # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) 279 static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT; 280 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock) 281 { 282 # ifdef OPENSSL_INIT_DEBUG 283 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_padlock: " 284 "engine_load_padlock_int()\n"); 285 # endif 286 engine_load_padlock_int(); 287 return 1; 288 } 289 # endif 290 # if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) 291 static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT; 292 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi) 293 { 294 # ifdef OPENSSL_INIT_DEBUG 295 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_capi: " 296 "engine_load_capi_int()\n"); 297 # endif 298 engine_load_capi_int(); 299 return 1; 300 } 301 # endif 302 # if !defined(OPENSSL_NO_AFALGENG) 303 static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT; 304 DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg) 305 { 306 # ifdef OPENSSL_INIT_DEBUG 307 fprintf(stderr, "OPENSSL_INIT: ossl_init_engine_afalg: " 308 "engine_load_afalg_int()\n"); 309 # endif 310 engine_load_afalg_int(); 311 return 1; 312 } 313 # endif 314 # endif 315 #endif 316 317 #ifndef OPENSSL_NO_COMP 318 static CRYPTO_ONCE zlib = CRYPTO_ONCE_STATIC_INIT; 319 320 static int zlib_inited = 0; 321 DEFINE_RUN_ONCE_STATIC(ossl_init_zlib) 322 { 323 /* Do nothing - we need to know about this for the later cleanup */ 324 zlib_inited = 1; 325 return 1; 326 } 327 #endif 328 329 static void ossl_init_thread_stop(struct thread_local_inits_st *locals) 330 { 331 /* Can't do much about this */ 332 if (locals == NULL) 333 return; 334 335 if (locals->async) { 336 #ifdef OPENSSL_INIT_DEBUG 337 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " 338 "ASYNC_cleanup_thread()\n"); 339 #endif 340 ASYNC_cleanup_thread(); 341 } 342 343 if (locals->err_state) { 344 #ifdef OPENSSL_INIT_DEBUG 345 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " 346 "err_delete_thread_state()\n"); 347 #endif 348 err_delete_thread_state(); 349 } 350 351 OPENSSL_free(locals); 352 } 353 354 void OPENSSL_thread_stop(void) 355 { 356 ossl_init_thread_stop( 357 (struct thread_local_inits_st *)ossl_init_get_thread_local(0)); 358 } 359 360 int ossl_init_thread_start(uint64_t opts) 361 { 362 struct thread_local_inits_st *locals; 363 364 if (!OPENSSL_init_crypto(0, NULL)) 365 return 0; 366 367 locals = ossl_init_get_thread_local(1); 368 369 if (locals == NULL) 370 return 0; 371 372 if (opts & OPENSSL_INIT_THREAD_ASYNC) { 373 #ifdef OPENSSL_INIT_DEBUG 374 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: " 375 "marking thread for async\n"); 376 #endif 377 locals->async = 1; 378 } 379 380 if (opts & OPENSSL_INIT_THREAD_ERR_STATE) { 381 #ifdef OPENSSL_INIT_DEBUG 382 fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_start: " 383 "marking thread for err_state\n"); 384 #endif 385 locals->err_state = 1; 386 } 387 388 return 1; 389 } 390 391 void OPENSSL_cleanup(void) 392 { 393 OPENSSL_INIT_STOP *currhandler, *lasthandler; 394 395 /* If we've not been inited then no need to deinit */ 396 if (!base_inited) 397 return; 398 399 /* Might be explicitly called and also by atexit */ 400 if (stopped) 401 return; 402 stopped = 1; 403 404 /* 405 * Thread stop may not get automatically called by the thread library for 406 * the very last thread in some situations, so call it directly. 407 */ 408 ossl_init_thread_stop(ossl_init_get_thread_local(0)); 409 410 currhandler = stop_handlers; 411 while (currhandler != NULL) { 412 currhandler->handler(); 413 lasthandler = currhandler; 414 currhandler = currhandler->next; 415 OPENSSL_free(lasthandler); 416 } 417 stop_handlers = NULL; 418 419 CRYPTO_THREAD_lock_free(init_lock); 420 421 /* 422 * We assume we are single-threaded for this function, i.e. no race 423 * conditions for the various "*_inited" vars below. 424 */ 425 426 #ifndef OPENSSL_NO_COMP 427 if (zlib_inited) { 428 #ifdef OPENSSL_INIT_DEBUG 429 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 430 "comp_zlib_cleanup_int()\n"); 431 #endif 432 comp_zlib_cleanup_int(); 433 } 434 #endif 435 436 if (async_inited) { 437 # ifdef OPENSSL_INIT_DEBUG 438 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 439 "async_deinit()\n"); 440 # endif 441 async_deinit(); 442 } 443 444 if (load_crypto_strings_inited) { 445 #ifdef OPENSSL_INIT_DEBUG 446 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 447 "err_free_strings_int()\n"); 448 #endif 449 err_free_strings_int(); 450 } 451 452 CRYPTO_THREAD_cleanup_local(&threadstopkey); 453 454 #ifdef OPENSSL_INIT_DEBUG 455 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 456 "rand_cleanup_int()\n"); 457 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 458 "conf_modules_free_int()\n"); 459 #ifndef OPENSSL_NO_ENGINE 460 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 461 "engine_cleanup_int()\n"); 462 #endif 463 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 464 "crypto_cleanup_all_ex_data_int()\n"); 465 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 466 "bio_sock_cleanup_int()\n"); 467 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 468 "bio_cleanup()\n"); 469 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 470 "evp_cleanup_int()\n"); 471 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 472 "obj_cleanup_int()\n"); 473 fprintf(stderr, "OPENSSL_INIT: OPENSSL_cleanup: " 474 "err_cleanup()\n"); 475 #endif 476 /* 477 * Note that cleanup order is important: 478 * - rand_cleanup_int could call an ENGINE's RAND cleanup function so 479 * must be called before engine_cleanup_int() 480 * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up 481 * before the ex data handlers are wiped in CRYPTO_cleanup_all_ex_data(). 482 * - conf_modules_free_int() can end up in ENGINE code so must be called 483 * before engine_cleanup_int() 484 * - ENGINEs and additional EVP algorithms might use added OIDs names so 485 * obj_cleanup_int() must be called last 486 */ 487 rand_cleanup_int(); 488 conf_modules_free_int(); 489 #ifndef OPENSSL_NO_ENGINE 490 engine_cleanup_int(); 491 #endif 492 crypto_cleanup_all_ex_data_int(); 493 bio_cleanup(); 494 evp_cleanup_int(); 495 obj_cleanup_int(); 496 err_cleanup(); 497 498 base_inited = 0; 499 } 500 501 /* 502 * If this function is called with a non NULL settings value then it must be 503 * called prior to any threads making calls to any OpenSSL functions, 504 * i.e. passing a non-null settings value is assumed to be single-threaded. 505 */ 506 int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) 507 { 508 static int stoperrset = 0; 509 510 if (stopped) { 511 if (!stoperrset) { 512 /* 513 * We only ever set this once to avoid getting into an infinite 514 * loop where the error system keeps trying to init and fails so 515 * sets an error etc 516 */ 517 stoperrset = 1; 518 CRYPTOerr(CRYPTO_F_OPENSSL_INIT_CRYPTO, ERR_R_INIT_FAIL); 519 } 520 return 0; 521 } 522 523 if (!base_inited && !RUN_ONCE(&base, ossl_init_base)) 524 return 0; 525 526 if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS) 527 && !RUN_ONCE(&load_crypto_strings, 528 ossl_init_no_load_crypto_strings)) 529 return 0; 530 531 if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS) 532 && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings)) 533 return 0; 534 535 if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS) 536 && !RUN_ONCE(&add_all_ciphers, ossl_init_no_add_algs)) 537 return 0; 538 539 if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS) 540 && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers)) 541 return 0; 542 543 if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS) 544 && !RUN_ONCE(&add_all_digests, ossl_init_no_add_algs)) 545 return 0; 546 547 if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS) 548 && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests)) 549 return 0; 550 551 if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG) 552 && !RUN_ONCE(&config, ossl_init_no_config)) 553 return 0; 554 555 if (opts & OPENSSL_INIT_LOAD_CONFIG) { 556 int ret; 557 CRYPTO_THREAD_write_lock(init_lock); 558 appname = (settings == NULL) ? NULL : settings->appname; 559 ret = RUN_ONCE(&config, ossl_init_config); 560 CRYPTO_THREAD_unlock(init_lock); 561 if (!ret) 562 return 0; 563 } 564 565 if ((opts & OPENSSL_INIT_ASYNC) 566 && !RUN_ONCE(&async, ossl_init_async)) 567 return 0; 568 569 #ifndef OPENSSL_NO_ENGINE 570 if ((opts & OPENSSL_INIT_ENGINE_OPENSSL) 571 && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl)) 572 return 0; 573 # if !defined(OPENSSL_NO_HW) && \ 574 (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)) 575 if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV) 576 && !RUN_ONCE(&engine_cryptodev, ossl_init_engine_cryptodev)) 577 return 0; 578 # endif 579 # ifndef OPENSSL_NO_RDRAND 580 if ((opts & OPENSSL_INIT_ENGINE_RDRAND) 581 && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand)) 582 return 0; 583 # endif 584 if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC) 585 && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic)) 586 return 0; 587 # ifndef OPENSSL_NO_STATIC_ENGINE 588 # if !defined(OPENSSL_NO_HW) && !defined(OPENSSL_NO_HW_PADLOCK) 589 if ((opts & OPENSSL_INIT_ENGINE_PADLOCK) 590 && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock)) 591 return 0; 592 # endif 593 # if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) 594 if ((opts & OPENSSL_INIT_ENGINE_CAPI) 595 && !RUN_ONCE(&engine_capi, ossl_init_engine_capi)) 596 return 0; 597 # endif 598 # if !defined(OPENSSL_NO_AFALGENG) 599 if ((opts & OPENSSL_INIT_ENGINE_AFALG) 600 && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg)) 601 return 0; 602 # endif 603 # endif 604 if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN 605 | OPENSSL_INIT_ENGINE_OPENSSL 606 | OPENSSL_INIT_ENGINE_AFALG)) { 607 ENGINE_register_all_complete(); 608 } 609 #endif 610 611 #ifndef OPENSSL_NO_COMP 612 if ((opts & OPENSSL_INIT_ZLIB) 613 && !RUN_ONCE(&zlib, ossl_init_zlib)) 614 return 0; 615 #endif 616 617 return 1; 618 } 619 620 int OPENSSL_atexit(void (*handler)(void)) 621 { 622 OPENSSL_INIT_STOP *newhand; 623 624 #if !defined(OPENSSL_NO_DSO) && !defined(OPENSSL_USE_NODELETE) 625 { 626 union { 627 void *sym; 628 void (*func)(void); 629 } handlersym; 630 631 handlersym.func = handler; 632 # ifdef DSO_WIN32 633 { 634 HMODULE handle = NULL; 635 BOOL ret; 636 637 /* 638 * We don't use the DSO route for WIN32 because there is a better 639 * way 640 */ 641 ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 642 | GET_MODULE_HANDLE_EX_FLAG_PIN, 643 handlersym.sym, &handle); 644 645 if (!ret) 646 return 0; 647 } 648 # else 649 /* 650 * Deliberately leak a reference to the handler. This will force the 651 * library/code containing the handler to remain loaded until we run the 652 * atexit handler. If -znodelete has been used then this is 653 * unnecessary. 654 */ 655 { 656 DSO *dso = NULL; 657 658 ERR_set_mark(); 659 dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE); 660 DSO_free(dso); 661 ERR_pop_to_mark(); 662 } 663 # endif 664 } 665 #endif 666 667 newhand = OPENSSL_malloc(sizeof(*newhand)); 668 if (newhand == NULL) 669 return 0; 670 671 newhand->handler = handler; 672 newhand->next = stop_handlers; 673 stop_handlers = newhand; 674 675 return 1; 676 } 677