mprotect — control allowable accesses to a region of memory
#include <sys/mman.h>
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.
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
.
The memory cannot be accessed.
addr
is not
a valid pointer, or not a multiple of PAGESIZE.
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 <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.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.
|