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