Coverage Report

Created: 2025-06-13 06:55

/src/openssl/crypto/init.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2016-2025 The OpenSSL Project Authors. All Rights Reserved.
3
 *
4
 * Licensed under the Apache License 2.0 (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
/* We need to use some engine deprecated APIs */
11
#define OPENSSL_SUPPRESS_DEPRECATED
12
13
#include "internal/e_os.h"
14
#include "crypto/cryptlib.h"
15
#include <openssl/err.h>
16
#include "crypto/rand.h"
17
#include "internal/bio.h"
18
#include <openssl/evp.h>
19
#include "crypto/evp.h"
20
#include "internal/conf.h"
21
#include "crypto/async.h"
22
#include "crypto/engine.h"
23
#include "internal/comp.h"
24
#include "internal/err.h"
25
#include "crypto/err.h"
26
#include "crypto/objects.h"
27
#include <stdlib.h>
28
#include <assert.h>
29
#include "internal/thread_once.h"
30
#include "crypto/dso_conf.h"
31
#include "internal/dso.h"
32
#include "crypto/store.h"
33
#include <openssl/cmp_util.h> /* for OSSL_CMP_log_close() */
34
#include <openssl/trace.h>
35
#include <openssl/ssl.h> /* for OPENSSL_INIT_(NO_)?LOAD_SSL_STRINGS */
36
#include "crypto/ctype.h"
37
#include "sslerr.h"
38
39
static int stopped = 0;
40
static uint64_t optsdone = 0;
41
42
typedef struct ossl_init_stop_st OPENSSL_INIT_STOP;
43
struct ossl_init_stop_st {
44
    void (*handler)(void);
45
    OPENSSL_INIT_STOP *next;
46
};
47
48
static OPENSSL_INIT_STOP *stop_handlers = NULL;
49
/* Guards access to the optsdone variable on platforms without atomics */
50
static CRYPTO_RWLOCK *optsdone_lock = NULL;
51
/* Guards simultaneous INIT_LOAD_CONFIG calls with non-NULL settings */
52
static CRYPTO_RWLOCK *init_lock = NULL;
53
static CRYPTO_THREAD_LOCAL in_init_config_local;
54
55
static CRYPTO_ONCE base = CRYPTO_ONCE_STATIC_INIT;
56
static int base_inited = 0;
57
DEFINE_RUN_ONCE_STATIC(ossl_init_base)
58
1
{
59
    /* no need to init trace */
60
61
1
    OSSL_TRACE(INIT, "ossl_init_base: setting up stop handlers\n");
62
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
63
    ossl_malloc_setup_failures();
64
#endif
65
66
1
    if ((optsdone_lock = CRYPTO_THREAD_lock_new()) == NULL
67
1
        || (init_lock = CRYPTO_THREAD_lock_new()) == NULL)
68
0
        goto err;
69
70
1
    OPENSSL_cpuid_setup();
71
72
1
    if (!ossl_init_thread())
73
0
        goto err;
74
75
1
    if (!CRYPTO_THREAD_init_local(&in_init_config_local, NULL))
76
0
        goto err;
77
78
1
    base_inited = 1;
79
1
    return 1;
80
81
0
err:
82
0
    OSSL_TRACE(INIT, "ossl_init_base failed!\n");
83
0
    CRYPTO_THREAD_lock_free(optsdone_lock);
84
0
    optsdone_lock = NULL;
85
0
    CRYPTO_THREAD_lock_free(init_lock);
86
0
    init_lock = NULL;
87
88
0
    return 0;
89
1
}
90
91
static CRYPTO_ONCE register_atexit = CRYPTO_ONCE_STATIC_INIT;
92
#if !defined(OPENSSL_SYS_UEFI) && defined(_WIN32)
93
static int win32atexit(void)
94
{
95
    OPENSSL_cleanup();
96
    return 0;
97
}
98
#endif
99
100
DEFINE_RUN_ONCE_STATIC(ossl_init_register_atexit)
101
1
{
102
1
#ifndef OPENSSL_NO_ATEXIT
103
# ifdef OPENSSL_INIT_DEBUG
104
    fprintf(stderr, "OPENSSL_INIT: ossl_init_register_atexit()\n");
105
# endif
106
1
# ifndef OPENSSL_SYS_UEFI
107
#  if defined(_WIN32) && !defined(__BORLANDC__)
108
    /* We use _onexit() in preference because it gets called on DLL unload */
109
    if (_onexit(win32atexit) == NULL)
110
        return 0;
111
#  else
112
1
    if (atexit(OPENSSL_cleanup) != 0)
113
0
        return 0;
114
1
#  endif
115
1
# endif
116
1
#endif
117
118
1
    return 1;
119
1
}
120
121
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_register_atexit,
122
                           ossl_init_register_atexit)
123
0
{
124
#ifdef OPENSSL_INIT_DEBUG
125
    fprintf(stderr, "OPENSSL_INIT: ossl_init_no_register_atexit ok!\n");
126
#endif
127
    /* Do nothing in this case */
128
0
    return 1;
129
0
}
130
131
static CRYPTO_ONCE load_crypto_nodelete = CRYPTO_ONCE_STATIC_INIT;
132
DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_nodelete)
133
1
{
134
1
    OSSL_TRACE(INIT, "ossl_init_load_crypto_nodelete()\n");
135
136
#if !defined(OPENSSL_USE_NODELETE) \
137
    && !defined(OPENSSL_NO_PINSHARED)
138
# if defined(DSO_WIN32) && !defined(_WIN32_WCE)
139
    {
140
        HMODULE handle = NULL;
141
        BOOL ret;
142
143
        /* We don't use the DSO route for WIN32 because there is a better way */
144
        ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
145
                                | GET_MODULE_HANDLE_EX_FLAG_PIN,
146
                                (void *)&base_inited, &handle);
147
148
        OSSL_TRACE1(INIT,
149
                    "ossl_init_load_crypto_nodelete: "
150
                    "obtained DSO reference? %s\n",
151
                    (ret == TRUE ? "No!" : "Yes."));
152
        return (ret == TRUE) ? 1 : 0;
153
    }
154
# elif !defined(DSO_NONE)
155
    /*
156
     * Deliberately leak a reference to ourselves. This will force the library
157
     * to remain loaded until the atexit() handler is run at process exit.
158
     */
159
    {
160
        DSO *dso;
161
        void *err;
162
163
        if (!err_shelve_state(&err))
164
            return 0;
165
166
        dso = DSO_dsobyaddr(&base_inited, DSO_FLAG_NO_UNLOAD_ON_FREE);
167
        /*
168
         * In case of No!, it is uncertain our exit()-handlers can still be
169
         * called. After dlclose() the whole library might have been unloaded
170
         * already.
171
         */
172
        OSSL_TRACE1(INIT, "obtained DSO reference? %s\n",
173
                    (dso == NULL ? "No!" : "Yes."));
174
        DSO_free(dso);
175
        err_unshelve_state(err);
176
    }
177
# endif
178
#endif
179
180
1
    return 1;
181
1
}
182
183
static CRYPTO_ONCE load_crypto_strings = CRYPTO_ONCE_STATIC_INIT;
184
185
DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)
186
1
{
187
1
    int ret = 1;
188
    /*
189
     * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
190
     * pulling in all the error strings during static linking
191
     */
192
1
#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
193
1
    void *err;
194
195
1
    if (!err_shelve_state(&err))
196
0
        return 0;
197
198
1
    OSSL_TRACE(INIT, "ossl_err_load_crypto_strings()\n");
199
1
    ret = ossl_err_load_crypto_strings();
200
201
1
    err_unshelve_state(err);
202
1
#endif
203
1
    return ret;
204
1
}
205
206
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_crypto_strings,
207
                           ossl_init_load_crypto_strings)
208
0
{
209
    /* Do nothing in this case */
210
0
    return 1;
211
0
}
212
213
static CRYPTO_ONCE ssl_strings = CRYPTO_ONCE_STATIC_INIT;
214
215
DEFINE_RUN_ONCE_STATIC(ossl_init_load_ssl_strings)
216
0
{
217
    /*
218
     * OPENSSL_NO_AUTOERRINIT is provided here to prevent at compile time
219
     * pulling in all the error strings during static linking
220
     */
221
0
#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
222
0
    OSSL_TRACE(INIT, "ossl_init_load_ssl_strings: ossl_err_load_SSL_strings()\n");
223
0
    ossl_err_load_SSL_strings();
224
0
#endif
225
0
    return 1;
226
0
}
227
228
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_load_ssl_strings,
229
                           ossl_init_load_ssl_strings)
230
0
{
231
    /* Do nothing in this case */
232
0
    return 1;
233
0
}
234
235
static CRYPTO_ONCE add_all_ciphers = CRYPTO_ONCE_STATIC_INIT;
236
DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_ciphers)
237
0
{
238
    /*
239
     * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
240
     * pulling in all the ciphers during static linking
241
     */
242
0
#ifndef OPENSSL_NO_AUTOALGINIT
243
0
    OSSL_TRACE(INIT, "openssl_add_all_ciphers_int()\n");
244
0
    openssl_add_all_ciphers_int();
245
0
#endif
246
0
    return 1;
247
0
}
248
249
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_ciphers,
250
                           ossl_init_add_all_ciphers)
251
0
{
252
    /* Do nothing */
253
0
    return 1;
254
0
}
255
256
static CRYPTO_ONCE add_all_digests = CRYPTO_ONCE_STATIC_INIT;
257
DEFINE_RUN_ONCE_STATIC(ossl_init_add_all_digests)
258
0
{
259
    /*
260
     * OPENSSL_NO_AUTOALGINIT is provided here to prevent at compile time
261
     * pulling in all the ciphers during static linking
262
     */
263
0
#ifndef OPENSSL_NO_AUTOALGINIT
264
0
    OSSL_TRACE(INIT, "openssl_add_all_digests()\n");
265
0
    openssl_add_all_digests_int();
266
0
#endif
267
0
    return 1;
268
0
}
269
270
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_add_all_digests,
271
                           ossl_init_add_all_digests)
272
0
{
273
    /* Do nothing */
274
0
    return 1;
275
0
}
276
277
static CRYPTO_ONCE config = CRYPTO_ONCE_STATIC_INIT;
278
static int config_inited = 0;
279
static const OPENSSL_INIT_SETTINGS *conf_settings = NULL;
280
DEFINE_RUN_ONCE_STATIC(ossl_init_config)
281
1
{
282
1
    int ret = ossl_config_int(NULL);
283
284
1
    config_inited = 1;
285
1
    return ret;
286
1
}
287
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_config_settings, ossl_init_config)
288
0
{
289
0
    int ret = ossl_config_int(conf_settings);
290
291
0
    config_inited = 1;
292
0
    return ret;
293
0
}
294
DEFINE_RUN_ONCE_STATIC_ALT(ossl_init_no_config, ossl_init_config)
295
0
{
296
0
    OSSL_TRACE(INIT, "ossl_no_config_int()\n");
297
0
    ossl_no_config_int();
298
0
    config_inited = 1;
299
0
    return 1;
300
0
}
301
302
static CRYPTO_ONCE async = CRYPTO_ONCE_STATIC_INIT;
303
static int async_inited = 0;
304
DEFINE_RUN_ONCE_STATIC(ossl_init_async)
305
0
{
306
0
    OSSL_TRACE(INIT, "async_init()\n");
307
0
    if (!async_init())
308
0
        return 0;
309
0
    async_inited = 1;
310
0
    return 1;
311
0
}
312
313
#ifndef OPENSSL_NO_ENGINE
314
static CRYPTO_ONCE engine_openssl = CRYPTO_ONCE_STATIC_INIT;
315
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_openssl)
316
0
{
317
0
    OSSL_TRACE(INIT, "engine_load_openssl_int()\n");
318
0
    engine_load_openssl_int();
319
0
    return 1;
320
0
}
321
# ifndef OPENSSL_NO_RDRAND
322
static CRYPTO_ONCE engine_rdrand = CRYPTO_ONCE_STATIC_INIT;
323
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_rdrand)
324
0
{
325
0
    OSSL_TRACE(INIT, "engine_load_rdrand_int()\n");
326
0
    engine_load_rdrand_int();
327
0
    return 1;
328
0
}
329
# endif
330
static CRYPTO_ONCE engine_dynamic = CRYPTO_ONCE_STATIC_INIT;
331
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_dynamic)
332
0
{
333
0
    OSSL_TRACE(INIT, "engine_load_dynamic_int()\n");
334
0
    engine_load_dynamic_int();
335
0
    return 1;
336
0
}
337
# ifndef OPENSSL_NO_STATIC_ENGINE
338
#  ifndef OPENSSL_NO_DEVCRYPTOENG
339
static CRYPTO_ONCE engine_devcrypto = CRYPTO_ONCE_STATIC_INIT;
340
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_devcrypto)
341
{
342
    OSSL_TRACE(INIT, "engine_load_devcrypto_int()\n");
343
    engine_load_devcrypto_int();
344
    return 1;
345
}
346
#  endif
347
#  if !defined(OPENSSL_NO_PADLOCKENG)
348
static CRYPTO_ONCE engine_padlock = CRYPTO_ONCE_STATIC_INIT;
349
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_padlock)
350
0
{
351
0
    OSSL_TRACE(INIT, "engine_load_padlock_int()\n");
352
0
    engine_load_padlock_int();
353
0
    return 1;
354
0
}
355
#  endif
356
#  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
357
static CRYPTO_ONCE engine_capi = CRYPTO_ONCE_STATIC_INIT;
358
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_capi)
359
{
360
    OSSL_TRACE(INIT, "engine_load_capi_int()\n");
361
    engine_load_capi_int();
362
    return 1;
363
}
364
#  endif
365
#  if !defined(OPENSSL_NO_AFALGENG)
366
static CRYPTO_ONCE engine_afalg = CRYPTO_ONCE_STATIC_INIT;
367
DEFINE_RUN_ONCE_STATIC(ossl_init_engine_afalg)
368
0
{
369
0
    OSSL_TRACE(INIT, "engine_load_afalg_int()\n");
370
0
    engine_load_afalg_int();
371
0
    return 1;
372
0
}
373
#  endif
374
# endif
375
#endif
376
377
void OPENSSL_cleanup(void)
378
1
{
379
1
    OPENSSL_INIT_STOP *currhandler, *lasthandler;
380
381
    /*
382
     * At some point we should consider looking at this function with a view to
383
     * moving most/all of this into onfree handlers in OSSL_LIB_CTX.
384
     */
385
386
    /* If we've not been inited then no need to deinit */
387
1
    if (!base_inited)
388
0
        return;
389
390
    /* Might be explicitly called and also by atexit */
391
1
    if (stopped)
392
0
        return;
393
1
    stopped = 1;
394
395
    /*
396
     * Thread stop may not get automatically called by the thread library for
397
     * the very last thread in some situations, so call it directly.
398
     */
399
1
    OPENSSL_thread_stop();
400
401
1
    currhandler = stop_handlers;
402
1
    while (currhandler != NULL) {
403
0
        currhandler->handler();
404
0
        lasthandler = currhandler;
405
0
        currhandler = currhandler->next;
406
0
        OPENSSL_free(lasthandler);
407
0
    }
408
1
    stop_handlers = NULL;
409
410
1
    CRYPTO_THREAD_lock_free(optsdone_lock);
411
1
    optsdone_lock = NULL;
412
1
    CRYPTO_THREAD_lock_free(init_lock);
413
1
    init_lock = NULL;
414
415
1
    CRYPTO_THREAD_cleanup_local(&in_init_config_local);
416
417
    /*
418
     * We assume we are single-threaded for this function, i.e. no race
419
     * conditions for the various "*_inited" vars below.
420
     */
421
422
1
#ifndef OPENSSL_NO_COMP
423
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_zlib_cleanup()\n");
424
1
    ossl_comp_zlib_cleanup();
425
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_brotli_cleanup()\n");
426
1
    ossl_comp_brotli_cleanup();
427
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_comp_zstd_cleanup()\n");
428
1
    ossl_comp_zstd_cleanup();
429
1
#endif
430
431
1
    if (async_inited) {
432
0
        OSSL_TRACE(INIT, "OPENSSL_cleanup: async_deinit()\n");
433
0
        async_deinit();
434
0
    }
435
436
    /*
437
     * Note that cleanup order is important:
438
     * - ossl_rand_cleanup_int could call an ENGINE's RAND cleanup function so
439
     * must be called before engine_cleanup_int()
440
     * - ENGINEs use CRYPTO_EX_DATA and therefore, must be cleaned up
441
     * before the ex data handlers are wiped during default ossl_lib_ctx deinit.
442
     * - ossl_config_modules_free() can end up in ENGINE code so must be called
443
     * before engine_cleanup_int()
444
     * - ENGINEs and additional EVP algorithms might use added OIDs names so
445
     * ossl_obj_cleanup_int() must be called last
446
     */
447
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_rand_cleanup_int()\n");
448
1
    ossl_rand_cleanup_int();
449
450
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_config_modules_free()\n");
451
1
    ossl_config_modules_free();
452
453
1
#ifndef OPENSSL_NO_ENGINE
454
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: engine_cleanup_int()\n");
455
1
    engine_cleanup_int();
456
1
#endif
457
458
1
#ifndef OPENSSL_NO_DEPRECATED_3_0
459
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_store_cleanup_int()\n");
460
1
    ossl_store_cleanup_int();
461
1
#endif
462
463
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_lib_ctx_default_deinit()\n");
464
1
    ossl_lib_ctx_default_deinit();
465
466
1
    ossl_cleanup_thread();
467
468
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: bio_cleanup()\n");
469
1
    bio_cleanup();
470
471
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: evp_cleanup_int()\n");
472
1
    evp_cleanup_int();
473
474
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_obj_cleanup_int()\n");
475
1
    ossl_obj_cleanup_int();
476
477
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: err_int()\n");
478
1
    err_cleanup();
479
480
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: CRYPTO_secure_malloc_done()\n");
481
1
    CRYPTO_secure_malloc_done();
482
483
1
#ifndef OPENSSL_NO_CMP
484
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: OSSL_CMP_log_close()\n");
485
1
    OSSL_CMP_log_close();
486
1
#endif
487
488
1
    OSSL_TRACE(INIT, "OPENSSL_cleanup: ossl_trace_cleanup()\n");
489
1
    ossl_trace_cleanup();
490
491
1
    base_inited = 0;
492
1
}
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
507k
{
501
507k
    uint64_t tmp;
502
507k
    int aloaddone = 0;
503
504
   /* Applications depend on 0 being returned when cleanup was already done */
505
507k
    if (stopped) {
506
0
        if (!(opts & OPENSSL_INIT_BASE_ONLY))
507
0
            ERR_raise(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL);
508
0
        return 0;
509
0
    }
510
511
    /*
512
     * We ignore failures from this function. It is probably because we are
513
     * on a platform that doesn't support lockless atomic loads (we may not
514
     * have created optsdone_lock yet so we can't use it). This is just an
515
     * optimisation to skip the full checks in this function if we don't need
516
     * to, so we carry on regardless in the event of failure.
517
     *
518
     * There could be a race here with other threads, so that optsdone has not
519
     * been updated yet, even though the options have in fact been initialised.
520
     * This doesn't matter - it just means we will run the full function
521
     * unnecessarily - but all the critical code is contained in RUN_ONCE
522
     * functions anyway so we are safe.
523
     */
524
507k
    if (CRYPTO_atomic_load(&optsdone, &tmp, NULL)) {
525
507k
        if ((tmp & opts) == opts)
526
445k
            return 1;
527
61.9k
        aloaddone = 1;
528
61.9k
    }
529
530
    /*
531
     * At some point we should look at this function with a view to moving
532
     * most/all of this into OSSL_LIB_CTX.
533
     *
534
     * When the caller specifies OPENSSL_INIT_BASE_ONLY, that should be the
535
     * *only* option specified.  With that option we return immediately after
536
     * doing the requested limited initialization.  Note that
537
     * err_shelve_state() called by us via ossl_init_load_crypto_nodelete()
538
     * re-enters OPENSSL_init_crypto() with OPENSSL_INIT_BASE_ONLY, but with
539
     * base already initialized this is a harmless NOOP.
540
     *
541
     * If we remain the only caller of err_shelve_state() the recursion should
542
     * perhaps be removed, but if in doubt, it can be left in place.
543
     */
544
61.9k
    if (!RUN_ONCE(&base, ossl_init_base))
545
0
        return 0;
546
547
61.9k
    if (opts & OPENSSL_INIT_BASE_ONLY)
548
61.9k
        return 1;
549
550
    /*
551
     * optsdone_lock should definitely be set up now, so we can now repeat the
552
     * same check from above but be sure that it will work even on platforms
553
     * without lockless CRYPTO_atomic_load
554
     */
555
2
    if (!aloaddone) {
556
0
        if (!CRYPTO_atomic_load(&optsdone, &tmp, optsdone_lock))
557
0
            return 0;
558
0
        if ((tmp & opts) == opts)
559
0
            return 1;
560
0
    }
561
562
    /*
563
     * Now we don't always set up exit handlers, the INIT_BASE_ONLY calls
564
     * should not have the side-effect of setting up exit handlers, and
565
     * therefore, this code block is below the INIT_BASE_ONLY-conditioned early
566
     * return above.
567
     */
568
2
    if ((opts & OPENSSL_INIT_NO_ATEXIT) != 0) {
569
0
        if (!RUN_ONCE_ALT(&register_atexit, ossl_init_no_register_atexit,
570
0
                          ossl_init_register_atexit))
571
0
            return 0;
572
2
    } else if (!RUN_ONCE(&register_atexit, ossl_init_register_atexit)) {
573
0
        return 0;
574
0
    }
575
576
2
    if (!RUN_ONCE(&load_crypto_nodelete, ossl_init_load_crypto_nodelete))
577
0
        return 0;
578
579
2
    if ((opts & OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS)
580
2
            && !RUN_ONCE_ALT(&load_crypto_strings,
581
2
                             ossl_init_no_load_crypto_strings,
582
2
                             ossl_init_load_crypto_strings))
583
0
        return 0;
584
585
2
    if ((opts & OPENSSL_INIT_LOAD_CRYPTO_STRINGS)
586
2
            && !RUN_ONCE(&load_crypto_strings, ossl_init_load_crypto_strings))
587
0
        return 0;
588
589
2
    if ((opts & OPENSSL_INIT_NO_LOAD_SSL_STRINGS)
590
2
        && !RUN_ONCE_ALT(&ssl_strings, ossl_init_no_load_ssl_strings,
591
2
                         ossl_init_load_ssl_strings))
592
0
        return 0;
593
594
2
    if ((opts & OPENSSL_INIT_LOAD_SSL_STRINGS)
595
2
        && !RUN_ONCE(&ssl_strings, ossl_init_load_ssl_strings))
596
0
        return 0;
597
598
2
    if ((opts & OPENSSL_INIT_NO_ADD_ALL_CIPHERS)
599
2
            && !RUN_ONCE_ALT(&add_all_ciphers, ossl_init_no_add_all_ciphers,
600
2
                             ossl_init_add_all_ciphers))
601
0
        return 0;
602
603
2
    if ((opts & OPENSSL_INIT_ADD_ALL_CIPHERS)
604
2
            && !RUN_ONCE(&add_all_ciphers, ossl_init_add_all_ciphers))
605
0
        return 0;
606
607
2
    if ((opts & OPENSSL_INIT_NO_ADD_ALL_DIGESTS)
608
2
            && !RUN_ONCE_ALT(&add_all_digests, ossl_init_no_add_all_digests,
609
2
                             ossl_init_add_all_digests))
610
0
        return 0;
611
612
2
    if ((opts & OPENSSL_INIT_ADD_ALL_DIGESTS)
613
2
            && !RUN_ONCE(&add_all_digests, ossl_init_add_all_digests))
614
0
        return 0;
615
616
2
    if ((opts & OPENSSL_INIT_ATFORK)
617
2
            && !openssl_init_fork_handlers())
618
0
        return 0;
619
620
2
    if ((opts & OPENSSL_INIT_NO_LOAD_CONFIG)
621
2
            && !RUN_ONCE_ALT(&config, ossl_init_no_config, ossl_init_config))
622
0
        return 0;
623
624
2
    if (opts & OPENSSL_INIT_LOAD_CONFIG) {
625
1
        int loading = CRYPTO_THREAD_get_local(&in_init_config_local) != NULL;
626
627
        /* If called recursively from OBJ_ calls, just skip it. */
628
1
        if (!loading) {
629
1
            int ret;
630
631
1
            if (!CRYPTO_THREAD_set_local(&in_init_config_local, (void *)-1))
632
0
                return 0;
633
1
            if (settings == NULL) {
634
1
                ret = RUN_ONCE(&config, ossl_init_config);
635
1
            } else {
636
0
                if (!CRYPTO_THREAD_write_lock(init_lock))
637
0
                    return 0;
638
0
                conf_settings = settings;
639
0
                ret = RUN_ONCE_ALT(&config, ossl_init_config_settings,
640
0
                                   ossl_init_config);
641
0
                conf_settings = NULL;
642
0
                CRYPTO_THREAD_unlock(init_lock);
643
0
            }
644
645
1
            if (ret <= 0)
646
0
                return 0;
647
1
        }
648
1
    }
649
650
2
    if ((opts & OPENSSL_INIT_ASYNC)
651
2
            && !RUN_ONCE(&async, ossl_init_async))
652
0
        return 0;
653
654
2
#ifndef OPENSSL_NO_ENGINE
655
2
    if ((opts & OPENSSL_INIT_ENGINE_OPENSSL)
656
2
            && !RUN_ONCE(&engine_openssl, ossl_init_engine_openssl))
657
0
        return 0;
658
2
# ifndef OPENSSL_NO_RDRAND
659
2
    if ((opts & OPENSSL_INIT_ENGINE_RDRAND)
660
2
            && !RUN_ONCE(&engine_rdrand, ossl_init_engine_rdrand))
661
0
        return 0;
662
2
# endif
663
2
    if ((opts & OPENSSL_INIT_ENGINE_DYNAMIC)
664
2
            && !RUN_ONCE(&engine_dynamic, ossl_init_engine_dynamic))
665
0
        return 0;
666
2
# ifndef OPENSSL_NO_STATIC_ENGINE
667
#  ifndef OPENSSL_NO_DEVCRYPTOENG
668
    if ((opts & OPENSSL_INIT_ENGINE_CRYPTODEV)
669
            && !RUN_ONCE(&engine_devcrypto, ossl_init_engine_devcrypto))
670
        return 0;
671
#  endif
672
2
#  if !defined(OPENSSL_NO_PADLOCKENG)
673
2
    if ((opts & OPENSSL_INIT_ENGINE_PADLOCK)
674
2
            && !RUN_ONCE(&engine_padlock, ossl_init_engine_padlock))
675
0
        return 0;
676
2
#  endif
677
#  if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG)
678
    if ((opts & OPENSSL_INIT_ENGINE_CAPI)
679
            && !RUN_ONCE(&engine_capi, ossl_init_engine_capi))
680
        return 0;
681
#  endif
682
2
#  if !defined(OPENSSL_NO_AFALGENG)
683
2
    if ((opts & OPENSSL_INIT_ENGINE_AFALG)
684
2
            && !RUN_ONCE(&engine_afalg, ossl_init_engine_afalg))
685
0
        return 0;
686
2
#  endif
687
2
# endif
688
2
    if (opts & (OPENSSL_INIT_ENGINE_ALL_BUILTIN
689
2
                | OPENSSL_INIT_ENGINE_OPENSSL
690
2
                | OPENSSL_INIT_ENGINE_AFALG)) {
691
0
        ENGINE_register_all_complete();
692
0
    }
693
2
#endif
694
695
2
    if (!CRYPTO_atomic_or(&optsdone, opts, &tmp, optsdone_lock))
696
0
        return 0;
697
698
2
    return 1;
699
2
}
700
701
int OPENSSL_atexit(void (*handler)(void))
702
0
{
703
0
    OPENSSL_INIT_STOP *newhand;
704
705
#if !defined(OPENSSL_USE_NODELETE)\
706
    && !defined(OPENSSL_NO_PINSHARED)
707
    {
708
# if defined(DSO_WIN32) && !defined(_WIN32_WCE)
709
        HMODULE handle = NULL;
710
        BOOL ret;
711
        union {
712
            void *sym;
713
            void (*func)(void);
714
        } handlersym;
715
716
        handlersym.func = handler;
717
718
        /*
719
         * We don't use the DSO route for WIN32 because there is a better
720
         * way
721
         */
722
        ret = GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
723
                                | GET_MODULE_HANDLE_EX_FLAG_PIN,
724
                                handlersym.sym, &handle);
725
726
        if (!ret)
727
            return 0;
728
# elif !defined(DSO_NONE)
729
        /*
730
         * Deliberately leak a reference to the handler. This will force the
731
         * library/code containing the handler to remain loaded until we run the
732
         * atexit handler. If -znodelete has been used then this is
733
         * unnecessary.
734
         */
735
        DSO *dso = NULL;
736
        union {
737
            void *sym;
738
            void (*func)(void);
739
        } handlersym;
740
741
        handlersym.func = handler;
742
743
        ERR_set_mark();
744
        dso = DSO_dsobyaddr(handlersym.sym, DSO_FLAG_NO_UNLOAD_ON_FREE);
745
        /* See same code above in ossl_init_base() for an explanation. */
746
        OSSL_TRACE1(INIT,
747
                   "atexit: obtained DSO reference? %s\n",
748
                   (dso == NULL ? "No!" : "Yes."));
749
        DSO_free(dso);
750
        ERR_pop_to_mark();
751
# endif
752
    }
753
#endif
754
755
0
    if ((newhand = OPENSSL_malloc(sizeof(*newhand))) == NULL)
756
0
        return 0;
757
758
0
    newhand->handler = handler;
759
0
    newhand->next = stop_handlers;
760
0
    stop_handlers = newhand;
761
762
0
    return 1;
763
0
}
764