mprotect()関数Unix/Linux


mprotect - 
アクセス可能なメモリ領域の制御
コンテンツの概要
#include  
int mprotect(const void *addr, size_t len, int prot);

説明


The function 
mprotect
() specifies the desired protection for the memory page(s) containing part or all of the interval [
addr
,
addr
+
len
-1]. If an access is disallowed by the protection given it, the program receives a 
SIGSEGV
.
prot is a bitwise-or of the following values:
タブ
説明
PROT_NONE
The memory cannot be accessed at all.
PROT_READ
The memory can be read.
PROT_WRITE
The memory can be written to.
PROT_EXEC
The memory can contain executing code.
The new protection replaces any existing protection. For example, if the memory had previously been marked 
PROT_READ
, and 
mprotect
() is then called with 
prot
PROT_WRITE
, it will no longer be readable.

戻り値


On success, 
mprotect
() returns zero. On error, -1 is returned, and 
errno
 is set appropriately.

エラー


タブ
説明
EACCES
The memory cannot be given the specified access. This can happen, for example, if you mmap(2) a file to which you have read-only access, then ask mprotect() to mark it PROT_WRITE.
EFAULT
The memory cannot be accessed.
EINVAL
addr is not a valid pointer, or not a multiple of PAGESIZE.
ENOMEM
Internal kernel structures could not be allocated. Or: addresses in the range [addr, addr+len] are invalid for the address space of the process, or specify one or more pages that are not mapped.
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include     /* for PAGESIZE */
#ifndef PAGESIZE
#define PAGESIZE 4096
#endif

int
main(void)
{
    char *p;
    char c;

    /* Allocate a buffer; it will have the default
       protection of PROT_READ|PROT_WRITE. */
    p = malloc(1024+PAGESIZE-1);
    if (!p) {
        perror("Couldn’t malloc(1024)");
        exit(errno);
    }

    /* Align to a multiple of PAGESIZE, assumed to be a power of two */
    p = (char *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1));

    c = p[666];         /* Read; ok */
    p[666] = 42;        /* Write; ok */

    /* Mark the buffer read-only. */
    if (mprotect(p, 1024, PROT_READ)) {
        perror("Couldn’t mprotect");
        exit(errno);
    }
    c = p[666];         /* Read; ok */
    p[666] = 42;        /* Write; program dies on SIGSEGV */

    exit(0);
}

に従う


SVr4, POSIX.1-2001. POSIX says that 
mprotect
() can be used only on regions of memory obtained from 
mmap
(2).

に注意


On Linux it is always legal to call 
mprotect
() on any address in a process’ address space (except for the kernel vsyscall area). In particular it can be used to change existing code mappings to be writable.
Whether PROT_EXEC has any effect different from PROT_READ is architecture and kernel version dependent.