1*9d12795fSRobert Mustacchi /*
2*9d12795fSRobert Mustacchi * This file and its contents are supplied under the terms of the
3*9d12795fSRobert Mustacchi * Common Development and Distribution License ("CDDL"), version 1.0.
4*9d12795fSRobert Mustacchi * You may only use this file in accordance with the terms of version
5*9d12795fSRobert Mustacchi * 1.0 of the CDDL.
6*9d12795fSRobert Mustacchi *
7*9d12795fSRobert Mustacchi * A full copy of the text of the CDDL should have accompanied this
8*9d12795fSRobert Mustacchi * source. A copy of the CDDL is also available via the Internet at
9*9d12795fSRobert Mustacchi * http://www.illumos.org/license/CDDL.
10*9d12795fSRobert Mustacchi */
11*9d12795fSRobert Mustacchi
12*9d12795fSRobert Mustacchi /*
13*9d12795fSRobert Mustacchi * Copyright (c) 2015, Joyent, Inc.
14*9d12795fSRobert Mustacchi */
15*9d12795fSRobert Mustacchi
16*9d12795fSRobert Mustacchi /*
17*9d12795fSRobert Mustacchi * Tests to make sure that a parent and child do not get the same arc4random
18*9d12795fSRobert Mustacchi * state across a fork from a signal handler. This source file is used to make
19*9d12795fSRobert Mustacchi * two tests. One which initializes the data in advance, one of which does not.
20*9d12795fSRobert Mustacchi */
21*9d12795fSRobert Mustacchi
22*9d12795fSRobert Mustacchi #include <stdlib.h>
23*9d12795fSRobert Mustacchi #include <sys/mman.h>
24*9d12795fSRobert Mustacchi #include <assert.h>
25*9d12795fSRobert Mustacchi #include <errno.h>
26*9d12795fSRobert Mustacchi #include <sys/types.h>
27*9d12795fSRobert Mustacchi #include <unistd.h>
28*9d12795fSRobert Mustacchi #include <sys/wait.h>
29*9d12795fSRobert Mustacchi #include <signal.h>
30*9d12795fSRobert Mustacchi #include <strings.h>
31*9d12795fSRobert Mustacchi
32*9d12795fSRobert Mustacchi typedef struct arc4_fork {
33*9d12795fSRobert Mustacchi uint32_t af_parent;
34*9d12795fSRobert Mustacchi uint32_t af_child;
35*9d12795fSRobert Mustacchi uint8_t af_pbuf[4096];
36*9d12795fSRobert Mustacchi uint8_t af_cbuf[4096];
37*9d12795fSRobert Mustacchi } arc4_fork_t;
38*9d12795fSRobert Mustacchi
39*9d12795fSRobert Mustacchi arc4_fork_t *fork_data;
40*9d12795fSRobert Mustacchi static pid_t pid;
41*9d12795fSRobert Mustacchi
42*9d12795fSRobert Mustacchi /*ARGSUSED*/
43*9d12795fSRobert Mustacchi static void
siguser_fork(int sig,siginfo_t * sip,void * ucp)44*9d12795fSRobert Mustacchi siguser_fork(int sig, siginfo_t *sip, void *ucp)
45*9d12795fSRobert Mustacchi {
46*9d12795fSRobert Mustacchi pid = fork();
47*9d12795fSRobert Mustacchi }
48*9d12795fSRobert Mustacchi
49*9d12795fSRobert Mustacchi int
main(void)50*9d12795fSRobert Mustacchi main(void)
51*9d12795fSRobert Mustacchi {
52*9d12795fSRobert Mustacchi int e, i, ret;
53*9d12795fSRobert Mustacchi pid_t child;
54*9d12795fSRobert Mustacchi struct sigaction sact;
55*9d12795fSRobert Mustacchi
56*9d12795fSRobert Mustacchi bzero(&sact, sizeof (struct sigaction));
57*9d12795fSRobert Mustacchi sact.sa_flags = SA_SIGINFO;
58*9d12795fSRobert Mustacchi sact.sa_sigaction = siguser_fork;
59*9d12795fSRobert Mustacchi
60*9d12795fSRobert Mustacchi (void) sigemptyset(&sact.sa_mask);
61*9d12795fSRobert Mustacchi ret = sigaction(SIGUSR1, &sact, NULL);
62*9d12795fSRobert Mustacchi assert(ret == 0);
63*9d12795fSRobert Mustacchi
64*9d12795fSRobert Mustacchi #ifdef ARC4_PREINIT
65*9d12795fSRobert Mustacchi (void) arc4random();
66*9d12795fSRobert Mustacchi #endif
67*9d12795fSRobert Mustacchi
68*9d12795fSRobert Mustacchi fork_data = (arc4_fork_t *)mmap(NULL, sizeof (arc4_fork_t),
69*9d12795fSRobert Mustacchi PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
70*9d12795fSRobert Mustacchi assert(fork_data != MAP_FAILED);
71*9d12795fSRobert Mustacchi
72*9d12795fSRobert Mustacchi ret = raise(SIGUSR1);
73*9d12795fSRobert Mustacchi assert(ret == 0);
74*9d12795fSRobert Mustacchi assert(pid != -1);
75*9d12795fSRobert Mustacchi if (pid == 0) {
76*9d12795fSRobert Mustacchi fork_data->af_child = arc4random();
77*9d12795fSRobert Mustacchi arc4random_buf(fork_data->af_cbuf, sizeof (fork_data->af_cbuf));
78*9d12795fSRobert Mustacchi exit(0);
79*9d12795fSRobert Mustacchi }
80*9d12795fSRobert Mustacchi
81*9d12795fSRobert Mustacchi fork_data->af_parent = arc4random();
82*9d12795fSRobert Mustacchi arc4random_buf(fork_data->af_pbuf, sizeof (fork_data->af_pbuf));
83*9d12795fSRobert Mustacchi do {
84*9d12795fSRobert Mustacchi child = wait(&e);
85*9d12795fSRobert Mustacchi } while (child == -1 && errno == EINTR);
86*9d12795fSRobert Mustacchi assert(child == pid);
87*9d12795fSRobert Mustacchi
88*9d12795fSRobert Mustacchi /* Now verify our data doesn't match */
89*9d12795fSRobert Mustacchi assert(fork_data->af_parent != fork_data->af_child);
90*9d12795fSRobert Mustacchi
91*9d12795fSRobert Mustacchi /*
92*9d12795fSRobert Mustacchi * For the buffer here, we're mostly concerned that they aren't somehow
93*9d12795fSRobert Mustacchi * getting the same stream.
94*9d12795fSRobert Mustacchi */
95*9d12795fSRobert Mustacchi for (i = 0; i < sizeof (fork_data->af_pbuf); i++) {
96*9d12795fSRobert Mustacchi if (fork_data->af_pbuf[i] != fork_data->af_cbuf[i])
97*9d12795fSRobert Mustacchi break;
98*9d12795fSRobert Mustacchi }
99*9d12795fSRobert Mustacchi assert(i != sizeof (fork_data->af_pbuf));
100*9d12795fSRobert Mustacchi
101*9d12795fSRobert Mustacchi return (0);
102*9d12795fSRobert Mustacchi }
103