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