xref: /netbsd-src/share/man/man7/stack.7 (revision 4fcf94919aae7826a59ef7f32be39e6304120ca3)
1*4fcf9491Sriastradh.\"	$NetBSD: stack.7,v 1.6 2023/12/07 17:24:22 riastradh Exp $
2001acc2fSriastradh.\"
3001acc2fSriastradh.\" Copyright (c) 2023 The NetBSD Foundation, Inc.
4001acc2fSriastradh.\" All rights reserved.
5001acc2fSriastradh.\"
6001acc2fSriastradh.\" Redistribution and use in source and binary forms, with or without
7001acc2fSriastradh.\" modification, are permitted provided that the following conditions
8001acc2fSriastradh.\" are met:
9001acc2fSriastradh.\" 1. Redistributions of source code must retain the above copyright
10001acc2fSriastradh.\"    notice, this list of conditions and the following disclaimer.
11001acc2fSriastradh.\" 2. Redistributions in binary form must reproduce the above copyright
12001acc2fSriastradh.\"    notice, this list of conditions and the following disclaimer in the
13001acc2fSriastradh.\"    documentation and/or other materials provided with the distribution.
14001acc2fSriastradh.\"
15001acc2fSriastradh.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16001acc2fSriastradh.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17001acc2fSriastradh.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18001acc2fSriastradh.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19001acc2fSriastradh.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20001acc2fSriastradh.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21001acc2fSriastradh.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22001acc2fSriastradh.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23001acc2fSriastradh.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24001acc2fSriastradh.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25001acc2fSriastradh.\" POSSIBILITY OF SUCH DAMAGE.
26001acc2fSriastradh.\"
27001acc2fSriastradh.Dd November 23, 2023
28001acc2fSriastradh.Dt STACK 7
29001acc2fSriastradh.Os
30001acc2fSriastradh.Sh NAME
31001acc2fSriastradh.Nm stack
32001acc2fSriastradh.Nd layout of program execution stack memory
33001acc2fSriastradh.Sh DESCRIPTION
34001acc2fSriastradhWhen executing a program, with the
35001acc2fSriastradh.Xr execve 2
36001acc2fSriastradhor
37001acc2fSriastradh.Xr posix_spawn 3
38001acc2fSriastradhfamilies of system calls,
39001acc2fSriastradh.Nx
40001acc2fSriastradhreserves a region in the new program image's virtual address space for
41001acc2fSriastradhthe
42001acc2fSriastradh.Em stack ,
43001acc2fSriastradhwhich stores return addresses and local variables for nested procedure
44001acc2fSriastradhcalls in program execution.
45001acc2fSriastradhSimilarly, threads created with
46001acc2fSriastradh.Xr pthread_create 3
47001acc2fSriastradhhave regions allocated for per-thread stacks.
48001acc2fSriastradh.Pp
49001acc2fSriastradhThe stack grows from the
50001acc2fSriastradh.Em base ,
51001acc2fSriastradhwhere information of the outermost procedure call is stored, fixed at
52001acc2fSriastradhprogram start, to the
53001acc2fSriastradh.Em stack pointer ,
54001acc2fSriastradha
55001acc2fSriastradh.Tn CPU
56001acc2fSriastradhregister that points to information used by the current procedure call,
57001acc2fSriastradhvarying during execution as procedures are called.
58001acc2fSriastradh.Pp
59001acc2fSriastradhOn most architectures, the stack base is at higher-numbered virtual
60001acc2fSriastradhaddresses and the stack pointer is at lower-numbered virtual addresses
61001acc2fSriastradh\(em on these architectures,
62001acc2fSriastradh.Em the stack grows down .
63001acc2fSriastradhOn some other architectures, notably
64001acc2fSriastradh.Tn HP PA-RISC
65001acc2fSriastradh.Pq Sq hppa ,
66001acc2fSriastradhthe stack base is at lower-numbered virtual addresses and the stack
67001acc2fSriastradhpointer is at higher-numbered virtual addresses, so on those
68001acc2fSriastradharchitectures
69001acc2fSriastradh.Em the stack grows up .
70001acc2fSriastradh.Pp
71001acc2fSriastradhIn the kernel, the C preprocessor macro
72001acc2fSriastradh.Dv __HAVE_MACHINE_STACK_GROWS_UP
73001acc2fSriastradhis defined in
74001acc2fSriastradh.In machine/types.h
75001acc2fSriastradhon architectures where the stack grows up.
76001acc2fSriastradh.Ss Main thread
77001acc2fSriastradhFor single-threaded programs, and for the main thread of multi-threaded
78001acc2fSriastradhprograms,
79001acc2fSriastradh.Nx
80001acc2fSriastradhreserves virtual addresses as follows on architectures where the stack
81001acc2fSriastradhgrows down:
82001acc2fSriastradh.Bd -literal
83001acc2fSriastradh+--------------------+ USRSTACK
84001acc2fSriastradh| stack gap          |
85001acc2fSriastradh+--------------------+ stack base
863c3bf573Sriastradh| accessible pages   |
87001acc2fSriastradh| .                  |
88001acc2fSriastradh| .                  | <-- stack pointer (varies during execution)
89001acc2fSriastradh| .                  |
90001acc2fSriastradh+--------------------+ (stack base) - (soft stack rlimit)
913c3bf573Sriastradh| inaccessible pages |
92001acc2fSriastradh+--------------------+ (stack base) - (hard stack rlimit)
93001acc2fSriastradh| guard/redzone      |
94001acc2fSriastradh+--------------------+ USRSTACK - MAXSSIZ
95001acc2fSriastradh.Ed
96001acc2fSriastradh.Pp
97001acc2fSriastradhOn architectures where the stack grows up, the layout is:
98001acc2fSriastradh.Bd -literal
99001acc2fSriastradh+--------------------+ USRSTACK + MAXSSIZ
100001acc2fSriastradh| guard/redzone      |
101001acc2fSriastradh+--------------------+ (stack base) + (hard stack rlimit)
102001acc2fSriastradh| inaccessible pages |
103001acc2fSriastradh+--------------------+ (stack base) + (soft stack rlimit)
104001acc2fSriastradh| .                  |
105001acc2fSriastradh| .                  | <-- stack pointer (varies during execution)
106001acc2fSriastradh| .                  |
107001acc2fSriastradh| accessible pages   |
108001acc2fSriastradh+--------------------+ stack base
109001acc2fSriastradh| stack gap          |
110001acc2fSriastradh+--------------------+ USRSTACK
111001acc2fSriastradh.Ed
112001acc2fSriastradh.Bl -bullet
113001acc2fSriastradh.It
114001acc2fSriastradhThe
115001acc2fSriastradh.Em stack guard
116001acc2fSriastradhis allocated so that any access \(em read, write, or execute \(em will
117001acc2fSriastradhdeliver
118001acc2fSriastradh.Dv SIGSEGV
119001acc2fSriastradhto the process.
120001acc2fSriastradhThis serves to detect stack overflow and crash rather than silently
121001acc2fSriastradhoverwrite other memory in the program's virtual address space.
122001acc2fSriastradhThe size of the stack guard is tuned by the
123001acc2fSriastradh.Li vm.guard_size
124001acc2fSriastradh.Xr sysctl 7
125001acc2fSriastradhknob.
126001acc2fSriastradh.Pp
127001acc2fSriastradhThe stack guard is also sometimes known as the
128001acc2fSriastradh.Sq redzone
129001acc2fSriastradhor
130001acc2fSriastradh.Sq red zone ,
131001acc2fSriastradhalthough the term
132001acc2fSriastradh.Sq red zone
133001acc2fSriastradhis also sometimes used to mean a fixed space
134001acc2fSriastradh.Em above
135001acc2fSriastradhthe stack pointer (in the direction of stack growth) that the system
136f1d67e98Sriastradhguarantees it will not overwrite when calling a signal handler in the
137001acc2fSriastradh.Tn ABI
138001acc2fSriastradhof some architectures; see also
139001acc2fSriastradh.Xr sigaltstack 2
140001acc2fSriastradhto specify an alternate stack base for the kernel to use when invoking
141001acc2fSriastradhsignal handlers on signal delivery.
142001acc2fSriastradh.It
143001acc2fSriastradhThe
144001acc2fSriastradh.Em inaccessible pages
145001acc2fSriastradhof the stack region are allocated so that any access will also deliver
146001acc2fSriastradh.Dv SIGSEGV
147001acc2fSriastradhto the process, but they can be made accessible by changing the soft
148001acc2fSriastradhstack rlimit with
149001acc2fSriastradh.Xr setrlimit 2 .
150001acc2fSriastradh.It
151001acc2fSriastradhThe
152001acc2fSriastradh.Em accessible pages
153001acc2fSriastradhof the stack region are allocated with read/write access permitted, and
154001acc2fSriastradhare used to store the actual data in the program stack.
155001acc2fSriastradh.It
156001acc2fSriastradhWhen
157001acc2fSriastradh.Tn PaX ASLR ,
158001acc2fSriastradhaddress space layout randomization, is enabled, the
159001acc2fSriastradh.Em stack gap
160001acc2fSriastradhis an
161001acc2fSriastradh.Em unallocated
162001acc2fSriastradhspace of a size chosen unpredictably at random at program startup time.
163001acc2fSriastradhWhen
164001acc2fSriastradh.Tn PaX ASLR
165001acc2fSriastradhis disabled, the stack gap is empty.
166001acc2fSriastradh.El
167001acc2fSriastradh.Pp
168001acc2fSriastradhAll of the boundaries \(em
169001acc2fSriastradh.Dv USRSTACK ,
170001acc2fSriastradhthe stack base, and the boundaries between the accessible,
171001acc2fSriastradhinaccessible, and guard pages \(em are page-aligned, or rounded to be
172001acc2fSriastradhpage-aligned even if the rlimits are not themselves page-aligned,
173001acc2fSriastradhrounding so that the sizes of the regions do not exceed the rlimits.
174001acc2fSriastradh.Pp
175001acc2fSriastradhThe stack base is exposed to programs via the
176001acc2fSriastradh.Dv AT_STACKBASE
177001acc2fSriastradh.Xr elf 5
178001acc2fSriastradhauxiliary info vector entry.
179001acc2fSriastradh.Pp
180001acc2fSriastradhThe per-architecture constants
181001acc2fSriastradh.Dv USRSTACK
182001acc2fSriastradhand
183001acc2fSriastradh.Dv MAXSSIZ
184001acc2fSriastradhare defined in
185001acc2fSriastradh.In machine/vmparam.h .
186001acc2fSriastradh.Ss Non-main threads
187001acc2fSriastradhThreads created with
188001acc2fSriastradh.Xr pthread_create 3
189f1d67e98Sriastradhhave stacks allocated at dynamically chosen addresses outside the main
190f1d67e98Sriastradhthread's stack region by default, and their stacks cannot be resized
191f1d67e98Sriastradhafter creation.
192001acc2fSriastradhOn architectures where the stack grows down, the layout is:
193001acc2fSriastradh.Bd -literal
194*4fcf9491Sriastradh+--------------------+ stack base = stackaddr + stacksize + guardsize
195bfb59bbaSriastradh| stack              |
196001acc2fSriastradh| .                  |
197001acc2fSriastradh| .                  | <-- stack pointer (varies during execution)
198001acc2fSriastradh| .                  |
199*4fcf9491Sriastradh+--------------------+ stackaddr
200001acc2fSriastradh| guard/redzone      |
201*4fcf9491Sriastradh+--------------------+ stackaddr - guardsize
202001acc2fSriastradh.Ed
203001acc2fSriastradh.Pp
204001acc2fSriastradhOn architectures where the stack grows up, the layout is:
205001acc2fSriastradh.Bd -literal
206001acc2fSriastradh+--------------------+ stackaddr + stacksize + guardsize
207001acc2fSriastradh| guard/redzone      |
208001acc2fSriastradh+--------------------+ stackaddr + stacksize
209001acc2fSriastradh| .                  |
210001acc2fSriastradh| .                  | <-- stack pointer (varies during execution)
211001acc2fSriastradh| .                  |
212001acc2fSriastradh| stack              |
213*4fcf9491Sriastradh+--------------------+ stack base = stackaddr
214001acc2fSriastradh.Ed
215001acc2fSriastradh.Pp
216001acc2fSriastradhThe parameters stackaddr, stacksize, and guardsize can be obtained from
217001acc2fSriastradhan existing thread using
218001acc2fSriastradh.Xr pthread_getattr_np 3 ,
219001acc2fSriastradh.Xr pthread_attr_getguardsize 3 ,
220001acc2fSriastradhand the
221001acc2fSriastradh.Xr pthread_attr_getstack 3
222001acc2fSriastradhfamily of functions.
223001acc2fSriastradh.Pp
224001acc2fSriastradhWhen creating a thread, the stack can be manually allocated and the
225001acc2fSriastradhparameters can be set using
226001acc2fSriastradh.Xr pthread_attr_setguardsize 3
227001acc2fSriastradhand the
228001acc2fSriastradh.Xr pthread_attr_setstack 3
229001acc2fSriastradhfamily of functions.
230001acc2fSriastradhHowever, the stack parameters cannot be changed after thread creation.
231001acc2fSriastradhThe default guard size is tuned by the
232001acc2fSriastradh.Li vm.thread_guard_size
233001acc2fSriastradh.Xr sysctl 7
234001acc2fSriastradhknob.
235001acc2fSriastradh.Pp
236001acc2fSriastradhFor the main thread,
237001acc2fSriastradh.Xr pthread_getattr_np 3
238001acc2fSriastradhreturns a
239001acc2fSriastradh.Em snapshot
240001acc2fSriastradhof the parameters as they existed at program startup, so that stackaddr
241001acc2fSriastradhand stacksize reflect the current accessible pages of the stack, and
242001acc2fSriastradhguardsize is the value of the
243001acc2fSriastradh.Li vm.guard_size
244001acc2fSriastradh.Xr sysctl 7
245001acc2fSriastradhknob at the time of program startup.
246f1d67e98Sriastradh.Po
247f1d67e98SriastradhNote that this means the
248623621d6Sriastradh.Xr pthread 3
249623621d6Sriastradhview of the main thread's stack guard may not coincide with the actual
250623621d6Sriastradhstack guard \(em it may overlap with, or lie entirely in, the
251f1d67e98Sriastradhinaccessible pages of the stack reserved on program start.
252f1d67e98Sriastradh.Pc
253001acc2fSriastradhHowever, if the program changes its soft stack rlimit with
254001acc2fSriastradh.Xr setrlimit 2 ,
255001acc2fSriastradhthis snapshot may become stale.
256001acc2fSriastradh.Sh SEE ALSO
257001acc2fSriastradh.Xr execve 2 ,
258001acc2fSriastradh.Xr mmap 2 ,
259001acc2fSriastradh.Xr mprotect 2 ,
260001acc2fSriastradh.Xr sigaltstack 2 ,
261001acc2fSriastradh.Xr ucontext 2 ,
262001acc2fSriastradh.Xr posix_spawn 3 ,
263001acc2fSriastradh.Xr pthread 3 ,
264001acc2fSriastradh.Xr security 7 ,
265001acc2fSriastradh.Xr sysctl 7 ,
266001acc2fSriastradh.Xr paxctl 8
267001acc2fSriastradh.Sh BUGS
268001acc2fSriastradh.Tn PaX ASLR
269001acc2fSriastradhdoesn't actually guarantee an accessible stack reservation of length
270001acc2fSriastradhequal to the soft stack rlimit \(em owing to a bug (XXX which PR
271001acc2fSriastradhnumber?),
272001acc2fSriastradh.Nx
273001acc2fSriastradhmay sometimes reserve less space than the soft rlimit, in which case
274001acc2fSriastradhthe accessible pages of the stack cannot be extended.
275001acc2fSriastradh.Pp
276001acc2fSriastradhThere is a race between the kernel's access of
277001acc2fSriastradh.Li vm.guard_size
278001acc2fSriastradhat exec time, and userland's access of
279001acc2fSriastradh.Li vm.guard_size
280001acc2fSriastradhin
281001acc2fSriastradh.Xr pthread 3
282001acc2fSriastradhinitialization.
283