From 477f1f018792ddb15a34926910d2f70bb2590cbd Mon Sep 17 00:00:00 2001 From: Brent Cook Date: Tue, 15 Jul 2014 16:43:00 -0500 Subject: added fork_rand test to check for PID wraparound ok beck@ --- tests/fork_rand.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/fork_rand.sh | 10 +++++++ 2 files changed, 91 insertions(+) create mode 100644 tests/fork_rand.c create mode 100755 tests/fork_rand.sh (limited to 'tests') 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 -- cgit v1.2.3-55-g6feb