openssl: Calling RAND_DRBG_get0_public without locks initialized segfaults on platforms without atomics

Hi ,every experts. I am newbie in Openssl. I have a issue when call RAND_DRBG_get0_public in program. The following is the detail information,please help to check what’s wrong? Thanks in advance.

uname -a
Linux linux 2.6.32.45-0.3-default #1 SMP 2011-08-22 10:12:58 +0200 x86_64 x86_64 x86_64 GNU/Linux
cat /etc/SuSE-release
SUSE Linux Enterprise Server 11 (x86_64)
VERSION = 11
PATCHLEVEL = 1

code snap:

static RAND_DRBG *public_drbg;
bool init_drbg(void)
{
	unsigned int reseedinterval = 0;
	time_t health_check_interval = 0;
	
	public_drbg = RAND_DRBG_get0_public();
	if (public_drbg == NULL)
	{
		return false;
	}
}

core stack information:

#0  0x00007f7a8e455c8a in pthread_rwlock_wrlock () from /lib64/libpthread.so.0
(gdb) bt
#0  0x00007f7a8e455c8a in pthread_rwlock_wrlock () from /lib64/libpthread.so.0
#1  0x00007f7a8dee0d89 in CRYPTO_THREAD_write_lock () from /usr/local/lib64/libcrypto.so.1.1
#2  0x0000000000007cf7 in ?? ()
#3  0x00007f7a8dee0dcc in CRYPTO_atomic_add () from /usr/local/lib64/libcrypto.so.1.1
#4  0x5bf3984a0008b192 in ?? ()
#5  0x0000000000000000 in ?? ()
(gdb)

but when call like following

public_drbg = RAND_DRBG_new(NID_aes_256_ctr, 0, NULL);

the program is ok, not coredump will be issued.

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 24 (15 by maintainers)

Commits related to this issue

Most upvoted comments

Hi,

AFAIK, @kuncao is using SLES 11 SP1. This implies GCC 4.3. This implies no support for C11 atomics, nor the underlying GCC _atomic* builtins. This implies that the pthread locks code path is used.

However, based on code posted by @kuncao , do_rand_init() from rand_lib.c is never called through, since there is no call to e.g. RAND_poll(), RAND_get_rand_method(), etc. So, the pthread locks are… never initialized. Hence the crash.

How to fix?

  • Have @kuncao upgrade to a modern compiler so that crypto atomics are implemented over C11/GCC atomics. But this probably isn’t an option to him, and the issue would remain for others ;
  • Implement crypto atomics with old-style GCC _sync* primitives. But this probably isn’t a good idea either since those are deprecated ;
  • Make sure that the default get_nonce() implementation have its pthread lock initialized before use? This sounds like the better option. Fortunately, this is implemented in the master branch, AFAICS. Unfortunately, this still is not the case for 1.1.x series.

Do people agree with this analysis?

OMG! It looks like I was confusing the function calls with function definitions in the unformatted and improperly indented output. https://github.com/openssl/openssl/issues/7870#issuecomment-446429599. Thanks for reformatting it! And please forget everything that I said about the RAND_DRBG_ functions… 😊.