1*86d7f5d3SJohn Marino /*
2*86d7f5d3SJohn Marino * Test a fork/munmap vm_object shadow chain race
3*86d7f5d3SJohn Marino *
4*86d7f5d3SJohn Marino * Written by "Samuel J. Greear" <sjg@evilcode.net>
5*86d7f5d3SJohn Marino */
6*86d7f5d3SJohn Marino #include <stdio.h>
7*86d7f5d3SJohn Marino #include <string.h>
8*86d7f5d3SJohn Marino #include <err.h>
9*86d7f5d3SJohn Marino #include <sysexits.h>
10*86d7f5d3SJohn Marino #include <unistd.h>
11*86d7f5d3SJohn Marino
12*86d7f5d3SJohn Marino #include <sys/types.h>
13*86d7f5d3SJohn Marino #include <sys/mman.h>
14*86d7f5d3SJohn Marino #include <sys/param.h>
15*86d7f5d3SJohn Marino #include <sys/wait.h>
16*86d7f5d3SJohn Marino
17*86d7f5d3SJohn Marino #define MAPPING_PAGES 4096
18*86d7f5d3SJohn Marino
19*86d7f5d3SJohn Marino int
main(int argc,char * argv[])20*86d7f5d3SJohn Marino main(int argc, char *argv[])
21*86d7f5d3SJohn Marino {
22*86d7f5d3SJohn Marino unsigned int i, size;
23*86d7f5d3SJohn Marino int status;
24*86d7f5d3SJohn Marino pid_t pid;
25*86d7f5d3SJohn Marino void *mapping;
26*86d7f5d3SJohn Marino char tmp[100];
27*86d7f5d3SJohn Marino
28*86d7f5d3SJohn Marino for (i = 1; i < MAPPING_PAGES; ++i) {
29*86d7f5d3SJohn Marino size = PAGE_SIZE * i;
30*86d7f5d3SJohn Marino mapping = mmap(0, size, PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED,
31*86d7f5d3SJohn Marino -1, 0);
32*86d7f5d3SJohn Marino if (mapping == MAP_FAILED)
33*86d7f5d3SJohn Marino errx(EX_OSERR, "mmap() failed");
34*86d7f5d3SJohn Marino
35*86d7f5d3SJohn Marino memset(mapping, 'x', 10);
36*86d7f5d3SJohn Marino printf(" %d", i);
37*86d7f5d3SJohn Marino fflush(stdout);
38*86d7f5d3SJohn Marino
39*86d7f5d3SJohn Marino pid = fork();
40*86d7f5d3SJohn Marino if (pid == 0) {
41*86d7f5d3SJohn Marino memcpy(&tmp, mapping, 12);
42*86d7f5d3SJohn Marino return (0);
43*86d7f5d3SJohn Marino } else if (pid != -1) {
44*86d7f5d3SJohn Marino if (munmap(mapping, PAGE_SIZE * i) != 0) {
45*86d7f5d3SJohn Marino printf("munmap failed\n");
46*86d7f5d3SJohn Marino return (0);
47*86d7f5d3SJohn Marino }
48*86d7f5d3SJohn Marino waitpid(pid, &status, 0);
49*86d7f5d3SJohn Marino if (status == 10) {
50*86d7f5d3SJohn Marino printf("child sig10 at %d pages\n", i);
51*86d7f5d3SJohn Marino return (0);
52*86d7f5d3SJohn Marino }
53*86d7f5d3SJohn Marino } else {
54*86d7f5d3SJohn Marino printf("fork failed\n");
55*86d7f5d3SJohn Marino }
56*86d7f5d3SJohn Marino }
57*86d7f5d3SJohn Marino
58*86d7f5d3SJohn Marino return (0);
59*86d7f5d3SJohn Marino }
60