1mprotect(2)                   System Calls Manual                  mprotect(2)
2
3
4

NAME

6       mprotect, pkey_mprotect - set protection on a region of memory
7

LIBRARY

9       Standard C library (libc, -lc)
10

SYNOPSIS

12       #include <sys/mman.h>
13
14       int mprotect(void addr[.len], size_t len, int prot);
15
16       #define _GNU_SOURCE             /* See feature_test_macros(7) */
17       #include <sys/mman.h>
18
19       int pkey_mprotect(void addr[.len], size_t len, int prot, int pkey);
20

DESCRIPTION

22       mprotect()  changes  the  access  protections for the calling process's
23       memory pages containing any part of the address range in  the  interval
24       [addr, addr+len-1].  addr must be aligned to a page boundary.
25
26       If the calling process tries to access memory in a manner that violates
27       the protections, then the kernel generates a  SIGSEGV  signal  for  the
28       process.
29
30       prot  is  a  combination  of the following access flags: PROT_NONE or a
31       bitwise-or of the other values in the following list:
32
33       PROT_NONE
34              The memory cannot be accessed at all.
35
36       PROT_READ
37              The memory can be read.
38
39       PROT_WRITE
40              The memory can be modified.
41
42       PROT_EXEC
43              The memory can be executed.
44
45       PROT_SEM (since Linux 2.5.7)
46              The memory can be used for atomic operations.  This flag was in‐
47              troduced  as  part  of  the futex(2) implementation (in order to
48              guarantee the ability to perform atomic operations  required  by
49              commands  such  as  FUTEX_WAIT), but is not currently used in on
50              any architecture.
51
52       PROT_SAO (since Linux 2.6.26)
53              The memory should have strong access ordering.  This feature  is
54              specific to the PowerPC architecture (version 2.06 of the archi‐
55              tecture specification adds the SAO CPU feature, and it is avail‐
56              able on POWER 7 or PowerPC A2, for example).
57
58       Additionally  (since  Linux  2.6.0), prot can have one of the following
59       flags set:
60
61       PROT_GROWSUP
62              Apply the protection mode up to the end of a mapping that  grows
63              upwards.   (Such  mappings are created for the stack area on ar‐
64              chitectures—for example, HP-PARISC—that have an upwardly growing
65              stack.)
66
67       PROT_GROWSDOWN
68              Apply  the  protection  mode  down to the beginning of a mapping
69              that grows downward (which should be a stack segment or  a  seg‐
70              ment mapped with the MAP_GROWSDOWN flag set).
71
72       Like  mprotect(),  pkey_mprotect()  changes the protection on the pages
73       specified by addr and len.  The pkey argument specifies the  protection
74       key (see pkeys(7)) to assign to the memory.  The protection key must be
75       allocated with pkey_alloc(2) before it is  passed  to  pkey_mprotect().
76       For an example of the use of this system call, see pkeys(7).
77

RETURN VALUE

79       On  success,  mprotect()  and  pkey_mprotect()  return zero.  On error,
80       these system calls return -1, and errno is set to indicate the error.
81

ERRORS

83       EACCES The memory cannot be given the specified access.  This can  hap‐
84              pen,  for example, if you mmap(2) a file to which you have read-
85              only access, then ask mprotect() to mark it PROT_WRITE.
86
87       EINVAL addr is not a valid pointer, or not a  multiple  of  the  system
88              page size.
89
90       EINVAL (pkey_mprotect()) pkey has not been allocated with pkey_alloc(2)
91
92       EINVAL Both PROT_GROWSUP and PROT_GROWSDOWN were specified in prot.
93
94       EINVAL Invalid flags specified in prot.
95
96       EINVAL (PowerPC  architecture)  PROT_SAO was specified in prot, but SAO
97              hardware feature is not available.
98
99       ENOMEM Internal kernel structures could not be allocated.
100
101       ENOMEM Addresses in the range [addr, addr+len-1] are  invalid  for  the
102              address  space of the process, or specify one or more pages that
103              are not mapped.  (Before Linux 2.4.19, the error EFAULT was  in‐
104              correctly produced for these cases.)
105
106       ENOMEM Changing  the  protection of a memory region would result in the
107              total number of mappings with distinct  attributes  (e.g.,  read
108              versus  read/write  protection)  exceeding  the allowed maximum.
109              (For example, making the protection of a range PROT_READ in  the
110              middle  of  a region currently protected as PROT_READ|PROT_WRITE
111              would result in three mappings: two read/write mappings at  each
112              end and a read-only mapping in the middle.)
113

VERSIONS

115       POSIX  says that the behavior of mprotect() is unspecified if it is ap‐
116       plied to a region of memory that was not obtained via mmap(2).
117
118       On Linux, it is always permissible to call mprotect() on any address in
119       a  process's  address  space (except for the kernel vsyscall area).  In
120       particular, it can be used to  change  existing  code  mappings  to  be
121       writable.
122
123       Whether  PROT_EXEC  has  any effect different from PROT_READ depends on
124       processor architecture, kernel version, and process state.  If READ_IM‐
125       PLIES_EXEC  is  set  in  the process's personality flags (see personal‐
126       ity(2)), specifying PROT_READ will implicitly add PROT_EXEC.
127
128       On  some  hardware  architectures  (e.g.,  i386),  PROT_WRITE   implies
129       PROT_READ.
130
131       POSIX.1  says  that an implementation may permit access other than that
132       specified in prot, but at a minimum can  allow  write  access  only  if
133       PROT_WRITE has been set, and must not allow any access if PROT_NONE has
134       been set.
135
136       Applications should be  careful  when  mixing  use  of  mprotect()  and
137       pkey_mprotect().   On  x86,  when  mprotect()  is used with prot set to
138       PROT_EXEC a pkey may be allocated and set on the memory  implicitly  by
139       the kernel, but only when the pkey was 0 previously.
140
141       On  systems that do not support protection keys in hardware, pkey_mpro‐
142       tect() may still be used, but pkey must be set to -1.  When called this
143       way, the operation of pkey_mprotect() is equivalent to mprotect().
144

STANDARDS

146       mprotect()
147              POSIX.1-2008.
148
149       pkey_mprotect()
150              Linux.
151

HISTORY

153       mprotect()
154              POSIX.1-2001, SVr4.
155
156       pkey_mprotect()
157              Linux 4.9, glibc 2.27.
158

NOTES

EXAMPLES

161       The  program below demonstrates the use of mprotect().  The program al‐
162       locates four pages of memory, makes the third of these pages read-only,
163       and then executes a loop that walks upward through the allocated region
164       modifying bytes.
165
166       An example of what we might see when running the program is the follow‐
167       ing:
168
169           $ ./a.out
170           Start of region:        0x804c000
171           Got SIGSEGV at address: 0x804e000
172
173   Program source
174
175       #include <malloc.h>
176       #include <signal.h>
177       #include <stdio.h>
178       #include <stdlib.h>
179       #include <sys/mman.h>
180       #include <unistd.h>
181
182       #define handle_error(msg) \
183           do { perror(msg); exit(EXIT_FAILURE); } while (0)
184
185       static char *buffer;
186
187       static void
188       handler(int sig, siginfo_t *si, void *unused)
189       {
190           /* Note: calling printf() from a signal handler is not safe
191              (and should not be done in production programs), since
192              printf() is not async-signal-safe; see signal-safety(7).
193              Nevertheless, we use printf() here as a simple way of
194              showing that the handler was called. */
195
196           printf("Got SIGSEGV at address: %p\n", si->si_addr);
197           exit(EXIT_FAILURE);
198       }
199
200       int
201       main(void)
202       {
203           int               pagesize;
204           struct sigaction  sa;
205
206           sa.sa_flags = SA_SIGINFO;
207           sigemptyset(&sa.sa_mask);
208           sa.sa_sigaction = handler;
209           if (sigaction(SIGSEGV, &sa, NULL) == -1)
210               handle_error("sigaction");
211
212           pagesize = sysconf(_SC_PAGE_SIZE);
213           if (pagesize == -1)
214               handle_error("sysconf");
215
216           /* Allocate a buffer aligned on a page boundary;
217              initial protection is PROT_READ | PROT_WRITE. */
218
219           buffer = memalign(pagesize, 4 * pagesize);
220           if (buffer == NULL)
221               handle_error("memalign");
222
223           printf("Start of region:        %p\n", buffer);
224
225           if (mprotect(buffer + pagesize * 2, pagesize,
226                        PROT_READ) == -1)
227               handle_error("mprotect");
228
229           for (char *p = buffer ; ; )
230               *(p++) = 'a';
231
232           printf("Loop completed\n");     /* Should never happen */
233           exit(EXIT_SUCCESS);
234       }
235

SEE ALSO

237       mmap(2), sysconf(3), pkeys(7)
238
239
240
241Linux man-pages 6.04              2023-03-30                       mprotect(2)
Impressum