aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrent Cook <bcook@openbsd.org>2014-07-15 16:43:00 -0500
committerBrent Cook <bcook@openbsd.org>2014-07-15 16:43:00 -0500
commit477f1f018792ddb15a34926910d2f70bb2590cbd (patch)
tree8776b44b2f9bfa8b655be0ed1b550993d1a750e4
parentc41fb098b98c1c792a9b86a22f1ba7a51adcc144 (diff)
downloadportable-477f1f018792ddb15a34926910d2f70bb2590cbd.tar.gz
portable-477f1f018792ddb15a34926910d2f70bb2590cbd.tar.bz2
portable-477f1f018792ddb15a34926910d2f70bb2590cbd.zip
added fork_rand test to check for PID wraparound
ok beck@
-rw-r--r--tests/fork_rand.c81
-rwxr-xr-xtests/fork_rand.sh10
-rwxr-xr-xupdate.sh4
3 files changed, 93 insertions, 2 deletions
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 @@
1/*
2 * Checks if LibreSSL's PRNG is fork-safe on Linux.
3 * From https://www.agwa.name/blog/post/libressls_prng_is_unsafe_on_linux
4 */
5
6#include <openssl/rand.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <unistd.h>
10#include <sys/wait.h>
11
12static void random_bytes (unsigned char* p, size_t len)
13{
14 if (RAND_bytes(p, len) != 1) {
15 fprintf(stderr, "RAND_bytes failed\n");
16 abort();
17 }
18}
19
20static void random_stir (void)
21{
22 if (RAND_poll() != 1) {
23 fprintf(stderr, "RAND_poll failed\n");
24 abort();
25 }
26}
27
28static void print_buffer (unsigned char* p, size_t len)
29{
30 while (len--) {
31 printf("%02x", (unsigned int)*p++);
32 }
33}
34
35int main ()
36{
37 char c = 0;
38 int pipefd[2];
39 pipe(pipefd);
40 setbuf(stdout, NULL);
41
42 if (fork() == 0) {
43 unsigned char buffer[32];
44 pid_t grandparent_pid = getpid();
45
46 random_bytes(buffer, sizeof(buffer));
47
48 if (fork() == 0) {
49 random_stir();
50 setsid();
51 while (1) {
52 pid_t grandchild_pid = fork();
53 if (grandchild_pid == 0) {
54 random_stir();
55 if (getpid() == grandparent_pid) {
56 random_bytes(buffer, sizeof(buffer));
57 print_buffer(buffer, sizeof(buffer));
58 printf("\n");
59 }
60 _exit(0);
61 }
62 wait(NULL);
63 if (grandchild_pid == grandparent_pid) {
64 break;
65 }
66 }
67 write(pipefd[1], &c, 1);
68 _exit(0);
69 }
70
71 random_bytes(buffer, sizeof(buffer));
72 print_buffer(buffer, sizeof(buffer));
73 printf(" ");
74 _exit(0);
75 }
76 wait(NULL);
77 close(pipefd[1]);
78 read(pipefd[0], &c, 1);
79 return 0;
80}
81
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 @@
1#!/usr/bin/env bash
2./fork_rand > fork_rand.txt
3while read -r a b;
4do
5 if [ "$a" = "$b" ]; then
6 echo "FAIL: $a = $b"
7 else
8 echo "PASS: $a != $b"
9 fi
10done < 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
273 s_server.c s_socket.c s_time.c sess_id.c smime.c speed.c spkac.c 273 s_server.c s_socket.c s_time.c sess_id.c smime.c speed.c spkac.c
274 testdsa.h testrsa.h timeouts.h ts.c verify.c version.c x509.c" 274 testdsa.h testrsa.h timeouts.h ts.c verify.c version.c x509.c"
275 275
276rm -f tests/*.c 276rm -f tests/*test.c
277for i in aead/aeadtest.c aeswrap/aes_wrap.c base64/base64test.c bf/bftest.c \ 277for i in aead/aeadtest.c aeswrap/aes_wrap.c base64/base64test.c bf/bftest.c \
278 bio/biotest.c bn/general/bntest.c bn/mont/mont.c \ 278 bio/biotest.c bn/general/bntest.c bn/mont/mont.c \
279 cast/casttest.c chacha/chachatest.c cts128/cts128test.c \ 279 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
295done 295done
296 296
297# do not directly run all test programs 297# do not directly run all test programs
298test_excludes=(biotest aeadtest evptest pq_test ssltest arc4randomforktest) 298test_excludes=(biotest aeadtest evptest pq_test ssltest arc4randomforktest fork_rand)
299(cd tests 299(cd tests
300 cp Makefile.am.tpl Makefile.am 300 cp Makefile.am.tpl Makefile.am
301 301