MPROTECT(2)

名前
mprotect - アクセス可能なメモリ区画を制御する

書式
#include <sys/mman.h>

int mprotect(const void *addr, size_t len, int prot);

説明
mprotect はメモリ区画がどのようにアクセスできるかを制御する。保護が与えられて いてアクセスできない場合、プログラムは SIGSEGV を受けとる。

prot は以下の値のビット OR である:

PROT_NONE
    そのメモリは全てのアクセスができない。

PROT_READ
    そのメモリは読み取ることができる。

PROT_WRITE
    そのメモリは書き込むことができる。

PROT_EXEC
    そのメモリは実行コードを含むことができる。

新しい保護は今までの保護を置き換える。例えば、メモリが以前には PROT_READ とマークされていて、mprotect が prot PROT_WRITE で呼び出された場合は、もうそれは読み込み可能 ではない。

返り値
成功した場合は、 mprotect はゼロを返す。エラーの場合は -1 が返され、 errno が適切に設定される。

エラー

EINVAL
    addr が有効なポインターでないか、PAGESIZE の倍数でない。

EFAULT
    メモリがアクセス可能でない。

EACCES
    指定されたアクセスをメモリに与えることができない。これは、例えば ファイルを読み込み専用で mmap(2) しており、それに mprotect で PROT_WRITE にマークしようとした場合に起きる。

ENOMEM
    カーネル内部の構造体を割り当てることができなかった。

例
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/mman.h>
#include <limits.h>    /* 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.1b (以前の POSIX.4). SVr4 は他に EAGAIN エラーを定義している。 SVr4 のエラー状態を Linux のものに対応しない。 POSIX.1b では mprotect は mmap(2) で得たメモリ領域のみが使用できるとされている。

関連項目
mmap(2)