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 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