]>
Commit | Line | Data |
---|---|---|
c13182ef | 1 | .\" -*- nroff -*- |
2a5e0dcd MK |
2 | .\" Copyright (C) 2007 Michael Kerrisk <mtk-manpages@gmx.net> |
3 | .\" and Copyright (C) 1995 Michael Shields <shields@tembel.org>. | |
fea681da MK |
4 | .\" |
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. | |
24 | .\" | |
25 | .\" Modified 1996-10-22 by Eric S. Raymond <esr@thyrsus.com> | |
26 | .\" Modified 1997-05-31 by Andries Brouwer <aeb@cwi.nl> | |
27 | .\" Modified 2003-08-24 by Andries Brouwer <aeb@cwi.nl> | |
28 | .\" Modified 2004-08-16 by Andi Kleen <ak@muc.de> | |
2a5e0dcd MK |
29 | .\" 2007-06-02, mtk: Fairly substantial rewrites and additions, and |
30 | .\" a much improved example program. | |
fea681da | 31 | .\" |
2a5e0dcd | 32 | .TH MPROTECT 2 2007-06-02 "Linux" "Linux Programmer's Manual" |
fea681da | 33 | .SH NAME |
2a5e0dcd | 34 | mprotect \- set protection on a region of memory |
fea681da MK |
35 | .SH SYNOPSIS |
36 | .nf | |
37 | .B #include <sys/mman.h> | |
38 | .sp | |
39 | \fBint mprotect(const void *\fIaddr\fB, size_t \fIlen\fB, int \fIprot\fB); | |
40 | .fi | |
41 | .SH DESCRIPTION | |
e511ffb6 | 42 | .BR mprotect () |
2a5e0dcd MK |
43 | changes protection for the calling process's memory page(s) |
44 | containing any part of the address range in the | |
45 | interval [\fIaddr\fP,\fIaddr\fP+\fIlen\fP\-1]. | |
46 | .I addr | |
47 | must be aligned to a page boundary. | |
48 | ||
49 | If the calling process tries to access memory in a manner | |
50 | that violates the protection, then the kernel generates a | |
51 | .B SIGSEGV | |
52 | signal for the process. | |
fea681da MK |
53 | .PP |
54 | .I prot | |
2a5e0dcd MK |
55 | is either |
56 | .B PROT_NONE | |
57 | or a bitwise-or of the other values in the following list: | |
fea681da MK |
58 | .TP 1.1i |
59 | .B PROT_NONE | |
60 | The memory cannot be accessed at all. | |
61 | .TP | |
62 | .B PROT_READ | |
63 | The memory can be read. | |
64 | .TP | |
65 | .B PROT_WRITE | |
2a5e0dcd | 66 | The memory can be modified. |
fea681da MK |
67 | .TP |
68 | .B PROT_EXEC | |
2a5e0dcd | 69 | The memory can contain be executed. |
e7d3b070 MK |
70 | .\" FIXME |
71 | .\" Document MAP_GROWSUP and MAP_GROWSDOWN | |
fea681da MK |
72 | .SH "RETURN VALUE" |
73 | On success, | |
e511ffb6 | 74 | .BR mprotect () |
c13182ef MK |
75 | returns zero. |
76 | On error, \-1 is returned, and | |
fea681da MK |
77 | .I errno |
78 | is set appropriately. | |
79 | .SH ERRORS | |
80 | .TP | |
81 | .B EACCES | |
c13182ef MK |
82 | The memory cannot be given the specified access. |
83 | This can happen, for example, if you | |
fea681da MK |
84 | .BR mmap (2) |
85 | a file to which you have read-only access, then ask | |
e511ffb6 | 86 | .BR mprotect () |
fea681da MK |
87 | to mark it |
88 | .BR PROT_WRITE . | |
89 | .TP | |
90 | .B EFAULT | |
91 | The memory cannot be accessed. | |
92 | .TP | |
93 | .B EINVAL | |
2a5e0dcd MK |
94 | \fIaddr\fR is not a valid pointer, |
95 | or not a multiple of the system page size. | |
fea681da MK |
96 | .TP |
97 | .B ENOMEM | |
c13182ef | 98 | Internal kernel structures could not be allocated. |
c8a55a3d | 99 | Or: addresses in the range |
f8ad0aeb MK |
100 | .RI [ addr , |
101 | .IR addr + len ] | |
102 | are invalid for the address space of the process, | |
103 | or specify one or more pages that are not mapped. | |
2b2581ee MK |
104 | .SH "CONFORMING TO" |
105 | SVr4, POSIX.1-2001. | |
106 | .\" SVr4 defines an additional error | |
107 | .\" code EAGAIN. The SVr4 error conditions don't map neatly onto Linux's. | |
d9bfdb9c | 108 | POSIX says that the behavior of |
2b2581ee | 109 | .BR mprotect () |
2a5e0dcd MK |
110 | is unspecified if it is applied to a region of memory that |
111 | was not obtained via | |
2b2581ee MK |
112 | .BR mmap (2). |
113 | .SH NOTES | |
114 | On Linux it is always legal to call | |
115 | .BR mprotect () | |
fc7ba057 | 116 | on any address in a process's address space (except for the |
2b2581ee MK |
117 | kernel vsyscall area). |
118 | In particular it can be used | |
119 | to change existing code mappings to be writable. | |
120 | ||
121 | Whether | |
122 | .B PROT_EXEC | |
123 | has any effect different from | |
124 | .B PROT_READ | |
125 | is architecture and kernel version dependent. | |
2a5e0dcd MK |
126 | |
127 | POSIX.1-2001 says that an implementation may permit access | |
128 | other than that specified in | |
129 | .IR prot , | |
130 | but at a minimum can only allow write access if | |
131 | .B PROT_WRITE | |
132 | has been set, and must not allow any access if | |
133 | .B PROT_NONE | |
134 | has been set. | |
fea681da | 135 | .SH EXAMPLE |
2720c2ed | 136 | .\" sigaction.2 refers to this example |
f20d7d8e | 137 | .PP |
2a5e0dcd | 138 | The program below allocates four pages of memory, makes the third |
f20d7d8e MK |
139 | of these pages read-only, and then executes a loop that walks upwards |
140 | through the allocated region modifying bytes. | |
141 | ||
142 | An example of what we might see when running the program is the | |
143 | following: | |
144 | ||
145 | .in +0.5i | |
fea681da | 146 | .nf |
f20d7d8e MK |
147 | $ ./a.out |
148 | Start of region: 0x804c000 | |
149 | Got SIGSEGV at address: 0x804e000 | |
150 | .fi | |
151 | .in | |
152 | .nf | |
153 | ||
154 | #include <unistd.h> | |
155 | #include <signal.h> | |
fea681da | 156 | #include <stdio.h> |
f20d7d8e | 157 | #include <malloc.h> |
fea681da MK |
158 | #include <stdlib.h> |
159 | #include <errno.h> | |
160 | #include <sys/mman.h> | |
161 | ||
d3b5ab82 MK |
162 | #define die(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0) |
163 | ||
f20d7d8e MK |
164 | char *buffer; |
165 | ||
166 | static void | |
167 | handler(int sig, siginfo_t *si, void *unused) | |
168 | { | |
169 | printf("Got SIGSEGV at address: 0x%lx\\n", | |
170 | (long) si->si_addr); | |
171 | exit(EXIT_FAILURE); | |
172 | } | |
fea681da MK |
173 | |
174 | int | |
f20d7d8e | 175 | main(int argc, char *argv[]) |
fea681da MK |
176 | { |
177 | char *p; | |
f20d7d8e MK |
178 | int pagesize; |
179 | struct sigaction sa; | |
180 | ||
181 | sa.sa_flags = SA_SIGINFO; | |
182 | sigemptyset(&sa.sa_mask); | |
183 | sa.sa_sigaction = handler; | |
d3b5ab82 MK |
184 | if (sigaction(SIGSEGV, &sa, NULL) == -1) |
185 | die("sigaction"); | |
fea681da | 186 | |
f20d7d8e | 187 | pagesize = sysconf(_SC_PAGE_SIZE); |
d3b5ab82 MK |
188 | if (pagesize == -1) |
189 | die("sysconf"); | |
fea681da | 190 | |
f20d7d8e MK |
191 | /* Allocate a buffer aligned on a page boundary; |
192 | initial protection is PROT_READ | PROT_WRITE */ | |
193 | ||
194 | buffer = memalign(pagesize, 4 * pagesize); | |
d3b5ab82 MK |
195 | if (buffer == NULL) |
196 | die("memalign"); | |
fea681da | 197 | |
f20d7d8e | 198 | printf("Start of region: 0x%lx\\n", (long) buffer); |
fea681da | 199 | |
f20d7d8e | 200 | if (mprotect(buffer + pagesize * 2, pagesize, |
d3b5ab82 MK |
201 | PROT_NONE) == -1) |
202 | die("mprotect"); | |
fea681da | 203 | |
f20d7d8e MK |
204 | for (p = buffer ; ; ) |
205 | *(p++) = 'a'; | |
fea681da | 206 | |
f20d7d8e | 207 | printf("Loop completed\\n"); /* Should never happen */ |
646f46f0 | 208 | exit(EXIT_SUCCESS); |
fea681da MK |
209 | } |
210 | .fi | |
fea681da | 211 | .SH "SEE ALSO" |
2a5e0dcd MK |
212 | .BR mmap (2), |
213 | .BR sysconf (3) |