Linux Manual Pages development
 help / color / mirror / Atom feed
* [PATCH] man/man2/mmap.2: Document when MAP_GROWSDOWN does/doesn't trigger growth
@ 2026-04-23 16:44 Ben Kallus
  2026-05-04 13:00 ` Alejandro Colomar
  0 siblings, 1 reply; 2+ messages in thread
From: Ben Kallus @ 2026-04-23 16:44 UTC (permalink / raw)
  To: alx; +Cc: linux-man, Ben Kallus

The man page states that MAP_GROWSDOWN can only cause a mapping to
grow by a single page.  This is incorrect; mappings can grow by many
pages at a time, until reaching either the stack size limit or growing
too close to another mapping.

To observe that mappings can grow by more than one page, and that they
are limited by the stack size limit, run the following C program with a
stack size limit of 0x800000 bytes, and then again with a stack size limit
of 0x801000 bytes, and observe that it segfaults as the comments describe.

> struct page {
>     char data[4096];
> };
> static_assert(sizeof(struct page) == 4096);
>
> void *const BASE_ADDRESS = (void *)0xabcdef000;
>
> int main(int const argc, char const * const * const argv) {
>     volatile struct page *p = mmap(
>         BASE_ADDRESS,
>         1,
>         PROT_READ | PROT_WRITE,
>         MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN | MAP_FIXED_NOREPLACE,
>         -1,
>         0
>     );
>                              // stack_limit=0x800000 // stack_limit=0x801000
>     (p - 2047)->data[0] = 0; // no segfault          // no segfault
>     (p - 2048)->data[0] = 0; // segfault             // no segfault
>     (p - 2049)->data[0] = 0; // segfault             // segfault
> }

To observe that mappings stop growing when they get within 256 pages of
the next lower mapping (instead of a single page, as the man page
currently states), run the following program, and observe that it
segfaults as the comments describe.

> struct page {
>     char data[4096];
> };
> static_assert(sizeof(struct page) == 4096);
>
> struct page *const BASE_ADDRESS = (void *)0xabcdef000;
>
> int main(int const argc, char const * const * const argv) {
>     volatile struct page *p = mmap(
>         BASE_ADDRESS,
>         1,
>         PROT_READ | PROT_WRITE,
>         MAP_ANONYMOUS | MAP_PRIVATE | MAP_GROWSDOWN | MAP_FIXED_NOREPLACE,
>         -1,
>         0
>     );
>
>     struct page *p2 = mmap(
>         BASE_ADDRESS - 258,
>         1,
>         PROT_READ | PROT_WRITE,
>         MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED_NOREPLACE,
>         -1,
>         0
>     );
>
>     // no segfault (causes p to grow by a page)
>     (p - 1)->data[0] = 0;
>
>     // unmap the test page
>     munmap(p2, 1);
>
>     // unmap the new page from p growing
>     munmap((struct page *)p - 1, 1);
>
>     struct page *p3 = mmap(
>         BASE_ADDRESS - 257,
>         1,
>         PROT_READ | PROT_WRITE,
>         MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED_NOREPLACE,
>         -1,
>         0
>     );
>
>     // segfault because p can't grow due to proximity to p3
>     (p - 1)->data[0] = 0;
> }

Fixes: 176b1a76 (2016-11-21; "mmap.2: Add (much) more detail on MAP_GROWSDOWN")
Signed-off-by: Ben Kallus <benjamin.p.kallus.gr@dartmouth.edu>
---
 man/man2/mmap.2 | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/man/man2/mmap.2 b/man/man2/mmap.2
index 20b94c243..925b18ffc 100644
--- a/man/man2/mmap.2
+++ b/man/man2/mmap.2
@@ -276,11 +276,11 @@ should check the returned address against the requested address.
 This flag is used for stacks.
 It indicates to the kernel virtual memory system that the mapping
 should extend downward in memory.
-Touching an address in the "guard" page below the mapping will cause
-the mapping to grow by a page.
-This growth can be repeated until the mapping grows to within a
-page of the high end of the next lower mapping,
-at which point touching the "guard" page will result in a
+Touching an address below the mapping will cause the mapping to grow to
+accommodate the access.
+This growth can be repeated until the mapping crosses the stack size limit,
+or grows to within 256 pages of the high end of the next lower mapping,
+at which point accessing below the mapping will result in a
 .B SIGSEGV
 signal.
 .TP
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-05-04 13:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-23 16:44 [PATCH] man/man2/mmap.2: Document when MAP_GROWSDOWN does/doesn't trigger growth Ben Kallus
2026-05-04 13:00 ` Alejandro Colomar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox