File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / ElectricFence / page.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:08:38 2012 UTC (12 years, 1 month ago) by misho
Branches: ntp, MAIN
CVS tags: v4_2_6p5p0, v4_2_6p5, HEAD
ntp 4.2.6p5

    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>