From 7fd467321d2c7aa8fdbbb30c13bab86b31d22803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kochma=C5=84ski?= Date: Sun, 15 Mar 2026 21:52:43 +0100 Subject: [PATCH] lwp: use mprotect to catch stack overflows --- src/c/lwp.d | 24 ++++++++++++++++++++++-- src/h/object.h | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/c/lwp.d b/src/c/lwp.d index 8d9dd7504..e632733c1 100644 --- a/src/c/lwp.d +++ b/src/c/lwp.d @@ -15,6 +15,8 @@ #include #include +# include +# include #include /* -- implementation notes ----------------------------------------------------- @@ -47,6 +49,24 @@ ensure_cc(cl_env_ptr the_env) return cc; } + +#define LWP_STACK_SIZE 8*1024 + +/* FIXME munmap in the finalizer. */ +static void* +make_stack(size_t size) +{ + size_t page_size = sysconf(_SC_PAGESIZE); + void *mem = mmap(NULL, size+page_size, + PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + /* catch overflows. Note that we don't need it normally in ECL, because we do + our own overflow checks, but this helps to illustrate and catch early when + GC goes off rails because it doesn't work well with multiple stakck. */ + mprotect(mem, page_size, PROT_NONE); + return mem+page_size; +} + static void _lwp_entry(void) { @@ -89,8 +109,8 @@ si_make_continuation(cl_object thread) o->cont.env = new_env; /* Create the context. */ getcontext(uc); - uc->uc_stack.ss_sp = stack; - uc->uc_stack.ss_size = 16*1024; + uc->uc_stack.ss_sp = make_stack(LWP_STACK_SIZE); + uc->uc_stack.ss_size = LWP_STACK_SIZE; uc->uc_link = NULL; makecontext(uc, (void(*)(void))_lwp_entry, 0); } diff --git a/src/h/object.h b/src/h/object.h index 126171e41..1f4839a8f 100644 --- a/src/h/object.h +++ b/src/h/object.h @@ -1071,7 +1071,7 @@ struct ecl_cont { _ECL_HDR2(resumed, timed_out); cl_object thread; /* its thread */ ucontext_t uc; - char stack[16*1024]; + void *stack; cl_env_ptr env; };