1*86d7f5d3SJohn Marino /*
2*86d7f5d3SJohn Marino * t_mmap_madvise_1.c
3*86d7f5d3SJohn Marino *
4*86d7f5d3SJohn Marino * Check that an mprotect(PROT_NONE) region cannot be read even after an
5*86d7f5d3SJohn Marino * madvise(MADV_WILLNEED) has been executed on the region.
6*86d7f5d3SJohn Marino *
7*86d7f5d3SJohn Marino * Returns 0 if mprotect() protected the segment, 1 if the segment was readable
8*86d7f5d3SJohn Marino * despite PROT_NONE.
9*86d7f5d3SJohn Marino *
10*86d7f5d3SJohn Marino * $Id: t_mmap_madvise_1.c,v 1.1 2011/10/30 15:10:34 me Exp me $
11*86d7f5d3SJohn Marino */
12*86d7f5d3SJohn Marino
13*86d7f5d3SJohn Marino #include <sys/types.h>
14*86d7f5d3SJohn Marino #include <sys/wait.h>
15*86d7f5d3SJohn Marino #include <sys/mman.h>
16*86d7f5d3SJohn Marino
17*86d7f5d3SJohn Marino #include <stdio.h>
18*86d7f5d3SJohn Marino #include <stdlib.h>
19*86d7f5d3SJohn Marino #include <string.h>
20*86d7f5d3SJohn Marino #include <errno.h>
21*86d7f5d3SJohn Marino #include <fcntl.h>
22*86d7f5d3SJohn Marino #include <unistd.h>
23*86d7f5d3SJohn Marino #include <err.h>
24*86d7f5d3SJohn Marino
25*86d7f5d3SJohn Marino int
main(int argc,char * argv[])26*86d7f5d3SJohn Marino main(int argc, char *argv[])
27*86d7f5d3SJohn Marino {
28*86d7f5d3SJohn Marino int fd;
29*86d7f5d3SJohn Marino char *mem;
30*86d7f5d3SJohn Marino char *tmpfile;
31*86d7f5d3SJohn Marino char teststring[] = "hello, world!\0";
32*86d7f5d3SJohn Marino int rc;
33*86d7f5d3SJohn Marino char c0;
34*86d7f5d3SJohn Marino int status;
35*86d7f5d3SJohn Marino
36*86d7f5d3SJohn Marino /* Setup: create a test file, write a test pattern, map it */
37*86d7f5d3SJohn Marino tmpfile = tmpnam(NULL);
38*86d7f5d3SJohn Marino
39*86d7f5d3SJohn Marino fd = open(tmpfile, O_RDWR | O_CREAT | O_TRUNC, 0777);
40*86d7f5d3SJohn Marino if (fd == -1)
41*86d7f5d3SJohn Marino err(1, "open/creat failure");
42*86d7f5d3SJohn Marino
43*86d7f5d3SJohn Marino unlink(tmpfile);
44*86d7f5d3SJohn Marino write(fd, teststring, strlen(teststring));
45*86d7f5d3SJohn Marino fsync(fd);
46*86d7f5d3SJohn Marino
47*86d7f5d3SJohn Marino mem = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
48*86d7f5d3SJohn Marino if (mem == MAP_FAILED)
49*86d7f5d3SJohn Marino err(1, "mmap failure");
50*86d7f5d3SJohn Marino
51*86d7f5d3SJohn Marino /* At this point the segment should be readable and reflect the file */
52*86d7f5d3SJohn Marino rc = strcmp(mem, teststring);
53*86d7f5d3SJohn Marino if (rc != 0)
54*86d7f5d3SJohn Marino err(1, "unexpected map region");
55*86d7f5d3SJohn Marino
56*86d7f5d3SJohn Marino rc = mprotect(mem, 4096, PROT_NONE);
57*86d7f5d3SJohn Marino if (rc == -1)
58*86d7f5d3SJohn Marino err(1, "mprotect error");
59*86d7f5d3SJohn Marino
60*86d7f5d3SJohn Marino /* At this point the segment should no longer be readable */
61*86d7f5d3SJohn Marino
62*86d7f5d3SJohn Marino /* POSIX hat: this call might want to fail w/ EINVAL; we are offering
63*86d7f5d3SJohn Marino * advice for a region that is invalid, posix_madvise() is marked as
64*86d7f5d3SJohn Marino * failing w/ EINVAL if "The value of advice is invalid." ; we need
65*86d7f5d3SJohn Marino * a more precise definition of invalid. */
66*86d7f5d3SJohn Marino rc = madvise(mem, 4096, MADV_WILLNEED);
67*86d7f5d3SJohn Marino if (rc == -1)
68*86d7f5d3SJohn Marino err(1, "madvise failed");
69*86d7f5d3SJohn Marino
70*86d7f5d3SJohn Marino /* Segment should still not be readable */
71*86d7f5d3SJohn Marino
72*86d7f5d3SJohn Marino rc = fork();
73*86d7f5d3SJohn Marino if (rc == 0) {
74*86d7f5d3SJohn Marino c0 = mem[0];
75*86d7f5d3SJohn Marino if (c0 == 'h')
76*86d7f5d3SJohn Marino exit(0);
77*86d7f5d3SJohn Marino exit(1);
78*86d7f5d3SJohn Marino }
79*86d7f5d3SJohn Marino wait(&status);
80*86d7f5d3SJohn Marino rc = 0;
81*86d7f5d3SJohn Marino
82*86d7f5d3SJohn Marino /* The child was able to read the segment. Uhoh. */
83*86d7f5d3SJohn Marino if (WIFEXITED(status)) {
84*86d7f5d3SJohn Marino rc = -1;
85*86d7f5d3SJohn Marino }
86*86d7f5d3SJohn Marino /* Child died via a signal (SEGV) */
87*86d7f5d3SJohn Marino if (WIFSIGNALED(status)) {
88*86d7f5d3SJohn Marino rc = 0;
89*86d7f5d3SJohn Marino }
90*86d7f5d3SJohn Marino
91*86d7f5d3SJohn Marino munmap(mem, 4096);
92*86d7f5d3SJohn Marino close(fd);
93*86d7f5d3SJohn Marino
94*86d7f5d3SJohn Marino printf("%d \n", rc);
95*86d7f5d3SJohn Marino return (rc);
96*86d7f5d3SJohn Marino }
97*86d7f5d3SJohn Marino
98