]>
Commit | Line | Data |
---|---|---|
c11b1abf | 1 | .\" Copyright (C) 2007 Michael Kerrisk <mtk.manpages@gmail.com> |
2a5e0dcd | 2 | .\" and Copyright (C) 1995 Michael Shields <shields@tembel.org>. |
fea681da | 3 | .\" |
93015253 | 4 | .\" %%%LICENSE_START(VERBATIM) |
fea681da MK |
5 | .\" Permission is granted to make and distribute verbatim copies of this |
6 | .\" manual provided the copyright notice and this permission notice are | |
7 | .\" preserved on all copies. | |
8 | .\" | |
9 | .\" Permission is granted to copy and distribute modified versions of this | |
10 | .\" manual under the conditions for verbatim copying, provided that the | |
11 | .\" entire resulting derived work is distributed under the terms of a | |
12 | .\" permission notice identical to this one. | |
c13182ef | 13 | .\" |
fea681da MK |
14 | .\" Since the Linux kernel and libraries are constantly changing, this |
15 | .\" manual page may be incorrect or out-of-date. The author(s) assume no | |
16 | .\" responsibility for errors or omissions, or for damages resulting from | |
17 | .\" the use of the information contained herein. The author(s) may not | |
18 | .\" have taken the same level of care in the production of this manual, | |
19 | .\" which is licensed free of charge, as they might when working | |
20 | .\" professionally. | |
c13182ef | 21 | .\" |
fea681da MK |
22 | .\" Formatted or processed versions of this manual, if unaccompanied by |
23 | .\" the source, must acknowledge the copyright and author of this work. | |
4b72fb64 | 24 | .\" %%%LICENSE_END |
fea681da MK |
25 | .\" |
26 | .\" Modified 1996-10-22 by Eric S. Raymond <esr@thyrsus.com> | |
27 | .\" Modified 1997-05-31 by Andries Brouwer <aeb@cwi.nl> | |
28 | .\" Modified 2003-08-24 by Andries Brouwer <aeb@cwi.nl> | |
29 | .\" Modified 2004-08-16 by Andi Kleen <ak@muc.de> | |
2a5e0dcd MK |
30 | .\" 2007-06-02, mtk: Fairly substantial rewrites and additions, and |
31 | .\" a much improved example program. | |
decaf596 MK |
32 | .\" FIXME The following protection flags need documenting: |
33 | .\" PROT_SEM | |
34 | .\" PROT_GROWSDOWN | |
35 | .\" PROT_GROWSUP | |
36 | .\" PROT_SAO (PowerPC) | |
fea681da | 37 | .\" |
bf42aad4 | 38 | .TH MPROTECT 2 2012-08-14 "Linux" "Linux Programmer's Manual" |
fea681da | 39 | .SH NAME |
2a5e0dcd | 40 | mprotect \- set protection on a region of memory |
fea681da MK |
41 | .SH SYNOPSIS |
42 | .nf | |
43 | .B #include <sys/mman.h> | |
44 | .sp | |
a2f11be3 | 45 | .BI "int mprotect(void *" addr ", size_t " len ", int " prot ); |
fea681da MK |
46 | .fi |
47 | .SH DESCRIPTION | |
e511ffb6 | 48 | .BR mprotect () |
2a5e0dcd | 49 | changes protection for the calling process's memory page(s) |
988db661 | 50 | containing any part of the address range in the |
657e762d | 51 | interval [\fIaddr\fP,\ \fIaddr\fP+\fIlen\fP\-1]. |
2a5e0dcd MK |
52 | .I addr |
53 | must be aligned to a page boundary. | |
54 | ||
55 | If the calling process tries to access memory in a manner | |
988db661 | 56 | that violates the protection, then the kernel generates a |
2a5e0dcd MK |
57 | .B SIGSEGV |
58 | signal for the process. | |
fea681da MK |
59 | .PP |
60 | .I prot | |
2a5e0dcd MK |
61 | is either |
62 | .B PROT_NONE | |
63 | or a bitwise-or of the other values in the following list: | |
fea681da MK |
64 | .TP 1.1i |
65 | .B PROT_NONE | |
66 | The memory cannot be accessed at all. | |
67 | .TP | |
68 | .B PROT_READ | |
69 | The memory can be read. | |
70 | .TP | |
71 | .B PROT_WRITE | |
2a5e0dcd | 72 | The memory can be modified. |
fea681da MK |
73 | .TP |
74 | .B PROT_EXEC | |
fc15ae54 | 75 | The memory can be executed. |
e7d3b070 | 76 | .\" FIXME |
2b83e9fe | 77 | .\" Document PROT_GROWSUP and PROT_GROWSDOWN |
47297adb | 78 | .SH RETURN VALUE |
fea681da | 79 | On success, |
e511ffb6 | 80 | .BR mprotect () |
c13182ef MK |
81 | returns zero. |
82 | On error, \-1 is returned, and | |
fea681da MK |
83 | .I errno |
84 | is set appropriately. | |
85 | .SH ERRORS | |
86 | .TP | |
87 | .B EACCES | |
c13182ef MK |
88 | The memory cannot be given the specified access. |
89 | This can happen, for example, if you | |
fea681da MK |
90 | .BR mmap (2) |
91 | a file to which you have read-only access, then ask | |
e511ffb6 | 92 | .BR mprotect () |
fea681da MK |
93 | to mark it |
94 | .BR PROT_WRITE . | |
95 | .TP | |
fea681da | 96 | .B EINVAL |
a8d55537 | 97 | \fIaddr\fP is not a valid pointer, |
2a5e0dcd | 98 | or not a multiple of the system page size. |
3a928a50 | 99 | .\" Or: both PROT_GROWSUP and PROT_GROWSDOWN were specified in 'prot'. |
fea681da MK |
100 | .TP |
101 | .B ENOMEM | |
c13182ef | 102 | Internal kernel structures could not be allocated. |
22b22831 MK |
103 | .TP |
104 | .B ENOMEM | |
105 | Addresses in the range | |
f8ad0aeb | 106 | .RI [ addr , |
da2336b3 | 107 | .IR addr + len \-1] |
f8ad0aeb MK |
108 | are invalid for the address space of the process, |
109 | or specify one or more pages that are not mapped. | |
22b22831 MK |
110 | (Before kernel 2.4.19, the error |
111 | .BR EFAULT | |
112 | was incorrectly produced for these cases.) | |
47297adb | 113 | .SH CONFORMING TO |
2b2581ee MK |
114 | SVr4, POSIX.1-2001. |
115 | .\" SVr4 defines an additional error | |
116 | .\" code EAGAIN. The SVr4 error conditions don't map neatly onto Linux's. | |
d9bfdb9c | 117 | POSIX says that the behavior of |
2b2581ee | 118 | .BR mprotect () |
2a5e0dcd MK |
119 | is unspecified if it is applied to a region of memory that |
120 | was not obtained via | |
2b2581ee MK |
121 | .BR mmap (2). |
122 | .SH NOTES | |
e935e108 | 123 | On Linux it is always permissible to call |
2b2581ee | 124 | .BR mprotect () |
fc7ba057 | 125 | on any address in a process's address space (except for the |
2b2581ee MK |
126 | kernel vsyscall area). |
127 | In particular it can be used | |
128 | to change existing code mappings to be writable. | |
129 | ||
130 | Whether | |
131 | .B PROT_EXEC | |
132 | has any effect different from | |
133 | .B PROT_READ | |
a43eed0c | 134 | is architecture- and kernel version-dependent. |
34ccb744 | 135 | On some hardware architectures (e.g., i386), |
0daa9e92 | 136 | .B PROT_WRITE |
f3edaabb MK |
137 | implies |
138 | .BR PROT_READ . | |
2a5e0dcd MK |
139 | |
140 | POSIX.1-2001 says that an implementation may permit access | |
141 | other than that specified in | |
142 | .IR prot , | |
143 | but at a minimum can only allow write access if | |
144 | .B PROT_WRITE | |
145 | has been set, and must not allow any access if | |
146 | .B PROT_NONE | |
147 | has been set. | |
fea681da | 148 | .SH EXAMPLE |
2720c2ed | 149 | .\" sigaction.2 refers to this example |
f20d7d8e | 150 | .PP |
2a5e0dcd | 151 | The program below allocates four pages of memory, makes the third |
5fab2e7c | 152 | of these pages read-only, and then executes a loop that walks upward |
f20d7d8e MK |
153 | through the allocated region modifying bytes. |
154 | ||
155 | An example of what we might see when running the program is the | |
156 | following: | |
157 | ||
088a639b | 158 | .in +4n |
fea681da | 159 | .nf |
b43a3b30 | 160 | .RB "$" " ./a.out" |
f20d7d8e MK |
161 | Start of region: 0x804c000 |
162 | Got SIGSEGV at address: 0x804e000 | |
163 | .fi | |
1c32ee47 | 164 | .in |
9c330504 | 165 | .SS Program source |
d84d0300 | 166 | \& |
f20d7d8e | 167 | .nf |
f20d7d8e MK |
168 | #include <unistd.h> |
169 | #include <signal.h> | |
fea681da | 170 | #include <stdio.h> |
f20d7d8e | 171 | #include <malloc.h> |
fea681da MK |
172 | #include <stdlib.h> |
173 | #include <errno.h> | |
174 | #include <sys/mman.h> | |
175 | ||
6a578b88 MK |
176 | #define handle_error(msg) \\ |
177 | do { perror(msg); exit(EXIT_FAILURE); } while (0) | |
d3b5ab82 | 178 | |
f20d7d8e MK |
179 | char *buffer; |
180 | ||
181 | static void | |
182 | handler(int sig, siginfo_t *si, void *unused) | |
183 | { | |
988db661 | 184 | printf("Got SIGSEGV at address: 0x%lx\\n", |
29059a65 | 185 | (long) si\->si_addr); |
f20d7d8e MK |
186 | exit(EXIT_FAILURE); |
187 | } | |
fea681da MK |
188 | |
189 | int | |
f20d7d8e | 190 | main(int argc, char *argv[]) |
fea681da MK |
191 | { |
192 | char *p; | |
f20d7d8e MK |
193 | int pagesize; |
194 | struct sigaction sa; | |
195 | ||
196 | sa.sa_flags = SA_SIGINFO; | |
197 | sigemptyset(&sa.sa_mask); | |
198 | sa.sa_sigaction = handler; | |
29059a65 | 199 | if (sigaction(SIGSEGV, &sa, NULL) == \-1) |
6a578b88 | 200 | handle_error("sigaction"); |
fea681da | 201 | |
f20d7d8e | 202 | pagesize = sysconf(_SC_PAGE_SIZE); |
29059a65 | 203 | if (pagesize == \-1) |
6a578b88 | 204 | handle_error("sysconf"); |
fea681da | 205 | |
988db661 | 206 | /* Allocate a buffer aligned on a page boundary; |
f20d7d8e MK |
207 | initial protection is PROT_READ | PROT_WRITE */ |
208 | ||
209 | buffer = memalign(pagesize, 4 * pagesize); | |
d3b5ab82 | 210 | if (buffer == NULL) |
6a578b88 | 211 | handle_error("memalign"); |
fea681da | 212 | |
f20d7d8e | 213 | printf("Start of region: 0x%lx\\n", (long) buffer); |
fea681da | 214 | |
988db661 | 215 | if (mprotect(buffer + pagesize * 2, pagesize, |
7d9da03f | 216 | PROT_READ) == \-1) |
6a578b88 | 217 | handle_error("mprotect"); |
fea681da | 218 | |
f20d7d8e | 219 | for (p = buffer ; ; ) |
f81fb444 | 220 | *(p++) = \(aqa\(aq; |
fea681da | 221 | |
f20d7d8e | 222 | printf("Loop completed\\n"); /* Should never happen */ |
646f46f0 | 223 | exit(EXIT_SUCCESS); |
fea681da MK |
224 | } |
225 | .fi | |
47297adb | 226 | .SH SEE ALSO |
2a5e0dcd MK |
227 | .BR mmap (2), |
228 | .BR sysconf (3) |