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:

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

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("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);
}

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

mmap(2)


Copyright (C) 1995 Michael Shields <shields@tembel.org>.

Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice are
preserved on all copies.

Permission is granted to copy and distribute modified versions of this
manual under the conditions for verbatim copying, provided that the
entire resulting derived work is distributed under the terms of a
permission notice identical to this one.

Since the Linux kernel and libraries are constantly changing, this
manual page may be incorrect or out-of-date.  The author(s) assume no
responsibility for errors or omissions, or for damages resulting from
the use of the information contained herein.  The author(s) may not
have taken the same level of care in the production of this manual,
which is licensed free of charge, as they might when working
professionally.

Formatted or processed versions of this manual, if unaccompanied by
the source, must acknowledge the copyright and author of this work.

Modified 1996-10-22 by Eric S. Raymond <esr@thyrsus.com>
Modified 1997-05-31 by Andries Brouwer <aeb@cwi.nl>
Modified 2003-08-24 by Andries Brouwer <aeb@cwi.nl>
Modified 2004-08-16 by Andi Kleen <ak@muc.de>