Thu Nov 23 21:27:08 2023 UTC ()
stack(7): Clarify thread stack guard vs program stack guard.

Just in case this confuses anyone dealing with PR pkg/57708.

XXX pullup-10


(riastradh)
diff -r1.1 -r1.2 src/share/man/man7/stack.7

cvs diff -r1.1 -r1.2 src/share/man/man7/stack.7 (switch to unified diff)

--- src/share/man/man7/stack.7 2023/11/23 21:20:49 1.1
+++ src/share/man/man7/stack.7 2023/11/23 21:27:08 1.2
@@ -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
34When executing a program, with the 34When executing a program, with the
35.Xr execve 2 35.Xr execve 2
36or 36or
37.Xr posix_spawn 3 37.Xr posix_spawn 3
38families of system calls, 38families of system calls,
39.Nx 39.Nx
40reserves a region in the new program image's virtual address space for 40reserves a region in the new program image's virtual address space for
41the 41the
42.Em stack , 42.Em stack ,
43which stores return addresses and local variables for nested procedure 43which stores return addresses and local variables for nested procedure
44calls in program execution. 44calls in program execution.
45Similarly, threads created with 45Similarly, threads created with
46.Xr pthread_create 3 46.Xr pthread_create 3
47have regions allocated for per-thread stacks. 47have regions allocated for per-thread stacks.
48.Pp 48.Pp
49The stack grows from the 49The stack grows from the
50.Em base , 50.Em base ,
51where information of the outermost procedure call is stored, fixed at 51where information of the outermost procedure call is stored, fixed at
52program start, to the 52program start, to the
53.Em stack pointer , 53.Em stack pointer ,
54a 54a
55.Tn CPU 55.Tn CPU
56register that points to information used by the current procedure call, 56register that points to information used by the current procedure call,
57varying during execution as procedures are called. 57varying during execution as procedures are called.
58.Pp 58.Pp
59On most architectures, the stack base is at higher-numbered virtual 59On most architectures, the stack base is at higher-numbered virtual
60addresses and the stack pointer is at lower-numbered virtual addresses 60addresses 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 .
63On some other architectures, notably 63On some other architectures, notably
64.Tn HP PA-RISC 64.Tn HP PA-RISC
65.Pq Sq hppa , 65.Pq Sq hppa ,
66the stack base is at lower-numbered virtual addresses and the stack 66the stack base is at lower-numbered virtual addresses and the stack
67pointer is at higher-numbered virtual addresses, so on those 67pointer is at higher-numbered virtual addresses, so on those
68architectures 68architectures
69.Em the stack grows up . 69.Em the stack grows up .
70.Pp 70.Pp
71In the kernel, the C preprocessor macro 71In the kernel, the C preprocessor macro
72.Dv __HAVE_MACHINE_STACK_GROWS_UP 72.Dv __HAVE_MACHINE_STACK_GROWS_UP
73is defined in 73is defined in
74.In machine/types.h 74.In machine/types.h
75on architectures where the stack grows up. 75on architectures where the stack grows up.
76.Ss Main thread 76.Ss Main thread
77For single-threaded programs, and for the main thread of multi-threaded 77For single-threaded programs, and for the main thread of multi-threaded
78programs, 78programs,
79.Nx 79.Nx
80reserves virtual addresses as follows on architectures where the stack 80reserves virtual addresses as follows on architectures where the stack
81grows down: 81grows 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
97On architectures where the stack grows up, the layout is: 97On 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
114The 114The
115.Em stack guard 115.Em stack guard
116is allocated so that any access \(em read, write, or execute \(em will 116is allocated so that any access \(em read, write, or execute \(em will
117deliver 117deliver
118.Dv SIGSEGV 118.Dv SIGSEGV
119to the process. 119to the process.
120This serves to detect stack overflow and crash rather than silently 120This serves to detect stack overflow and crash rather than silently
121overwrite other memory in the program's virtual address space. 121overwrite other memory in the program's virtual address space.
122The size of the stack guard is tuned by the 122The 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
125knob. 125knob.
126.Pp 126.Pp
127The stack guard is also sometimes known as the 127The stack guard is also sometimes known as the
128.Sq redzone 128.Sq redzone
129or 129or
130.Sq red zone , 130.Sq red zone ,
131although the term 131although the term
132.Sq red zone 132.Sq red zone
133is also sometimes used to mean a fixed space 133is also sometimes used to mean a fixed space
134.Em above 134.Em above
135the stack pointer (in the direction of stack growth) that the system 135the stack pointer (in the direction of stack growth) that the system
136guarantees will it will not overwrite when calling a signal handler in 136guarantees will it will not overwrite when calling a signal handler in
137the 137the
138.Tn ABI 138.Tn ABI
139of some architectures; see also 139of some architectures; see also
140.Xr sigaltstack 2 140.Xr sigaltstack 2
141to specify an alternate stack base for the kernel to use when invoking 141to specify an alternate stack base for the kernel to use when invoking
142signal handlers on signal delivery. 142signal handlers on signal delivery.
143.It 143.It
144The 144The
145.Em inaccessible pages 145.Em inaccessible pages
146of the stack region are allocated so that any access will also deliver 146of the stack region are allocated so that any access will also deliver
147.Dv SIGSEGV 147.Dv SIGSEGV
148to the process, but they can be made accessible by changing the soft 148to the process, but they can be made accessible by changing the soft
149stack rlimit with 149stack rlimit with
150.Xr setrlimit 2 . 150.Xr setrlimit 2 .
151.It 151.It
152The 152The
153.Em accessible pages 153.Em accessible pages
154of the stack region are allocated with read/write access permitted, and 154of the stack region are allocated with read/write access permitted, and
155are used to store the actual data in the program stack. 155are used to store the actual data in the program stack.
156.It 156.It
157When 157When
158.Tn PaX ASLR , 158.Tn PaX ASLR ,
159address space layout randomization, is enabled, the 159address space layout randomization, is enabled, the
160.Em stack gap 160.Em stack gap
161is an 161is an
162.Em unallocated 162.Em unallocated
163space of a size chosen unpredictably at random at program startup time. 163space of a size chosen unpredictably at random at program startup time.
164When 164When
165.Tn PaX ASLR 165.Tn PaX ASLR
166is disabled, the stack gap is empty. 166is disabled, the stack gap is empty.
167.El 167.El
168.Pp 168.Pp
169All of the boundaries \(em 169All of the boundaries \(em
170.Dv USRSTACK , 170.Dv USRSTACK ,
171the stack base, and the boundaries between the accessible, 171the stack base, and the boundaries between the accessible,
172inaccessible, and guard pages \(em are page-aligned, or rounded to be 172inaccessible, and guard pages \(em are page-aligned, or rounded to be
173page-aligned even if the rlimits are not themselves page-aligned, 173page-aligned even if the rlimits are not themselves page-aligned,
174rounding so that the sizes of the regions do not exceed the rlimits. 174rounding so that the sizes of the regions do not exceed the rlimits.
175.Pp 175.Pp
176The stack base is exposed to programs via the 176The stack base is exposed to programs via the
177.Dv AT_STACKBASE 177.Dv AT_STACKBASE
178.Xr elf 5 178.Xr elf 5
179auxiliary info vector entry. 179auxiliary info vector entry.
180.Pp 180.Pp
181The per-architecture constants 181The per-architecture constants
182.Dv USRSTACK 182.Dv USRSTACK
183and 183and
184.Dv MAXSSIZ 184.Dv MAXSSIZ
185are defined in 185are defined in
186.In machine/vmparam.h . 186.In machine/vmparam.h .
187.Ss Non-main threads 187.Ss Non-main threads
188Threads created with 188Threads created with
189.Xr pthread_create 3 189.Xr pthread_create 3
190have stacks allocated at dynamically chosen addresses, and cannot be 190have stacks allocated at dynamically chosen addresses, and cannot be
191resized after creation. 191resized after creation.
192On architectures where the stack grows down, the layout is: 192On 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
204On architectures where the stack grows up, the layout is: 204On 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
216The parameters stackaddr, stacksize, and guardsize can be obtained from 216The parameters stackaddr, stacksize, and guardsize can be obtained from
217an existing thread using 217an 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 ,
220and the 220and the
221.Xr pthread_attr_getstack 3 221.Xr pthread_attr_getstack 3
222family of functions. 222family of functions.
223.Pp 223.Pp
224When creating a thread, the stack can be manually allocated and the 224When creating a thread, the stack can be manually allocated and the
225parameters can be set using 225parameters can be set using
226.Xr pthread_attr_setguardsize 3 226.Xr pthread_attr_setguardsize 3
227and the 227and the
228.Xr pthread_attr_setstack 3 228.Xr pthread_attr_setstack 3
229family of functions. 229family of functions.
230However, the stack parameters cannot be changed after thread creation. 230However, the stack parameters cannot be changed after thread creation.
231The default guard size is tuned by the 231The 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
234knob. 234knob.
235.Pp 235.Pp
236For the main thread, 236For the main thread,
237.Xr pthread_getattr_np 3 237.Xr pthread_getattr_np 3
238returns a 238returns a
239.Em snapshot 239.Em snapshot
240of the parameters as they existed at program startup, so that stackaddr 240of the parameters as they existed at program startup, so that stackaddr
241and stacksize reflect the current accessible pages of the stack, and 241and stacksize reflect the current accessible pages of the stack, and
242guardsize is the value of the 242guardsize is the value of the
243.Li vm.guard_size 243.Li vm.guard_size
244.Xr sysctl 7 244.Xr sysctl 7
245knob at the time of program startup. 245knob at the time of program startup.
 246(Note that this means the
 247.Xr pthread 3
 248view of the main thread's stack guard may not coincide with the actual
 249stack guard \(em it may overlap with, or lie entirely in, the
 250inaccessible pages of the stack reserved on program start.)
246However, if the program changes its soft stack rlimit with 251However, if the program changes its soft stack rlimit with
247.Xr setrlimit 2 , 252.Xr setrlimit 2 ,
248this snapshot may become stale. 253this 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
262doesn't actually guarantee an accessible stack reservation of length 267doesn't actually guarantee an accessible stack reservation of length
263equal to the soft stack rlimit \(em owing to a bug (XXX which PR 268equal to the soft stack rlimit \(em owing to a bug (XXX which PR
264number?), 269number?),
265.Nx 270.Nx
266may sometimes reserve less space than the soft rlimit, in which case 271may sometimes reserve less space than the soft rlimit, in which case
267the accessible pages of the stack cannot be extended. 272the accessible pages of the stack cannot be extended.
268.Pp 273.Pp
269There is a race between the kernel's access of 274There is a race between the kernel's access of
270.Li vm.guard_size 275.Li vm.guard_size
271at exec time, and userland's access of 276at exec time, and userland's access of
272.Li vm.guard_size 277.Li vm.guard_size
273in 278in
274.Xr pthread 3 279.Xr pthread 3
275initialization. 280initialization.