Unix for Beginners
Unix Shell Programming
Advanced Unix
Unix Useful References
Unix Useful Resources
Selected Reading
Copyright © 2014 by tutorialspoint
|
mprotect() - Unix, Linux System Call
Advertisements
NAME
mprotect - control allowable accesses to a region of memory
SYNOPSIS
#include <sys/mman.h>
int mprotect(const void *addr, size_t len, int prot);
|
DESCRIPTION
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:
Tag | Description |
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.
RETURN VALUE
On success,
mprotect() returns zero. On error, -1 is returned, and
errno is set appropriately.
ERRORS
Tag | Description |
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.
|
EXAMPLE
#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("Couldnt 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("Couldnt mprotect");
exit(errno);
}
c = p[666]; /* Read; ok */
p[666] = 42; /* Write; program dies on SIGSEGV */
exit(0);
}
|
CONFORMING TO
SVr4, POSIX.1-2001.
POSIX says that
mprotect() can be used only on regions of memory obtained from
mmap(2).
NOTES
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.
SEE ALSO
Advertisements
|
|
|