summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Kernel/API/POSIX/sys/limits.h3
-rw-r--r--Kernel/API/Syscall.h2
-rw-r--r--Kernel/API/serenity_limits.h9
-rw-r--r--Kernel/Syscalls/execve.cpp11
-rw-r--r--Userland/Libraries/LibC/elf.h2
-rw-r--r--Userland/Libraries/LibC/limits.h3
-rw-r--r--Userland/Libraries/LibC/pthread.cpp3
-rw-r--r--Userland/Libraries/LibELF/Image.cpp1
-rw-r--r--Userland/Libraries/LibELF/Validation.cpp16
9 files changed, 43 insertions, 7 deletions
diff --git a/Kernel/API/POSIX/sys/limits.h b/Kernel/API/POSIX/sys/limits.h
index df12d14894..9afa33667c 100644
--- a/Kernel/API/POSIX/sys/limits.h
+++ b/Kernel/API/POSIX/sys/limits.h
@@ -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
diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h
index d9be71d747..a1c0f11da4 100644
--- a/Kernel/API/Syscall.h
+++ b/Kernel/API/Syscall.h
@@ -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;
diff --git a/Kernel/API/serenity_limits.h b/Kernel/API/serenity_limits.h
new file mode 100644
index 0000000000..6fe025f535
--- /dev/null
+++ b/Kernel/API/serenity_limits.h
@@ -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
diff --git a/Kernel/Syscalls/execve.cpp b/Kernel/Syscalls/execve.cpp
index 7026f6090b..206b414582 100644
--- a/Kernel/Syscalls/execve.cpp
+++ b/Kernel/Syscalls/execve.cpp
@@ -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 {
diff --git a/Userland/Libraries/LibC/elf.h b/Userland/Libraries/LibC/elf.h
index 97e0660251..9d968e59bf 100644
--- a/Userland/Libraries/LibC/elf.h
+++ b/Userland/Libraries/LibC/elf.h
@@ -487,7 +487,7 @@ typedef struct {
#define PT_GNU_EH_FRAME 0x6474e550 /* Exception handling info */
#define PT_GNU_RELRO 0x6474e552 /* Read-only after relocation */
-#define PT_GNU_STACK 0x6474e551 /* Stack permissions info */
+#define PT_GNU_STACK 0x6474e551 /* Stack permissions & size info */
#define PT_OPENBSD_RANDOMIZE 0x65a3dbe6 /* fill with random data */
#define PT_OPENBSD_WXNEEDED 0x65a3dbe7 /* program performs W^X violations */
diff --git a/Userland/Libraries/LibC/limits.h b/Userland/Libraries/LibC/limits.h
index 54d288a6e4..24280767d0 100644
--- a/Userland/Libraries/LibC/limits.h
+++ b/Userland/Libraries/LibC/limits.h
@@ -7,6 +7,7 @@
#pragma once
#include <Kernel/API/POSIX/sys/limits.h>
+#include <Kernel/API/serenity_limits.h>
#include <bits/posix1_lim.h>
#include <bits/stdint.h>
#include <bits/wchar.h>
@@ -86,8 +87,6 @@
#define ARG_MAX 65536
-#define PTHREAD_STACK_MIN 65536
-
#define SSIZE_MAX 2147483647
#define LINK_MAX 4096
diff --git a/Userland/Libraries/LibC/pthread.cpp b/Userland/Libraries/LibC/pthread.cpp
index 0bc540991c..5af92b2c80 100644
--- a/Userland/Libraries/LibC/pthread.cpp
+++ b/Userland/Libraries/LibC/pthread.cpp
@@ -34,7 +34,6 @@ using PthreadAttrImpl = Syscall::SC_create_thread_params;
static constexpr size_t required_stack_alignment = 4 * MiB;
static constexpr size_t highest_reasonable_guard_size = 32 * PAGE_SIZE;
-static constexpr size_t highest_reasonable_stack_size = 8 * MiB; // That's the default in Ubuntu?
__thread void* s_stack_location;
__thread size_t s_stack_size;
@@ -467,7 +466,7 @@ int pthread_attr_setstacksize(pthread_attr_t* attributes, size_t stack_size)
if (!attributes_impl)
return EINVAL;
- if ((stack_size < PTHREAD_STACK_MIN) || stack_size > highest_reasonable_stack_size)
+ if (stack_size < PTHREAD_STACK_MIN || stack_size > PTHREAD_STACK_MAX)
return EINVAL;
attributes_impl->stack_size = stack_size;
diff --git a/Userland/Libraries/LibELF/Image.cpp b/Userland/Libraries/LibELF/Image.cpp
index 49af2ef3eb..0a4dea5b45 100644
--- a/Userland/Libraries/LibELF/Image.cpp
+++ b/Userland/Libraries/LibELF/Image.cpp
@@ -12,6 +12,7 @@
#include <AK/QuickSort.h>
#include <AK/StringBuilder.h>
#include <AK/StringView.h>
+#include <Kernel/API/serenity_limits.h>
#include <LibELF/Image.h>
#include <LibELF/Validation.h>
#include <limits.h>
diff --git a/Userland/Libraries/LibELF/Validation.cpp b/Userland/Libraries/LibELF/Validation.cpp
index c3d01f8dfe..d334777fdf 100644
--- a/Userland/Libraries/LibELF/Validation.cpp
+++ b/Userland/Libraries/LibELF/Validation.cpp
@@ -7,6 +7,7 @@
#include <AK/Assertions.h>
#include <AK/Checked.h>
+#include <Kernel/API/serenity_limits.h>
#include <LibC/elf.h>
#include <LibELF/Validation.h>
#include <limits.h>
@@ -298,6 +299,21 @@ ErrorOr<bool> validate_program_headers(ElfW(Ehdr) const& elf_header, size_t file
if (verbose)
dbgln("Possible shenanigans! Validating an ELF with executable stack.");
}
+
+ if (program_header.p_memsz != 0) {
+ if (program_header.p_memsz < static_cast<unsigned>(PTHREAD_STACK_MIN) || program_header.p_memsz > static_cast<unsigned>(PTHREAD_STACK_MAX)) {
+ if (verbose)
+ dbgln("PT_GNU_STACK defines an unacceptable stack size.");
+ return false;
+ }
+
+ if (program_header.p_memsz % PAGE_SIZE != 0) {
+ if (verbose)
+ dbgln("PT_GNU_STACK size is not page-aligned.");
+ return false;
+ }
+ }
+
break;
case PT_GNU_RELRO:
if ((program_header.p_flags & PF_X) && (program_header.p_flags & PF_W)) {