OSDN Git Service

LDP: Update original to LDP v3.75
[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 .\"
33 .\" FIXME The following protection flags need documenting:
34 .\"         PROT_SEM
35 .\"         PROT_GROWSDOWN
36 .\"         PROT_GROWSUP
37 .\"         PROT_SAO (PowerPC)
38 .\"
39 .TH MPROTECT 2 2014-01-05 "Linux" "Linux Programmer's Manual"
40 .SH NAME
41 mprotect \- set protection on a region of memory
42 .SH SYNOPSIS
43 .nf
44 .B #include <sys/mman.h>
45 .sp
46 .BI "int mprotect(void *" addr ", size_t " len ", int " prot );
47 .fi
48 .SH DESCRIPTION
49 .BR mprotect ()
50 changes protection for the calling process's memory page(s)
51 containing any part of the address range in the
52 interval [\fIaddr\fP,\ \fIaddr\fP+\fIlen\fP\-1].
53 .I addr
54 must be aligned to a page boundary.
55
56 If the calling process tries to access memory in a manner
57 that violates the protection, then the kernel generates a
58 .B SIGSEGV
59 signal for the process.
60 .PP
61 .I prot
62 is either
63 .B PROT_NONE
64 or a bitwise-or of the other values in the following list:
65 .TP 1.1i
66 .B PROT_NONE
67 The memory cannot be accessed at all.
68 .TP
69 .B PROT_READ
70 The memory can be read.
71 .TP
72 .B PROT_WRITE
73 The memory can be modified.
74 .TP
75 .B PROT_EXEC
76 The memory can be executed.
77 .SH RETURN VALUE
78 On success,
79 .BR mprotect ()
80 returns zero.
81 On error, \-1 is returned, and
82 .I errno
83 is set appropriately.
84 .SH ERRORS
85 .TP
86 .B EACCES
87 The memory cannot be given the specified access.
88 This can happen, for example, if you
89 .BR mmap (2)
90 a file to which you have read-only access, then ask
91 .BR mprotect ()
92 to mark it
93 .BR PROT_WRITE .
94 .TP
95 .B EINVAL
96 \fIaddr\fP is not a valid pointer,
97 or not a multiple of the system page size.
98 .\" Or: both PROT_GROWSUP and PROT_GROWSDOWN were specified in 'prot'.
99 .TP
100 .B ENOMEM
101 Internal kernel structures could not be allocated.
102 .TP
103 .B ENOMEM
104 Addresses in the range
105 .RI [ addr ,
106 .IR addr + len \-1]
107 are invalid for the address space of the process,
108 or specify one or more pages that are not mapped.
109 (Before kernel 2.4.19, the error
110 .BR EFAULT
111 was incorrectly produced for these cases.)
112 .SH CONFORMING TO
113 SVr4, POSIX.1-2001.
114 .\" SVr4 defines an additional error
115 .\" code EAGAIN. The SVr4 error conditions don't map neatly onto Linux's.
116 POSIX says that the behavior of
117 .BR mprotect ()
118 is unspecified if it is applied to a region of memory that
119 was not obtained via
120 .BR mmap (2).
121 .SH NOTES
122 On Linux it is always permissible to call
123 .BR mprotect ()
124 on any address in a process's address space (except for the
125 kernel vsyscall area).
126 In particular it can be used
127 to change existing code mappings to be writable.
128
129 Whether
130 .B PROT_EXEC
131 has any effect different from
132 .B PROT_READ
133 is architecture- and kernel version-dependent.
134 On some hardware architectures (e.g., i386),
135 .B PROT_WRITE
136 implies
137 .BR PROT_READ .
138
139 POSIX.1-2001 says that an implementation may permit access
140 other than that specified in
141 .IR prot ,
142 but at a minimum can allow write access only if
143 .B PROT_WRITE
144 has been set, and must not allow any access if
145 .B PROT_NONE
146 has been set.
147 .SH EXAMPLE
148 .\" sigaction.2 refers to this example
149 .PP
150 The program below allocates four pages of memory, makes the third
151 of these pages read-only, and then executes a loop that walks upward
152 through the allocated region modifying bytes.
153
154 An example of what we might see when running the program is the
155 following:
156
157 .in +4n
158 .nf
159 .RB "$" " ./a.out"
160 Start of region:        0x804c000
161 Got SIGSEGV at address: 0x804e000
162 .fi
163 .in
164 .SS Program source
165 \&
166 .nf
167 #include <unistd.h>
168 #include <signal.h>
169 #include <stdio.h>
170 #include <malloc.h>
171 #include <stdlib.h>
172 #include <errno.h>
173 #include <sys/mman.h>
174
175 #define handle_error(msg) \\
176     do { perror(msg); exit(EXIT_FAILURE); } while (0)
177
178 static char *buffer;
179
180 static void
181 handler(int sig, siginfo_t *si, void *unused)
182 {
183     printf("Got SIGSEGV at address: 0x%lx\\n",
184             (long) si\->si_addr);
185     exit(EXIT_FAILURE);
186 }
187
188 int
189 main(int argc, char *argv[])
190 {
191     char *p;
192     int pagesize;
193     struct sigaction sa;
194
195     sa.sa_flags = SA_SIGINFO;
196     sigemptyset(&sa.sa_mask);
197     sa.sa_sigaction = handler;
198     if (sigaction(SIGSEGV, &sa, NULL) == \-1)
199         handle_error("sigaction");
200
201     pagesize = sysconf(_SC_PAGE_SIZE);
202     if (pagesize == \-1)
203         handle_error("sysconf");
204
205     /* Allocate a buffer aligned on a page boundary;
206        initial protection is PROT_READ | PROT_WRITE */
207
208     buffer = memalign(pagesize, 4 * pagesize);
209     if (buffer == NULL)
210         handle_error("memalign");
211
212     printf("Start of region:        0x%lx\\n", (long) buffer);
213
214     if (mprotect(buffer + pagesize * 2, pagesize,
215                 PROT_READ) == \-1)
216         handle_error("mprotect");
217
218     for (p = buffer ; ; )
219         *(p++) = \(aqa\(aq;
220
221     printf("Loop completed\\n");     /* Should never happen */
222     exit(EXIT_SUCCESS);
223 }
224 .fi
225 .SH SEE ALSO
226 .BR mmap (2),
227 .BR sysconf (3)
228 .SH COLOPHON
229 This page is part of release 3.75 of the Linux
230 .I man-pages
231 project.
232 A description of the project,
233 information about reporting bugs,
234 and the latest version of this page,
235 can be found at
236 \%http://www.kernel.org/doc/man\-pages/.