New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
segfault when shared library uses getrandom() in library initialization and FAKERANDOM_SEED is unset #295
Comments
The above report is from a debian amd64 (x86_64) testing/unstable, fwiw. all of the segfaulting executables i've found thus far are linking against libgnutls, which is (i think) where they're invoking If i permit a crash from the test to dump core, and then try to load the corefile into gdb, i get an unannotated backtrace, even though test program is not stripped, and i have the debug symbols for gnutls installed:
|
I've traced this back to I have no explanation for this yet and need to investigate further. If you have a minimum example of a GnuTLS-based C program (which crashes) lying around somewhere, that'd be useful. I'll try my luck with |
sample /* gnutls_rnd.c */
#include <stdio.h>
#include <string.h>
#include <gnutls/crypto.h>
int main() {
unsigned char buf[10];
int rc;
struct { int level; const char* name; } steps[] = {
{GNUTLS_RND_NONCE, "NONCE"},
{GNUTLS_RND_RANDOM, "RANDOM"},
{GNUTLS_RND_KEY, "KEY"},
};
for (int step = 0; step < sizeof(steps)/sizeof(steps[0]); step++) {
memset(buf, 0x12, sizeof(buf));
rc = gnutls_rnd (steps[step].level, buf, sizeof(buf));
if (rc) {
gnutls_perror (rc);
return rc;
}
printf ("GnuTLS %10s: ", steps[step].name);
for (int i = 0; i < sizeof(buf); i++)
printf ("%02x", buf[i]);
printf ("\n");
}
return 0;
} build with: dkg@alice:~$ gcc -g -Wall -pedantic -Werror -O2 gnutls_rnd.c $(pkg-config --libs --cflags gnutls) -o gnutls_rnd |
i suspect the issue is that this crash is happening during the initialization of libgnutls -- so /* gnutls_rnd.c */
#include <stdio.h>
#include <string.h>
#include <gnutls/crypto.h>
int _real_main();
int main() {
int rc;
gnutls_global_init();
rc = _real_main();
gnutls_global_deinit();
return rc;
}
int _real_main() {
unsigned char buf[10];
int rc;
struct { int level; const char* name; } steps[] = {
{GNUTLS_RND_NONCE, "NONCE"},
{GNUTLS_RND_RANDOM, "RANDOM"},
{GNUTLS_RND_KEY, "KEY"},
};
for (int step = 0; step < sizeof(steps)/sizeof(steps[0]); step++) {
memset(buf, 0x12, sizeof(buf));
rc = gnutls_rnd (steps[step].level, buf, sizeof(buf));
if (rc) {
gnutls_perror (rc);
return rc;
}
printf ("GnuTLS %10s: ", steps[step].name);
for (int i = 0; i < sizeof(buf); i++)
printf ("%02x", buf[i]);
printf ("\n");
}
return 0;
} Then i can trigger the crash (or not) by avoiding the implicit library initialization using a (misnamed) env var: dkg@alice:~$ GNUTLS_NO_EXPLICIT_INIT=1 LD_PRELOAD=libfaketime.so.1 ./gnutls_rnd
GnuTLS NONCE: a7d24c4d5279cfefa9a7
GnuTLS RANDOM: c77778afb396dab4aa7a
GnuTLS KEY: dc916fcee2c2a8109c1a
dkg@alice:~$ LD_PRELOAD=libfaketime.so.1 ./gnutls_rnd
Segmentation fault
dkg@alice:~$ |
Running "make randomtest" should demonstrates the segfault described in wolfcw#295
better testing, without introducing any additional build dependencies can be found in #296, which demonstrates that it is indeed a problem with calls to To be clear, I haven't solved the problem, just crafted a reproducer. |
It occurs to me that this same problem might happen if any shared library invokes time-related functions (not only |
This avoids potential failure if another library calls getrandom() within its constructor before we are loaded. For me, it lets "make randomtest" succeed in tests/ Closes: wolfcw#295
This is an attempt to ensure that an external library invocation of getpid doesn't trigger a crash (e.g. wolfcw#295) or an infinite loop (e.g. wolfcw#297).
I'm using the 0.9.8+git20210209-1 snapshot from debian experimental, which is basically 0.9.9, but with
FAKE_RANDOM
enabled during the build.looks like my testing isn't complete, though, because:
but this succeeds:
I thought maybe the issue was multiple calls to
getrandom
, but i did some additional testing (see #294) and that doesn't appear to trigger the failure ingetrandom.c
either -- the getrandom stuff intests/
still succeeds, even thoughcerttool
is segfaulting.fwiw,
LD_PRELOAD=../src/libfaketime.so.1 curl --help
is segfaulting too. so i don't think this is a problem peculiar tocerttool
.looking at
strace
output between curl without theLD_PRELOAD
and with theLD_PRELOAD
, the segfault does show up right when the program should be invoking thegetrandom()
syscall, but i'm also having trouble getting any sort of debugging info becausegdb
itself also segfaults if i have theLD_PRELOAD
set when launching gdb.The text was updated successfully, but these errors were encountered: