mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 13:07:46 +00:00
Kernel+LibC+LibELF: Set stack size based on PT_GNU_STACK during execve
Some programs explicitly ask for a different initial stack size than what the OS provides. This is implemented in ELF by having a PT_GNU_STACK header which has its p_memsz set to the amount that the program requires. This commit implements this policy by reading the p_memsz of the header and setting the main thread stack size to that. ELF::Image::validate_program_headers ensures that the size attribute is a reasonable value.
This commit is contained in:
parent
3275015786
commit
ef6921d7c7
9 changed files with 43 additions and 7 deletions
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2022, Andreas Kling <kling@serenityos.org>
|
||||
* Copyright (c) 2022, sin-ack <sin-ack@protonmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -7,3 +8,5 @@
|
|||
#pragma once
|
||||
|
||||
#define NGROUPS_MAX 32
|
||||
|
||||
#define PTHREAD_STACK_MIN (64 * 1024) // 64KiB
|
||||
|
|
|
@ -360,7 +360,7 @@ struct SC_create_thread_params {
|
|||
// ... ok, if you say so posix. Guess we get to lie to people about guard page size
|
||||
unsigned int guard_page_size = 0; // Rounded up to PAGE_SIZE
|
||||
unsigned int reported_guard_page_size = 0; // The lie we tell callers
|
||||
unsigned int stack_size = 1 * MiB; // Default PTHREAD_STACK_MIN
|
||||
unsigned int stack_size = 1 * MiB; // Equal to Thread::default_userspace_stack_size
|
||||
void* stack_location; // nullptr means any, o.w. process virtual address
|
||||
# if ARCH(X86_64)
|
||||
FlatPtr rdi;
|
||||
|
|
9
Kernel/API/serenity_limits.h
Normal file
9
Kernel/API/serenity_limits.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
/*
|
||||
* Copyright (c) 2022, sin-ack <sin-ack@protonmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define PTHREAD_STACK_MAX (8 * 1024 * 1024) // 8MiB
|
|
@ -279,6 +279,7 @@ static ErrorOr<LoadResult> load_elf_object(NonnullOwnPtr<Memory::AddressSpace> n
|
|||
size_t master_tls_size = 0;
|
||||
size_t master_tls_alignment = 0;
|
||||
FlatPtr load_base_address = 0;
|
||||
size_t stack_size = 0;
|
||||
|
||||
auto elf_name = TRY(object_description.pseudo_path());
|
||||
VERIFY(!Processor::in_critical());
|
||||
|
@ -374,6 +375,10 @@ static ErrorOr<LoadResult> load_elf_object(NonnullOwnPtr<Memory::AddressSpace> n
|
|||
if (program_header.type() == PT_LOAD)
|
||||
return load_section(program_header);
|
||||
|
||||
if (program_header.type() == PT_GNU_STACK) {
|
||||
stack_size = program_header.size_in_memory();
|
||||
}
|
||||
|
||||
// NOTE: We ignore other program header types.
|
||||
return {};
|
||||
};
|
||||
|
@ -387,12 +392,16 @@ static ErrorOr<LoadResult> load_elf_object(NonnullOwnPtr<Memory::AddressSpace> n
|
|||
return result;
|
||||
}());
|
||||
|
||||
if (stack_size == 0) {
|
||||
stack_size = Thread::default_userspace_stack_size;
|
||||
}
|
||||
|
||||
if (!elf_image.entry().offset(load_offset).get()) {
|
||||
dbgln("do_exec: Failure loading program, entry pointer is invalid! {})", elf_image.entry().offset(load_offset));
|
||||
return ENOEXEC;
|
||||
}
|
||||
|
||||
auto* stack_region = TRY(new_space->allocate_region(Memory::RandomizeVirtualAddress::Yes, {}, Thread::default_userspace_stack_size, PAGE_SIZE, "Stack (Main thread)"sv, PROT_READ | PROT_WRITE, AllocationStrategy::Reserve));
|
||||
auto* stack_region = TRY(new_space->allocate_region(Memory::RandomizeVirtualAddress::Yes, {}, stack_size, PAGE_SIZE, "Stack (Main thread)"sv, PROT_READ | PROT_WRITE, AllocationStrategy::Reserve));
|
||||
stack_region->set_stack(true);
|
||||
|
||||
return LoadResult {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue