xref: /openbsd-src/regress/sys/uvm/mmap_noreplace/mmap_noreplace.c (revision 7f7d72468670c65830d0161e3ac169d5419d1887)
1 /*	$OpenBSD: mmap_noreplace.c,v 1.1 2014/06/19 19:34:22 matthew Exp $	*/
2 /*
3  * Copyright (c) 2014 Google Inc.
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/mman.h>
19 #include <assert.h>
20 #include <string.h>
21 #include <unistd.h>
22 
23 #define CHECK(a) assert(a)
24 #define CHECK_EQ(a, b) assert((a) == (b))
25 #define CHECK_NE(a, b) assert((a) != (b))
26 #define CHECK_GE(a, b) assert((a) >= (b))
27 
28 int
ismemset(void * b,int c,size_t n)29 ismemset(void *b, int c, size_t n)
30 {
31 	unsigned char *p = b;
32 	size_t i;
33 	for (i = 0; i < n; i++)
34 		if (p[i] != c)
35 			return (0);
36 	return (1);
37 }
38 
39 int
main()40 main()
41 {
42 	char *p;
43 	long pagesize;
44 
45 	pagesize = sysconf(_SC_PAGESIZE);
46 	CHECK_GE(pagesize, 1);
47 
48 	/* Allocate three pages of anonymous memory. */
49 	p = mmap(NULL, 3 * pagesize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
50 	CHECK_NE(MAP_FAILED, p);
51 
52 	/* Initialize memory to all 1 bytes. */
53 	memset(p, 1, 3 * pagesize);
54 	CHECK(ismemset(p, 1, 3 * pagesize));
55 
56 	/* Map new anonymous memory over the second page. */
57 	CHECK_EQ(p + pagesize, mmap(p + pagesize, pagesize,
58 	    PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON|MAP_FIXED, -1, 0));
59 
60 	/* Verify the second page is zero'd out, and the others are unscathed. */
61 	CHECK(ismemset(p, 1, pagesize));
62 	CHECK(ismemset(p + pagesize, 0, pagesize));
63 	CHECK(ismemset(p + 2 * pagesize, 1, pagesize));
64 
65 	/* Re-initialized memory. */
66 	memset(p, 1, 3 * pagesize);
67 	CHECK(ismemset(p, 1, 3 * pagesize));
68 
69 	/* Try to map over second page with __MAP_NOREPLACE; should fail. */
70 	CHECK_EQ(MAP_FAILED, mmap(p, pagesize, PROT_READ|PROT_WRITE,
71 	    MAP_PRIVATE|MAP_ANON|MAP_FIXED|__MAP_NOREPLACE, -1, 0));
72 
73 	/* Verify the pages are still set. */
74 	CHECK(ismemset(p, 1, 3 * pagesize));
75 
76 	return (0);
77 }
78