Originální popis anglicky:
mprotect - control allowable accesses to a region of memory
Návod, kniha: Linux Programmer's Manual
#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.
- 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.
#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 (formerly POSIX.4). SVr4 defines an additional error code EAGAIN.
The SVr4 error conditions don't map neatly onto Linux's. 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.
mmap(2)