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