OSDN Git Service

(split) LDP: Update original to LDP v3.50.
[linuxjm/LDP_man-pages.git] / original / man2 / mprotect.2
1 .\" Copyright (C) 2007 Michael Kerrisk <mtk.manpages@gmail.com>
2 .\" and Copyright (C) 1995 Michael Shields <shields@tembel.org>.
3 .\"
4 .\" %%%LICENSE_START(VERBATIM)
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.
13 .\"
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.
21 .\"
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and author of this work.
24 .\" %%%LICENSE_END
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>
30 .\" 2007-06-02, mtk: Fairly substantial rewrites and additions, and
31 .\" a much improved example program.
32 .\" FIXME The following protection flags need documenting:
33 .\"         PROT_SEM
34 .\"         PROT_GROWSDOWN
35 .\"         PROT_GROWSUP
36 .\"         PROT_SAO (PowerPC)
37 .\"
38 .TH MPROTECT 2 2012-08-14 "Linux" "Linux Programmer's Manual"
39 .SH NAME
40 mprotect \- set protection on a region of memory
41 .SH SYNOPSIS
42 .nf
43 .B #include <sys/mman.h>
44 .sp
45 .BI "int mprotect(void *" addr ", size_t " len ", int " prot );
46 .fi
47 .SH DESCRIPTION
48 .BR mprotect ()
49 changes protection for the calling process's memory page(s)
50 containing any part of the address range in the
51 interval [\fIaddr\fP,\ \fIaddr\fP+\fIlen\fP\-1].
52 .I addr
53 must be aligned to a page boundary.
54
55 If the calling process tries to access memory in a manner
56 that violates the protection, then the kernel generates a
57 .B SIGSEGV
58 signal for the process.
59 .PP
60 .I prot
61 is either
62 .B PROT_NONE
63 or a bitwise-or of the other values in the following list:
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
72 The memory can be modified.
73 .TP
74 .B PROT_EXEC
75 The memory can be executed.
76 .\" FIXME
77 .\" Document PROT_GROWSUP and PROT_GROWSDOWN
78 .SH RETURN VALUE
79 On success,
80 .BR mprotect ()
81 returns zero.
82 On error, \-1 is returned, and
83 .I errno
84 is set appropriately.
85 .SH ERRORS
86 .TP
87 .B EACCES
88 The memory cannot be given the specified access.
89 This can happen, for example, if you
90 .BR mmap (2)
91 a file to which you have read-only access, then ask
92 .BR mprotect ()
93 to mark it
94 .BR PROT_WRITE .
95 .TP
96 .B EINVAL
97 \fIaddr\fP is not a valid pointer,
98 or not a multiple of the system page size.
99 .\" Or: both PROT_GROWSUP and PROT_GROWSDOWN were specified in 'prot'.
100 .TP
101 .B ENOMEM
102 Internal kernel structures could not be allocated.
103 .TP
104 .B ENOMEM
105 Addresses in the range
106 .RI [ addr ,
107 .IR addr + len \-1]
108 are invalid for the address space of the process,
109 or specify one or more pages that are not mapped.
110 (Before kernel 2.4.19, the error
111 .BR EFAULT
112 was incorrectly produced for these cases.)
113 .SH CONFORMING TO
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.
117 POSIX says that the behavior of
118 .BR mprotect ()
119 is unspecified if it is applied to a region of memory that
120 was not obtained via
121 .BR mmap (2).
122 .SH NOTES
123 On Linux it is always permissible to call
124 .BR mprotect ()
125 on any address in a process's address space (except for the
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
134 is architecture- and kernel version-dependent.
135 On some hardware architectures (e.g., i386),
136 .B PROT_WRITE
137 implies
138 .BR PROT_READ .
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.
148 .SH EXAMPLE
149 .\" sigaction.2 refers to this example
150 .PP
151 The program below allocates four pages of memory, makes the third
152 of these pages read-only, and then executes a loop that walks upward
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
158 .in +4n
159 .nf
160 .RB "$" " ./a.out"
161 Start of region:        0x804c000
162 Got SIGSEGV at address: 0x804e000
163 .fi
164 .in
165 .SS Program source
166 \&
167 .nf
168 #include <unistd.h>
169 #include <signal.h>
170 #include <stdio.h>
171 #include <malloc.h>
172 #include <stdlib.h>
173 #include <errno.h>
174 #include <sys/mman.h>
175
176 #define handle_error(msg) \\
177     do { perror(msg); exit(EXIT_FAILURE); } while (0)
178
179 char *buffer;
180
181 static void
182 handler(int sig, siginfo_t *si, void *unused)
183 {
184     printf("Got SIGSEGV at address: 0x%lx\\n",
185             (long) si\->si_addr);
186     exit(EXIT_FAILURE);
187 }
188
189 int
190 main(int argc, char *argv[])
191 {
192     char *p;
193     int pagesize;
194     struct sigaction sa;
195
196     sa.sa_flags = SA_SIGINFO;
197     sigemptyset(&sa.sa_mask);
198     sa.sa_sigaction = handler;
199     if (sigaction(SIGSEGV, &sa, NULL) == \-1)
200         handle_error("sigaction");
201
202     pagesize = sysconf(_SC_PAGE_SIZE);
203     if (pagesize == \-1)
204         handle_error("sysconf");
205
206     /* Allocate a buffer aligned on a page boundary;
207        initial protection is PROT_READ | PROT_WRITE */
208
209     buffer = memalign(pagesize, 4 * pagesize);
210     if (buffer == NULL)
211         handle_error("memalign");
212
213     printf("Start of region:        0x%lx\\n", (long) buffer);
214
215     if (mprotect(buffer + pagesize * 2, pagesize,
216                 PROT_READ) == \-1)
217         handle_error("mprotect");
218
219     for (p = buffer ; ; )
220         *(p++) = \(aqa\(aq;
221
222     printf("Loop completed\\n");     /* Should never happen */
223     exit(EXIT_SUCCESS);
224 }
225 .fi
226 .SH SEE ALSO
227 .BR mmap (2),
228 .BR sysconf (3)