1 /* $OpenBSD: mmap_hint.c,v 1.2 2013/03/21 21:59:55 deraadt Exp $ */ 2 /* 3 * Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl> 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/param.h> 19 #include <sys/types.h> 20 #include <sys/mman.h> 21 #include <machine/vmparam.h> 22 #include <err.h> 23 #include <sysexits.h> 24 #include <stdio.h> 25 26 #define MAX_HINT_DIST (2UL * 1024 * 1024 * 1024) 27 28 int errors = 0; 29 30 void * 31 mmap_hint(void *hint) 32 { 33 void *p; 34 size_t pd; 35 36 p = mmap(hint, 1, PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, 0); 37 if (p == MAP_FAILED) { 38 warn("mmap(addr=%p, len=1) failed", hint); 39 errors++; 40 return MAP_FAILED; 41 } else if (p == NULL) { 42 warnx("mmap(addr=%p, len=1) mapped at address 0", hint); 43 errors++; 44 return MAP_FAILED; 45 } else 46 fprintf(stderr, " -> %p\n", p); 47 48 if (hint > p) 49 pd = hint - p; 50 else 51 pd = p - hint; 52 53 if (hint != NULL && pd > MAX_HINT_DIST) { 54 warnx("hinted allocation more than 0x%lx " 55 "bytes away from hint: " 56 "hint %p, result %p", pd, hint, p); 57 errors++; 58 return MAP_FAILED; 59 } 60 return p; 61 } 62 63 int 64 main() 65 { 66 void *p, *p_prev; 67 68 /* Check that unhinted allocation works properly. */ 69 fprintf(stderr, "1: Checking hint NULL mmap\n"); 70 p = mmap_hint(NULL); 71 72 /* Check hinted allocation at top of map. */ 73 fprintf(stderr, "2: Checking hint VM_MAXUSER_ADDRESS 0x%lx mmap\n", 74 (unsigned long)VM_MAXUSER_ADDRESS); 75 p = mmap_hint((void*)VM_MAXUSER_ADDRESS); 76 77 /* Check hinted allocation at bottom of map. */ 78 fprintf(stderr, "3: Checking hint VM_MIN_ADDRESS 0x%lx mmap\n", 79 (unsigned long)VM_MIN_ADDRESS); 80 p = mmap_hint((void*)VM_MIN_ADDRESS); 81 82 /* 83 * Check that hinted allocation doesn't overwrite existing allocation. 84 */ 85 if (p == MAP_FAILED) { 86 fprintf(stderr, "4: Skipping test: required previous test " 87 "to succeed"); 88 goto skip4; 89 } 90 p_prev = p; 91 fprintf(stderr, "4: Checking hint 0x%lx mmap, which is in use\n", 92 p_prev); 93 p = mmap_hint(p_prev); 94 if (p == p_prev) { 95 warnx("hinted allocation %p " 96 "overwrites previous allocation", p_prev); 97 errors++; 98 } 99 skip4: 100 101 return errors; 102 } 103