added fork_rand test to check for PID wraparound

ok beck@
This commit is contained in:
Brent Cook 2014-07-15 16:43:00 -05:00
parent c41fb098b9
commit 477f1f0187
3 changed files with 93 additions and 2 deletions

81
tests/fork_rand.c Normal file
View File

@ -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 <openssl/rand.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
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;
}

10
tests/fork_rand.sh Executable file
View File

@ -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

View File

@ -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