aboutsummaryrefslogtreecommitdiff
path: root/nptl/allocatestack.c
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2025-09-08 13:06:13 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2025-09-23 10:33:49 -0300
commit18fd689cdced8348e42991964557cddea0ba2dc5 (patch)
treef2b40065430ac18fea01909898d7754a6faefb17 /nptl/allocatestack.c
parent46b4e37c9e0619d0cf065ba207c29996b326a06f (diff)
downloadglibc-release/2.42/master.zip
glibc-release/2.42/master.tar.gz
glibc-release/2.42/master.tar.bz2
nptl: Fix MADV_GUARD_INSTALL logic for thread without guard page (BZ 33356)release/2.42/master
The main issue is that setup_stack_prot fails to account for cases where the cached thread stack lacks a guard page, which can cause madvise to fail. Update the logic to also handle whether MADV_GUARD_INSTALL is supported when resizing the guard page. Checked on x86_64-linux-gnu with 6.8.0 and 6.15 kernels. Reviewed-by: Florian Weimer <fweimer@redhat.com> (cherry picked from commit 855bfa2566bbefefa27c516b344df58a75824a5c)
Diffstat (limited to 'nptl/allocatestack.c')
-rw-r--r--nptl/allocatestack.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c
index 800ca89..fb8a60a 100644
--- a/nptl/allocatestack.c
+++ b/nptl/allocatestack.c
@@ -240,7 +240,7 @@ setup_stack_prot (char *mem, size_t size, struct pthread *pd,
/* Update the guard area of the thread stack MEM of size SIZE with the new
GUARDISZE. It uses the method defined by PD stack_mode. */
static inline bool
-adjust_stack_prot (char *mem, size_t size, const struct pthread *pd,
+adjust_stack_prot (char *mem, size_t size, struct pthread *pd,
size_t guardsize, size_t pagesize_m1)
{
/* The required guard area is larger than the current one. For
@@ -258,11 +258,23 @@ adjust_stack_prot (char *mem, size_t size, const struct pthread *pd,
so use the new guard placement with the new size. */
if (guardsize > pd->guardsize)
{
+ /* There was no need to previously setup a guard page, so we need
+ to check whether the kernel supports guard advise. */
char *guard = guard_position (mem, size, guardsize, pd, pagesize_m1);
- if (pd->stack_mode == ALLOCATE_GUARD_MADV_GUARD)
- return __madvise (guard, guardsize, MADV_GUARD_INSTALL) == 0;
- else if (pd->stack_mode == ALLOCATE_GUARD_PROT_NONE)
- return __mprotect (guard, guardsize, PROT_NONE) == 0;
+ if (atomic_load_relaxed (&allocate_stack_mode)
+ == ALLOCATE_GUARD_MADV_GUARD)
+ {
+ if (__madvise (guard, guardsize, MADV_GUARD_INSTALL) == 0)
+ {
+ pd->stack_mode = ALLOCATE_GUARD_MADV_GUARD;
+ return true;
+ }
+ atomic_store_relaxed (&allocate_stack_mode,
+ ALLOCATE_GUARD_PROT_NONE);
+ }
+
+ pd->stack_mode = ALLOCATE_GUARD_PROT_NONE;
+ return __mprotect (guard, guardsize, PROT_NONE) == 0;
}
/* The current guard area is larger than the required one. For
_STACK_GROWS_DOWN is means change the guard as: