xref: /dflybsd-src/test/testcases/mem/mmap_madvise_1/mmap_madvise_1.c (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
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