Annotation of embedaddon/ntp/ElectricFence/page.c, revision 1.1.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>