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>