From 477f1f018792ddb15a34926910d2f70bb2590cbd Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Tue, 15 Jul 2014 16:43:00 -0500 Subject: [PATCH] added fork_rand test to check for PID wraparound ok beck@ --- tests/fork_rand.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++ tests/fork_rand.sh | 10 ++++++ update.sh | 4 +-- 3 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 tests/fork_rand.c create mode 100755 tests/fork_rand.sh diff --git a/tests/fork_rand.c b/tests/fork_rand.c new file mode 100644 index 0000000..75f2cc2 --- /dev/null +++ b/tests/fork_rand.c @@ -0,0 +1,81 @@ +/* + * Checks if LibreSSL's PRNG is fork-safe on Linux. + * From https://www.agwa.name/blog/post/libressls_prng_is_unsafe_on_linux + */ + +#include +#include +#include +#include +#include + +static void random_bytes (unsigned char* p, size_t len) +{ + if (RAND_bytes(p, len) != 1) { + fprintf(stderr, "RAND_bytes failed\n"); + abort(); + } +} + +static void random_stir (void) +{ + if (RAND_poll() != 1) { + fprintf(stderr, "RAND_poll failed\n"); + abort(); + } +} + +static void print_buffer (unsigned char* p, size_t len) +{ + while (len--) { + printf("%02x", (unsigned int)*p++); + } +} + +int main () +{ + char c = 0; + int pipefd[2]; + pipe(pipefd); + setbuf(stdout, NULL); + + if (fork() == 0) { + unsigned char buffer[32]; + pid_t grandparent_pid = getpid(); + + random_bytes(buffer, sizeof(buffer)); + + if (fork() == 0) { + random_stir(); + setsid(); + while (1) { + pid_t grandchild_pid = fork(); + if (grandchild_pid == 0) { + random_stir(); + if (getpid() == grandparent_pid) { + random_bytes(buffer, sizeof(buffer)); + print_buffer(buffer, sizeof(buffer)); + printf("\n"); + } + _exit(0); + } + wait(NULL); + if (grandchild_pid == grandparent_pid) { + break; + } + } + write(pipefd[1], &c, 1); + _exit(0); + } + + random_bytes(buffer, sizeof(buffer)); + print_buffer(buffer, sizeof(buffer)); + printf(" "); + _exit(0); + } + wait(NULL); + close(pipefd[1]); + read(pipefd[0], &c, 1); + return 0; +} + diff --git a/tests/fork_rand.sh b/tests/fork_rand.sh new file mode 100755 index 0000000..333516e --- /dev/null +++ b/tests/fork_rand.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +./fork_rand > fork_rand.txt +while read -r a b; +do + if [ "$a" = "$b" ]; then + echo "FAIL: $a = $b" + else + echo "PASS: $a != $b" + fi +done < fork_rand.txt diff --git a/update.sh b/update.sh index 9512f8c..1b30f7d 100755 --- a/update.sh +++ b/update.sh @@ -273,7 +273,7 @@ copy_src apps "apps.c apps.h asn1pars.c ca.c ciphers.c cms.c crl.c crl2p7.c s_server.c s_socket.c s_time.c sess_id.c smime.c speed.c spkac.c testdsa.h testrsa.h timeouts.h ts.c verify.c version.c x509.c" -rm -f tests/*.c +rm -f tests/*test.c for i in aead/aeadtest.c aeswrap/aes_wrap.c base64/base64test.c bf/bftest.c \ bio/biotest.c bn/general/bntest.c bn/mont/mont.c \ cast/casttest.c chacha/chachatest.c cts128/cts128test.c \ @@ -295,7 +295,7 @@ for i in asn1/asn1test.c ssl/ssltest.c ssl/testssl certs/ca.pem certs/server.pem done # do not directly run all test programs -test_excludes=(biotest aeadtest evptest pq_test ssltest arc4randomforktest) +test_excludes=(biotest aeadtest evptest pq_test ssltest arc4randomforktest fork_rand) (cd tests cp Makefile.am.tpl Makefile.am