Skip to content

Commit 3ecadc4

Browse files
NoobZangtimschumi
authored andcommitted
LibC: Implement guard page for pthread
1 parent c8cc2fd commit 3ecadc4

File tree

3 files changed

+13
-5
lines changed

3 files changed

+13
-5
lines changed

Kernel/API/Syscall.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,6 @@ struct SC_getkeymap_params {
361361
struct SC_create_thread_params {
362362
unsigned int detach_state = 0; // JOINABLE or DETACHED
363363
int schedule_priority = 30; // THREAD_PRIORITY_NORMAL
364-
// FIXME: Implement guard pages in create_thread (unreadable pages at "overflow" end of stack)
365364
// "If an implementation rounds up the value of guardsize to a multiple of {PAGESIZE},
366365
// a call to pthread_attr_getguardsize() specifying attr shall store in the guardsize
367366
// parameter the guard size specified by the previous pthread_attr_setguardsize() function call"

Kernel/Syscalls/thread.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ ErrorOr<FlatPtr> Process::sys$create_thread(void* (*entry)(void*), Userspace<Sys
4141

4242
bool is_thread_joinable = (0 == detach_state);
4343

44-
// FIXME: Do something with guard pages?
45-
4644
auto thread = TRY(Thread::create(*this));
4745

4846
// We know this thread is not the main_thread,

Userland/Libraries/LibC/pthread.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,20 @@ int pthread_create(pthread_t* thread, pthread_attr_t const* attributes, void* (*
136136
if (0 != (used_attributes->stack_size % required_stack_alignment))
137137
used_attributes->stack_size += required_stack_alignment - (used_attributes->stack_size % required_stack_alignment);
138138

139-
used_attributes->stack_location = mmap_with_name(nullptr, used_attributes->stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, 0, 0, "Thread stack");
140-
if (!used_attributes->stack_location)
139+
// According to POSIX, if the stack address attribute has been set in attr,
140+
// then the guard size attribute is ignored: it is the application's responsibility
141+
// to handle stack overflow.
142+
size_t total_size = used_attributes->stack_size + used_attributes->guard_page_size;
143+
void* memory_location = mmap_with_name(nullptr, total_size, used_attributes->guard_page_size == 0 ? PROT_READ | PROT_WRITE : PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, 0, 0, "Thread stack");
144+
if (!memory_location)
141145
return -1;
146+
if (used_attributes->guard_page_size > 0) {
147+
if (mprotect((void*)((FlatPtr)memory_location + used_attributes->guard_page_size), used_attributes->stack_size, PROT_READ | PROT_WRITE) < 0) {
148+
munmap(memory_location, total_size);
149+
return -1;
150+
}
151+
}
152+
used_attributes->stack_location = (void*)((FlatPtr)memory_location + used_attributes->guard_page_size);
142153
}
143154

144155
dbgln_if(PTHREAD_DEBUG, "pthread_create: Creating thread with attributes at {}, detach state {}, priority {}, guard page size {}, stack size {}, stack location {}",

0 commit comments

Comments
 (0)