Skip to content

Commit

Permalink
Fix an init-deadlock in OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_…
Browse files Browse the repository at this point in the history
…STRINGS)

A recursive OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS) call
may happen if an out-of-memory error happens at the first callstack,
and the dead-lock happens at the second callstack, because ossl_err_get_state_int
calls OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS) although that
call is currently already executing.

At least on posix system this causes the process to freeze at this
point, and must be avoided whatever it takes.

The fix is using err_shelve_state around the critical region, which
makes ossl_err_get_state_int return early and not call the recursive
OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS).

This can be reproduced with my error injection patch.

The test vector has been validated on the master branch:

$ ERROR_INJECT=1692279870 ../util/shlib_wrap.sh ./asn1parse-test ./corpora/asn1parse/027f6e82ba01d9db9a9167b83e56cc9f2c602550
ERROR_INJECT=1692279870
    #0 0x7f280b42fef8 in __sanitizer_print_stack_trace ../../../../src/libsanitizer/asan/asan_stack.cpp:86
    #1 0x5610a3f396b4 in my_malloc fuzz/test-corpus.c:114
    #2 0x7f280a2eb94c in CRYPTO_malloc crypto/mem.c:177
    #3 0x7f280a2dafdb in OPENSSL_LH_insert crypto/lhash/lhash.c:114
    #4 0x7f280a1c87fe in err_load_strings crypto/err/err.c:264
    #5 0x7f280a1c87fe in err_load_strings crypto/err/err.c:259
    #6 0x7f280a1c87fe in ERR_load_strings_const crypto/err/err.c:301
    openssl#7 0x7f280a6f513b in ossl_err_load_PROV_strings providers/common/provider_err.c:233
    openssl#8 0x7f280a1cf015 in ossl_err_load_crypto_strings crypto/err/err_all.c:109
    openssl#9 0x7f280a2e9b8c in ossl_init_load_crypto_strings crypto/init.c:190
    openssl#10 0x7f280a2e9b8c in ossl_init_load_crypto_strings_ossl_ crypto/init.c:181
    openssl#11 0x7f2808cfbf67  (/lib/x86_64-linux-gnu/libc.so.6+0x99f67)
    openssl#12 0x7f280a32301e in CRYPTO_THREAD_run_once crypto/threads_pthread.c:154
    openssl#13 0x7f280a2ea1da in OPENSSL_init_crypto crypto/init.c:553
    openssl#14 0x5610a3f38e2f in FuzzerInitialize fuzz/asn1parse.c:29
    openssl#15 0x5610a3f38783 in main fuzz/test-corpus.c:194
    openssl#16 0x7f2808c8bd8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)
    openssl#17 0x7f2808c8be3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f)
    openssl#18 0x5610a3f38d34 in _start (/home/runner/work/openssl/openssl/fuzz/asn1parse-test+0x3d34)

AddressSanitizer:DEADLYSIGNAL
=================================================================
==27629==ERROR: AddressSanitizer: ABRT on unknown address 0x03e900006e23 (pc 0x7f2808cfbef8 bp 0x7f280b36afe0 sp 0x7ffd545b2460 T0)
    #0 0x7f2808cfbef8  (/lib/x86_64-linux-gnu/libc.so.6+0x99ef8)
    #1 0x7f280a32301e in CRYPTO_THREAD_run_once crypto/threads_pthread.c:154
    #2 0x7f280a2ea1da in OPENSSL_init_crypto crypto/init.c:553
    #3 0x7f280a1c935e in ossl_err_get_state_int crypto/err/err.c:705
    #4 0x7f280a1cf1f9 in ERR_new crypto/err/err_blocks.c:20
    #5 0x7f280a2eb9ac in CRYPTO_malloc crypto/mem.c:205
    #6 0x7f280a2dafdb in OPENSSL_LH_insert crypto/lhash/lhash.c:114
    openssl#7 0x7f280a1c87fe in err_load_strings crypto/err/err.c:264
    openssl#8 0x7f280a1c87fe in err_load_strings crypto/err/err.c:259
    openssl#9 0x7f280a1c87fe in ERR_load_strings_const crypto/err/err.c:301
    openssl#10 0x7f280a6f513b in ossl_err_load_PROV_strings providers/common/provider_err.c:233
    openssl#11 0x7f280a1cf015 in ossl_err_load_crypto_strings crypto/err/err_all.c:109
    openssl#12 0x7f280a2e9b8c in ossl_init_load_crypto_strings crypto/init.c:190
    openssl#13 0x7f280a2e9b8c in ossl_init_load_crypto_strings_ossl_ crypto/init.c:181
    openssl#14 0x7f2808cfbf67  (/lib/x86_64-linux-gnu/libc.so.6+0x99f67)
    openssl#15 0x7f280a32301e in CRYPTO_THREAD_run_once crypto/threads_pthread.c:154
    openssl#16 0x7f280a2ea1da in OPENSSL_init_crypto crypto/init.c:553
    openssl#17 0x5610a3f38e2f in FuzzerInitialize fuzz/asn1parse.c:29
    openssl#18 0x5610a3f38783 in main fuzz/test-corpus.c:194
    openssl#19 0x7f2808c8bd8f  (/lib/x86_64-linux-gnu/libc.so.6+0x29d8f)
    openssl#20 0x7f2808c8be3f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29e3f)
    openssl#21 0x5610a3f38d34 in _start (/home/runner/work/openssl/openssl/fuzz/asn1parse-test+0x3d34)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: ABRT (/lib/x86_64-linux-gnu/libc.so.6+0x99ef8)
==27629==ABORTING

Reviewed-by: Tomas Mraz <[email protected]>
Reviewed-by: Tom Cosgrove <[email protected]>
(Merged from openssl#21683)
  • Loading branch information
bernd-edlinger committed Aug 10, 2023
1 parent 420a087 commit 6b1a127
Showing 1 changed file with 7 additions and 0 deletions.
7 changes: 7 additions & 0 deletions crypto/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,15 @@ DEFINE_RUN_ONCE_STATIC(ossl_init_load_crypto_strings)
* pulling in all the error strings during static linking
*/
#if !defined(OPENSSL_NO_ERR) && !defined(OPENSSL_NO_AUTOERRINIT)
void *err;

if (!err_shelve_state(&err))
return 0;

OSSL_TRACE(INIT, "ossl_err_load_crypto_strings()\n");
ret = ossl_err_load_crypto_strings();

err_unshelve_state(err);
#endif
return ret;
}
Expand Down

0 comments on commit 6b1a127

Please sign in to comment.