Annotation of embedaddon/ntp/ElectricFence/page.c, revision 1.1
1.1 ! misho 1: #ifdef HAVE_CONFIG_H
! 2: # include <config.h>
! 3: #endif
! 4: #include "efence.h"
! 5: #include <stdlib.h>
! 6: #include <unistd.h>
! 7: #include <fcntl.h>
! 8: #include <sys/mman.h>
! 9: #include <stdio.h>
! 10: #include <errno.h>
! 11: #include <string.h>
! 12:
! 13: /*
! 14: * Lots of systems are missing the definition of PROT_NONE.
! 15: */
! 16: #ifndef PROT_NONE
! 17: #define PROT_NONE 0
! 18: #endif
! 19:
! 20: /*
! 21: * 386 BSD has MAP_ANON instead of MAP_ANONYMOUS.
! 22: */
! 23: #if ( !defined(MAP_ANONYMOUS) && defined(MAP_ANON) )
! 24: #define MAP_ANONYMOUS MAP_ANON
! 25: #endif
! 26:
! 27: /*
! 28: * For some reason, I can't find mprotect() in any of the headers on
! 29: * IRIX or SunOS 4.1.2
! 30: */
! 31: /* extern C_LINKAGE int mprotect(void * addr, size_t len, int prot); */
! 32:
! 33: static caddr_t startAddr = (caddr_t) 0;
! 34:
! 35: static const char *
! 36: stringErrorReport(void)
! 37: {
! 38: return strerror(errno);
! 39: }
! 40:
! 41: /*
! 42: * Create memory.
! 43: */
! 44: #if defined(MAP_ANONYMOUS)
! 45: void *
! 46: Page_Create(size_t size)
! 47: {
! 48: caddr_t allocation;
! 49:
! 50: /*
! 51: * In this version, "startAddr" is a _hint_, not a demand.
! 52: * When the memory I map here is contiguous with other
! 53: * mappings, the allocator can coalesce the memory from two
! 54: * or more mappings into one large contiguous chunk, and thus
! 55: * might be able to find a fit that would not otherwise have
! 56: * been possible. I could _force_ it to be contiguous by using
! 57: * the MMAP_FIXED flag, but I don't want to stomp on memory mappings
! 58: * generated by other software, etc.
! 59: */
! 60: allocation = (caddr_t) mmap(
! 61: startAddr
! 62: ,(int)size
! 63: ,PROT_READ|PROT_WRITE
! 64: ,MAP_PRIVATE|MAP_ANONYMOUS
! 65: ,-1
! 66: ,0);
! 67:
! 68: #ifndef __hpux
! 69: /*
! 70: * Set the "address hint" for the next mmap() so that it will abut
! 71: * the mapping we just created.
! 72: *
! 73: * HP/UX 9.01 has a kernel bug that makes mmap() fail sometimes
! 74: * when given a non-zero address hint, so we'll leave the hint set
! 75: * to zero on that system. HP recently told me this is now fixed.
! 76: * Someone please tell me when it is probable to assume that most
! 77: * of those systems that were running 9.01 have been upgraded.
! 78: */
! 79: startAddr = allocation + size;
! 80: #endif
! 81:
! 82: if ( allocation == (caddr_t)-1 )
! 83: EF_Exit("mmap() failed: %s", stringErrorReport());
! 84:
! 85: return (void *)allocation;
! 86: }
! 87: #else
! 88: void *
! 89: Page_Create(size_t size)
! 90: {
! 91: static int devZeroFd = -1;
! 92: caddr_t allocation;
! 93:
! 94: if ( devZeroFd == -1 ) {
! 95: devZeroFd = open("/dev/zero", O_RDWR);
! 96: if ( devZeroFd < 0 )
! 97: EF_Exit(
! 98: "open() on /dev/zero failed: %s"
! 99: ,stringErrorReport());
! 100: }
! 101:
! 102: /*
! 103: * In this version, "startAddr" is a _hint_, not a demand.
! 104: * When the memory I map here is contiguous with other
! 105: * mappings, the allocator can coalesce the memory from two
! 106: * or more mappings into one large contiguous chunk, and thus
! 107: * might be able to find a fit that would not otherwise have
! 108: * been possible. I could _force_ it to be contiguous by using
! 109: * the MMAP_FIXED flag, but I don't want to stomp on memory mappings
! 110: * generated by other software, etc.
! 111: */
! 112: allocation = (caddr_t) mmap(
! 113: startAddr
! 114: ,(int)size
! 115: ,PROT_READ|PROT_WRITE
! 116: ,MAP_PRIVATE
! 117: ,devZeroFd
! 118: ,0);
! 119:
! 120: startAddr = allocation + size;
! 121:
! 122: if ( allocation == (caddr_t)-1 )
! 123: EF_Exit("mmap() failed: %s", stringErrorReport());
! 124:
! 125: return (void *)allocation;
! 126: }
! 127: #endif
! 128:
! 129: static void
! 130: mprotectFailed(void)
! 131: {
! 132: EF_Exit("mprotect() failed: %s", stringErrorReport());
! 133: }
! 134:
! 135: void
! 136: Page_AllowAccess(void * address, size_t size)
! 137: {
! 138: if ( mprotect((caddr_t)address, size, PROT_READ|PROT_WRITE) < 0 )
! 139: mprotectFailed();
! 140: }
! 141:
! 142: void
! 143: Page_DenyAccess(void * address, size_t size)
! 144: {
! 145: if ( mprotect((caddr_t)address, size, PROT_NONE) < 0 )
! 146: mprotectFailed();
! 147: }
! 148:
! 149: void
! 150: Page_Delete(void * address, size_t size)
! 151: {
! 152: if ( munmap((caddr_t)address, size) < 0 )
! 153: Page_DenyAccess(address, size);
! 154: }
! 155:
! 156: #if defined(_SC_PAGESIZE)
! 157: size_t
! 158: Page_Size(void)
! 159: {
! 160: return (size_t)sysconf(_SC_PAGESIZE);
! 161: }
! 162: #elif defined(_SC_PAGE_SIZE)
! 163: size_t
! 164: Page_Size(void)
! 165: {
! 166: return (size_t)sysconf(_SC_PAGE_SIZE);
! 167: }
! 168: #else
! 169: /* extern int getpagesize(); */
! 170: size_t
! 171: Page_Size(void)
! 172: {
! 173: return getpagesize();
! 174: }
! 175: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>