aboutsummaryrefslogtreecommitdiff
path: root/tests/pidwraptest.c
diff options
context:
space:
mode:
authorBrent Cook <bcook@openbsd.org>2014-07-21 18:25:54 -0500
committerBrent Cook <bcook@openbsd.org>2014-07-21 19:54:21 -0500
commit23dc97f8c2543cf67881dd6d4a351e95318637db (patch)
treeb4bd77c9d4762331da593cae2743942d06238c42 /tests/pidwraptest.c
parentf425f564d5062fdc3f7a0d15c7cc5c36a1723abd (diff)
downloadportable-23dc97f8c2543cf67881dd6d4a351e95318637db.tar.gz
portable-23dc97f8c2543cf67881dd6d4a351e95318637db.tar.bz2
portable-23dc97f8c2543cf67881dd6d4a351e95318637db.zip
rename local tests to end in test.c
ok beck@ guenther@
Diffstat (limited to 'tests/pidwraptest.c')
-rw-r--r--tests/pidwraptest.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/tests/pidwraptest.c b/tests/pidwraptest.c
new file mode 100644
index 0000000..75f2cc2
--- /dev/null
+++ b/tests/pidwraptest.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