htl: Respect GL(dl_stack_flags) when allocating stacks

Previously, HTL would always allocate non-executable stacks.  This has
never been noticed, since GNU Mach on x86 ignores VM_PROT_EXECUTE and
makes all pages implicitly executable.  Since GNU Mach on AArch64
supports non-executable pages, HTL forgetting to pass VM_PROT_EXECUTE
immediately breaks any code that (unfortunately, still) relies on
executable stacks.

Signed-off-by: Sergey Bugaev <bugaevc@gmail.com>
Message-ID: <20240323173301.151066-7-bugaevc@gmail.com>
This commit is contained in:
Sergey Bugaev 2024-03-23 20:32:47 +03:00 committed by Samuel Thibault
parent b467cfcaee
commit a4273efa21
2 changed files with 11 additions and 2 deletions

View File

@ -12,4 +12,8 @@ libc {
pthread_spin_destroy; pthread_spin_init; pthread_spin_lock; pthread_spin_destroy; pthread_spin_init; pthread_spin_lock;
pthread_spin_trylock; pthread_spin_unlock; pthread_spin_trylock; pthread_spin_unlock;
} }
GLIBC_PRIVATE {
__vm_map;
}
} }

View File

@ -31,9 +31,14 @@ int
__pthread_stack_alloc (void **stackaddr, size_t stacksize) __pthread_stack_alloc (void **stackaddr, size_t stacksize)
{ {
error_t err; error_t err;
vm_prot_t prot = VM_PROT_READ | VM_PROT_WRITE;
err = __vm_allocate (__mach_task_self (), (vm_offset_t *) stackaddr, if (GL(dl_stack_flags) & PF_X)
stacksize, TRUE); prot |= VM_PROT_EXECUTE;
err = __vm_map (__mach_task_self (), (vm_offset_t *) stackaddr,
stacksize, 0, TRUE, MEMORY_OBJECT_NULL, 0, FALSE,
prot, VM_PROT_ALL, VM_INHERIT_COPY);
if (err == KERN_NO_SPACE) if (err == KERN_NO_SPACE)
err = EAGAIN; err = EAGAIN;