| @@ -1,275 +1,280 @@ | | | @@ -1,275 +1,280 @@ |
1 | .\" $NetBSD: stack.7,v 1.1 2023/11/23 21:20:49 riastradh Exp $ | | 1 | .\" $NetBSD: stack.7,v 1.2 2023/11/23 21:27:08 riastradh Exp $ |
2 | .\" | | 2 | .\" |
3 | .\" Copyright (c) 2023 The NetBSD Foundation, Inc. | | 3 | .\" Copyright (c) 2023 The NetBSD Foundation, Inc. |
4 | .\" All rights reserved. | | 4 | .\" All rights reserved. |
5 | .\" | | 5 | .\" |
6 | .\" Redistribution and use in source and binary forms, with or without | | 6 | .\" Redistribution and use in source and binary forms, with or without |
7 | .\" modification, are permitted provided that the following conditions | | 7 | .\" modification, are permitted provided that the following conditions |
8 | .\" are met: | | 8 | .\" are met: |
9 | .\" 1. Redistributions of source code must retain the above copyright | | 9 | .\" 1. Redistributions of source code must retain the above copyright |
10 | .\" notice, this list of conditions and the following disclaimer. | | 10 | .\" notice, this list of conditions and the following disclaimer. |
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | | 11 | .\" 2. Redistributions in binary form must reproduce the above copyright |
12 | .\" notice, this list of conditions and the following disclaimer in the | | 12 | .\" notice, this list of conditions and the following disclaimer in the |
13 | .\" documentation and/or other materials provided with the distribution. | | 13 | .\" documentation and/or other materials provided with the distribution. |
14 | .\" | | 14 | .\" |
15 | .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS | | 15 | .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS |
16 | .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 16 | .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
17 | .\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 17 | .\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
18 | .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | | 18 | .\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS |
19 | .\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | | 19 | .\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | | 20 | .\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | | 21 | .\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | | 22 | .\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 23 | .\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 24 | .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 | .\" POSSIBILITY OF SUCH DAMAGE. | | 25 | .\" POSSIBILITY OF SUCH DAMAGE. |
26 | .\" | | 26 | .\" |
27 | .Dd November 23, 2023 | | 27 | .Dd November 23, 2023 |
28 | .Dt STACK 7 | | 28 | .Dt STACK 7 |
29 | .Os | | 29 | .Os |
30 | .Sh NAME | | 30 | .Sh NAME |
31 | .Nm stack | | 31 | .Nm stack |
32 | .Nd layout of program execution stack memory | | 32 | .Nd layout of program execution stack memory |
33 | .Sh DESCRIPTION | | 33 | .Sh DESCRIPTION |
34 | When executing a program, with the | | 34 | When executing a program, with the |
35 | .Xr execve 2 | | 35 | .Xr execve 2 |
36 | or | | 36 | or |
37 | .Xr posix_spawn 3 | | 37 | .Xr posix_spawn 3 |
38 | families of system calls, | | 38 | families of system calls, |
39 | .Nx | | 39 | .Nx |
40 | reserves a region in the new program image's virtual address space for | | 40 | reserves a region in the new program image's virtual address space for |
41 | the | | 41 | the |
42 | .Em stack , | | 42 | .Em stack , |
43 | which stores return addresses and local variables for nested procedure | | 43 | which stores return addresses and local variables for nested procedure |
44 | calls in program execution. | | 44 | calls in program execution. |
45 | Similarly, threads created with | | 45 | Similarly, threads created with |
46 | .Xr pthread_create 3 | | 46 | .Xr pthread_create 3 |
47 | have regions allocated for per-thread stacks. | | 47 | have regions allocated for per-thread stacks. |
48 | .Pp | | 48 | .Pp |
49 | The stack grows from the | | 49 | The stack grows from the |
50 | .Em base , | | 50 | .Em base , |
51 | where information of the outermost procedure call is stored, fixed at | | 51 | where information of the outermost procedure call is stored, fixed at |
52 | program start, to the | | 52 | program start, to the |
53 | .Em stack pointer , | | 53 | .Em stack pointer , |
54 | a | | 54 | a |
55 | .Tn CPU | | 55 | .Tn CPU |
56 | register that points to information used by the current procedure call, | | 56 | register that points to information used by the current procedure call, |
57 | varying during execution as procedures are called. | | 57 | varying during execution as procedures are called. |
58 | .Pp | | 58 | .Pp |
59 | On most architectures, the stack base is at higher-numbered virtual | | 59 | On most architectures, the stack base is at higher-numbered virtual |
60 | addresses and the stack pointer is at lower-numbered virtual addresses | | 60 | addresses and the stack pointer is at lower-numbered virtual addresses |
61 | \(em on these architectures, | | 61 | \(em on these architectures, |
62 | .Em the stack grows down . | | 62 | .Em the stack grows down . |
63 | On some other architectures, notably | | 63 | On some other architectures, notably |
64 | .Tn HP PA-RISC | | 64 | .Tn HP PA-RISC |
65 | .Pq Sq hppa , | | 65 | .Pq Sq hppa , |
66 | the stack base is at lower-numbered virtual addresses and the stack | | 66 | the stack base is at lower-numbered virtual addresses and the stack |
67 | pointer is at higher-numbered virtual addresses, so on those | | 67 | pointer is at higher-numbered virtual addresses, so on those |
68 | architectures | | 68 | architectures |
69 | .Em the stack grows up . | | 69 | .Em the stack grows up . |
70 | .Pp | | 70 | .Pp |
71 | In the kernel, the C preprocessor macro | | 71 | In the kernel, the C preprocessor macro |
72 | .Dv __HAVE_MACHINE_STACK_GROWS_UP | | 72 | .Dv __HAVE_MACHINE_STACK_GROWS_UP |
73 | is defined in | | 73 | is defined in |
74 | .In machine/types.h | | 74 | .In machine/types.h |
75 | on architectures where the stack grows up. | | 75 | on architectures where the stack grows up. |
76 | .Ss Main thread | | 76 | .Ss Main thread |
77 | For single-threaded programs, and for the main thread of multi-threaded | | 77 | For single-threaded programs, and for the main thread of multi-threaded |
78 | programs, | | 78 | programs, |
79 | .Nx | | 79 | .Nx |
80 | reserves virtual addresses as follows on architectures where the stack | | 80 | reserves virtual addresses as follows on architectures where the stack |
81 | grows down: | | 81 | grows down: |
82 | .Bd -literal | | 82 | .Bd -literal |
83 | +--------------------+ USRSTACK | | 83 | +--------------------+ USRSTACK |
84 | | stack gap | | | 84 | | stack gap | |
85 | +--------------------+ stack base | | 85 | +--------------------+ stack base |
86 | | accessible stack | | | 86 | | accessible stack | |
87 | | . | | | 87 | | . | |
88 | | . | <-- stack pointer (varies during execution) | | 88 | | . | <-- stack pointer (varies during execution) |
89 | | . | | | 89 | | . | |
90 | +--------------------+ (stack base) - (soft stack rlimit) | | 90 | +--------------------+ (stack base) - (soft stack rlimit) |
91 | | inaccessible stack | | | 91 | | inaccessible stack | |
92 | +--------------------+ (stack base) - (hard stack rlimit) | | 92 | +--------------------+ (stack base) - (hard stack rlimit) |
93 | | guard/redzone | | | 93 | | guard/redzone | |
94 | +--------------------+ USRSTACK - MAXSSIZ | | 94 | +--------------------+ USRSTACK - MAXSSIZ |
95 | .Ed | | 95 | .Ed |
96 | .Pp | | 96 | .Pp |
97 | On architectures where the stack grows up, the layout is: | | 97 | On architectures where the stack grows up, the layout is: |
98 | .Bd -literal | | 98 | .Bd -literal |
99 | +--------------------+ USRSTACK + MAXSSIZ | | 99 | +--------------------+ USRSTACK + MAXSSIZ |
100 | | guard/redzone | | | 100 | | guard/redzone | |
101 | +--------------------+ (stack base) + (hard stack rlimit) | | 101 | +--------------------+ (stack base) + (hard stack rlimit) |
102 | | inaccessible pages | | | 102 | | inaccessible pages | |
103 | +--------------------+ (stack base) + (soft stack rlimit) | | 103 | +--------------------+ (stack base) + (soft stack rlimit) |
104 | | . | | | 104 | | . | |
105 | | . | <-- stack pointer (varies during execution) | | 105 | | . | <-- stack pointer (varies during execution) |
106 | | . | | | 106 | | . | |
107 | | accessible pages | | | 107 | | accessible pages | |
108 | +--------------------+ stack base | | 108 | +--------------------+ stack base |
109 | | stack gap | | | 109 | | stack gap | |
110 | +--------------------+ USRSTACK | | 110 | +--------------------+ USRSTACK |
111 | .Ed | | 111 | .Ed |
112 | .Bl -bullet | | 112 | .Bl -bullet |
113 | .It | | 113 | .It |
114 | The | | 114 | The |
115 | .Em stack guard | | 115 | .Em stack guard |
116 | is allocated so that any access \(em read, write, or execute \(em will | | 116 | is allocated so that any access \(em read, write, or execute \(em will |
117 | deliver | | 117 | deliver |
118 | .Dv SIGSEGV | | 118 | .Dv SIGSEGV |
119 | to the process. | | 119 | to the process. |
120 | This serves to detect stack overflow and crash rather than silently | | 120 | This serves to detect stack overflow and crash rather than silently |
121 | overwrite other memory in the program's virtual address space. | | 121 | overwrite other memory in the program's virtual address space. |
122 | The size of the stack guard is tuned by the | | 122 | The size of the stack guard is tuned by the |
123 | .Li vm.guard_size | | 123 | .Li vm.guard_size |
124 | .Xr sysctl 7 | | 124 | .Xr sysctl 7 |
125 | knob. | | 125 | knob. |
126 | .Pp | | 126 | .Pp |
127 | The stack guard is also sometimes known as the | | 127 | The stack guard is also sometimes known as the |
128 | .Sq redzone | | 128 | .Sq redzone |
129 | or | | 129 | or |
130 | .Sq red zone , | | 130 | .Sq red zone , |
131 | although the term | | 131 | although the term |
132 | .Sq red zone | | 132 | .Sq red zone |
133 | is also sometimes used to mean a fixed space | | 133 | is also sometimes used to mean a fixed space |
134 | .Em above | | 134 | .Em above |
135 | the stack pointer (in the direction of stack growth) that the system | | 135 | the stack pointer (in the direction of stack growth) that the system |
136 | guarantees will it will not overwrite when calling a signal handler in | | 136 | guarantees will it will not overwrite when calling a signal handler in |
137 | the | | 137 | the |
138 | .Tn ABI | | 138 | .Tn ABI |
139 | of some architectures; see also | | 139 | of some architectures; see also |
140 | .Xr sigaltstack 2 | | 140 | .Xr sigaltstack 2 |
141 | to specify an alternate stack base for the kernel to use when invoking | | 141 | to specify an alternate stack base for the kernel to use when invoking |
142 | signal handlers on signal delivery. | | 142 | signal handlers on signal delivery. |
143 | .It | | 143 | .It |
144 | The | | 144 | The |
145 | .Em inaccessible pages | | 145 | .Em inaccessible pages |
146 | of the stack region are allocated so that any access will also deliver | | 146 | of the stack region are allocated so that any access will also deliver |
147 | .Dv SIGSEGV | | 147 | .Dv SIGSEGV |
148 | to the process, but they can be made accessible by changing the soft | | 148 | to the process, but they can be made accessible by changing the soft |
149 | stack rlimit with | | 149 | stack rlimit with |
150 | .Xr setrlimit 2 . | | 150 | .Xr setrlimit 2 . |
151 | .It | | 151 | .It |
152 | The | | 152 | The |
153 | .Em accessible pages | | 153 | .Em accessible pages |
154 | of the stack region are allocated with read/write access permitted, and | | 154 | of the stack region are allocated with read/write access permitted, and |
155 | are used to store the actual data in the program stack. | | 155 | are used to store the actual data in the program stack. |
156 | .It | | 156 | .It |
157 | When | | 157 | When |
158 | .Tn PaX ASLR , | | 158 | .Tn PaX ASLR , |
159 | address space layout randomization, is enabled, the | | 159 | address space layout randomization, is enabled, the |
160 | .Em stack gap | | 160 | .Em stack gap |
161 | is an | | 161 | is an |
162 | .Em unallocated | | 162 | .Em unallocated |
163 | space of a size chosen unpredictably at random at program startup time. | | 163 | space of a size chosen unpredictably at random at program startup time. |
164 | When | | 164 | When |
165 | .Tn PaX ASLR | | 165 | .Tn PaX ASLR |
166 | is disabled, the stack gap is empty. | | 166 | is disabled, the stack gap is empty. |
167 | .El | | 167 | .El |
168 | .Pp | | 168 | .Pp |
169 | All of the boundaries \(em | | 169 | All of the boundaries \(em |
170 | .Dv USRSTACK , | | 170 | .Dv USRSTACK , |
171 | the stack base, and the boundaries between the accessible, | | 171 | the stack base, and the boundaries between the accessible, |
172 | inaccessible, and guard pages \(em are page-aligned, or rounded to be | | 172 | inaccessible, and guard pages \(em are page-aligned, or rounded to be |
173 | page-aligned even if the rlimits are not themselves page-aligned, | | 173 | page-aligned even if the rlimits are not themselves page-aligned, |
174 | rounding so that the sizes of the regions do not exceed the rlimits. | | 174 | rounding so that the sizes of the regions do not exceed the rlimits. |
175 | .Pp | | 175 | .Pp |
176 | The stack base is exposed to programs via the | | 176 | The stack base is exposed to programs via the |
177 | .Dv AT_STACKBASE | | 177 | .Dv AT_STACKBASE |
178 | .Xr elf 5 | | 178 | .Xr elf 5 |
179 | auxiliary info vector entry. | | 179 | auxiliary info vector entry. |
180 | .Pp | | 180 | .Pp |
181 | The per-architecture constants | | 181 | The per-architecture constants |
182 | .Dv USRSTACK | | 182 | .Dv USRSTACK |
183 | and | | 183 | and |
184 | .Dv MAXSSIZ | | 184 | .Dv MAXSSIZ |
185 | are defined in | | 185 | are defined in |
186 | .In machine/vmparam.h . | | 186 | .In machine/vmparam.h . |
187 | .Ss Non-main threads | | 187 | .Ss Non-main threads |
188 | Threads created with | | 188 | Threads created with |
189 | .Xr pthread_create 3 | | 189 | .Xr pthread_create 3 |
190 | have stacks allocated at dynamically chosen addresses, and cannot be | | 190 | have stacks allocated at dynamically chosen addresses, and cannot be |
191 | resized after creation. | | 191 | resized after creation. |
192 | On architectures where the stack grows down, the layout is: | | 192 | On architectures where the stack grows down, the layout is: |
193 | .Bd -literal | | 193 | .Bd -literal |
194 | +--------------------+ stackaddr | | 194 | +--------------------+ stackaddr |
195 | | . | | | 195 | | . | |
196 | | . | <-- stack pointer (varies during execution) | | 196 | | . | <-- stack pointer (varies during execution) |
197 | | . | | | 197 | | . | |
198 | | stack | | | 198 | | stack | |
199 | +--------------------+ stackaddr - stacksize | | 199 | +--------------------+ stackaddr - stacksize |
200 | | guard/redzone | | | 200 | | guard/redzone | |
201 | +--------------------+ stackaddr - stacksize - guardsize | | 201 | +--------------------+ stackaddr - stacksize - guardsize |
202 | .Ed | | 202 | .Ed |
203 | .Pp | | 203 | .Pp |
204 | On architectures where the stack grows up, the layout is: | | 204 | On architectures where the stack grows up, the layout is: |
205 | .Bd -literal | | 205 | .Bd -literal |
206 | +--------------------+ stackaddr + stacksize + guardsize | | 206 | +--------------------+ stackaddr + stacksize + guardsize |
207 | | guard/redzone | | | 207 | | guard/redzone | |
208 | +--------------------+ stackaddr + stacksize | | 208 | +--------------------+ stackaddr + stacksize |
209 | | . | | | 209 | | . | |
210 | | . | <-- stack pointer (varies during execution) | | 210 | | . | <-- stack pointer (varies during execution) |
211 | | . | | | 211 | | . | |
212 | | stack | | | 212 | | stack | |
213 | +--------------------+ stackaddr | | 213 | +--------------------+ stackaddr |
214 | .Ed | | 214 | .Ed |
215 | .Pp | | 215 | .Pp |
216 | The parameters stackaddr, stacksize, and guardsize can be obtained from | | 216 | The parameters stackaddr, stacksize, and guardsize can be obtained from |
217 | an existing thread using | | 217 | an existing thread using |
218 | .Xr pthread_getattr_np 3 , | | 218 | .Xr pthread_getattr_np 3 , |
219 | .Xr pthread_attr_getguardsize 3 , | | 219 | .Xr pthread_attr_getguardsize 3 , |
220 | and the | | 220 | and the |
221 | .Xr pthread_attr_getstack 3 | | 221 | .Xr pthread_attr_getstack 3 |
222 | family of functions. | | 222 | family of functions. |
223 | .Pp | | 223 | .Pp |
224 | When creating a thread, the stack can be manually allocated and the | | 224 | When creating a thread, the stack can be manually allocated and the |
225 | parameters can be set using | | 225 | parameters can be set using |
226 | .Xr pthread_attr_setguardsize 3 | | 226 | .Xr pthread_attr_setguardsize 3 |
227 | and the | | 227 | and the |
228 | .Xr pthread_attr_setstack 3 | | 228 | .Xr pthread_attr_setstack 3 |
229 | family of functions. | | 229 | family of functions. |
230 | However, the stack parameters cannot be changed after thread creation. | | 230 | However, the stack parameters cannot be changed after thread creation. |
231 | The default guard size is tuned by the | | 231 | The default guard size is tuned by the |
232 | .Li vm.thread_guard_size | | 232 | .Li vm.thread_guard_size |
233 | .Xr sysctl 7 | | 233 | .Xr sysctl 7 |
234 | knob. | | 234 | knob. |
235 | .Pp | | 235 | .Pp |
236 | For the main thread, | | 236 | For the main thread, |
237 | .Xr pthread_getattr_np 3 | | 237 | .Xr pthread_getattr_np 3 |
238 | returns a | | 238 | returns a |
239 | .Em snapshot | | 239 | .Em snapshot |
240 | of the parameters as they existed at program startup, so that stackaddr | | 240 | of the parameters as they existed at program startup, so that stackaddr |
241 | and stacksize reflect the current accessible pages of the stack, and | | 241 | and stacksize reflect the current accessible pages of the stack, and |
242 | guardsize is the value of the | | 242 | guardsize is the value of the |
243 | .Li vm.guard_size | | 243 | .Li vm.guard_size |
244 | .Xr sysctl 7 | | 244 | .Xr sysctl 7 |
245 | knob at the time of program startup. | | 245 | knob at the time of program startup. |
| | | 246 | (Note that this means the |
| | | 247 | .Xr pthread 3 |
| | | 248 | view of the main thread's stack guard may not coincide with the actual |
| | | 249 | stack guard \(em it may overlap with, or lie entirely in, the |
| | | 250 | inaccessible pages of the stack reserved on program start.) |
246 | However, if the program changes its soft stack rlimit with | | 251 | However, if the program changes its soft stack rlimit with |
247 | .Xr setrlimit 2 , | | 252 | .Xr setrlimit 2 , |
248 | this snapshot may become stale. | | 253 | this snapshot may become stale. |
249 | .Sh SEE ALSO | | 254 | .Sh SEE ALSO |
250 | .Xr execve 2 , | | 255 | .Xr execve 2 , |
251 | .Xr mmap 2 , | | 256 | .Xr mmap 2 , |
252 | .Xr mprotect 2 , | | 257 | .Xr mprotect 2 , |
253 | .Xr sigaltstack 2 , | | 258 | .Xr sigaltstack 2 , |
254 | .Xr ucontext 2 , | | 259 | .Xr ucontext 2 , |
255 | .Xr posix_spawn 3 , | | 260 | .Xr posix_spawn 3 , |
256 | .Xr pthread 3 , | | 261 | .Xr pthread 3 , |
257 | .Xr security 7 , | | 262 | .Xr security 7 , |
258 | .Xr sysctl 7 , | | 263 | .Xr sysctl 7 , |
259 | .Xr paxctl 8 | | 264 | .Xr paxctl 8 |
260 | .Sh BUGS | | 265 | .Sh BUGS |
261 | .Tn PaX ASLR | | 266 | .Tn PaX ASLR |
262 | doesn't actually guarantee an accessible stack reservation of length | | 267 | doesn't actually guarantee an accessible stack reservation of length |
263 | equal to the soft stack rlimit \(em owing to a bug (XXX which PR | | 268 | equal to the soft stack rlimit \(em owing to a bug (XXX which PR |
264 | number?), | | 269 | number?), |
265 | .Nx | | 270 | .Nx |
266 | may sometimes reserve less space than the soft rlimit, in which case | | 271 | may sometimes reserve less space than the soft rlimit, in which case |
267 | the accessible pages of the stack cannot be extended. | | 272 | the accessible pages of the stack cannot be extended. |
268 | .Pp | | 273 | .Pp |
269 | There is a race between the kernel's access of | | 274 | There is a race between the kernel's access of |
270 | .Li vm.guard_size | | 275 | .Li vm.guard_size |
271 | at exec time, and userland's access of | | 276 | at exec time, and userland's access of |
272 | .Li vm.guard_size | | 277 | .Li vm.guard_size |
273 | in | | 278 | in |
274 | .Xr pthread 3 | | 279 | .Xr pthread 3 |
275 | initialization. | | 280 | initialization. |