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