Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define __stack_base and __stack_limit globals in debug mode for stack overflow detection #380

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ jobs:
shell: bash
run: make -j4 THREAD_MODEL=posix

- name: Build libc + threads in debug mode
# There are features like stack boundary exposure that
# only compile in debug mode (i.e. when NDEBUG is not defined).
if: matrix.clang_version != '10.0.0'
shell: bash
run: make -j4 THREAD_MODEL=posix EXTRA_CFLAGS=

# Disable the headerstest job for now, while WASI transitions from the
# witx snapshots to wit proposals, and we have a few manual edits to the
# generated header to make life easier for folks.
Expand Down
13 changes: 9 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ NM ?= $(patsubst %clang,%llvm-nm,$(filter-out ccache sccache,$(CC)))
ifeq ($(origin AR), default)
AR = $(patsubst %clang,%llvm-ar,$(filter-out ccache sccache,$(CC)))
endif
EXTRA_CFLAGS ?= -O2 -DNDEBUG
DEFAULT_EXTRA_CFLAGS = -O2 -DNDEBUG
EXTRA_CFLAGS ?= $(DEFAULT_EXTRA_CFLAGS)
# The directory where we build the sysroot.
SYSROOT ?= $(CURDIR)/sysroot
# A directory to install to for "make install".
Expand Down Expand Up @@ -269,7 +270,7 @@ LIBC_TOP_HALF_MUSL_SOURCES += \
thread/sem_timedwait.c \
thread/sem_trywait.c \
thread/sem_wait.c \
thread/wasm32/wasi_thread_start.s \
thread/wasm32/wasi_thread_start.S \
)
endif

Expand Down Expand Up @@ -341,7 +342,7 @@ CFLAGS += -isystem "$(SYSROOT_INC)"
# These variables describe the locations of various files and directories in
# the build tree.
objs = $(patsubst $(CURDIR)/%.c,$(OBJDIR)/%.o,$(1))
asmobjs = $(patsubst $(CURDIR)/%.s,$(OBJDIR)/%.o,$(1))
asmobjs = $(patsubst $(CURDIR)/%.S,$(OBJDIR)/%.o,$(1))
DLMALLOC_OBJS = $(call objs,$(DLMALLOC_SOURCES))
EMMALLOC_OBJS = $(call objs,$(EMMALLOC_SOURCES))
LIBC_BOTTOM_HALF_ALL_OBJS = $(call objs,$(LIBC_BOTTOM_HALF_ALL_SOURCES))
Expand Down Expand Up @@ -520,7 +521,7 @@ $(OBJDIR)/%.o: $(CURDIR)/%.c include_dirs
@mkdir -p "$(@D)"
$(CC) $(CFLAGS) -MD -MP -o $@ -c $<

$(OBJDIR)/%.o: $(CURDIR)/%.s include_dirs
$(OBJDIR)/%.o: $(CURDIR)/%.S include_dirs
@mkdir -p "$(@D)"
$(CC) $(ASMFLAGS) -o $@ -c $<

Expand Down Expand Up @@ -704,9 +705,13 @@ check-symbols: startup_files libc
| grep -v '^#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_\(1\|2\|4\|8\)' \
> "$(SYSROOT_SHARE)/predefined-macros.txt"

# Only verify metadata for default set of extra cflags; otherwise, it
# most likely won't match.
ifeq ($(EXTRA_CFLAGS),$(DEFAULT_EXTRA_CFLAGS))
# Check that the computed metadata matches the expected metadata.
# This ignores whitespace because on Windows the output has CRLF line endings.
diff -wur "$(CURDIR)/expected/$(TARGET_TRIPLE)" "$(SYSROOT_SHARE)"
endif

install: finish
mkdir -p "$(INSTALL_DIR)"
Expand Down
12 changes: 10 additions & 2 deletions libc-top-half/musl/src/thread/pthread_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,14 @@ struct start_args {
unsigned long sig_mask[_NSIG/8/sizeof(long)];
#else
/*
* Note: the offset of the "stack" and "tls_base" members
* Note: the offset of the "stack", "stack_limit" and "tls_base" members
* in this structure is hardcoded in wasi_thread_start.
*/
void *stack;
void *tls_base;
#ifndef NDEBUG
void *stack_limit;
#endif
void *(*start_func)(void *);
void *start_arg;
#endif
Expand Down Expand Up @@ -501,7 +504,12 @@ int __pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict att
/* Correct the stack size */
new->stack_size = stack - stack_limit;

args->stack = new->stack; /* just for convenience of asm trampoline */
/* just for convenience of asm trampoline */
args->stack = new->stack;
#ifndef NDEBUG
args->stack_limit = stack_limit;
#endif

args->start_func = entry;
args->start_arg = arg;
args->tls_base = (void*)new_tls_base;
Expand Down
64 changes: 64 additions & 0 deletions libc-top-half/musl/src/thread/wasm32/wasi_thread_start.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#define PTR i32
#define PTRSIZE 4
# Preprocessor's define directive doesn't resolve math expressions,
# so we hardcode the result of PTRSIZE * 2 operation
#define DOUBLE_PTRSIZE 8

.text

.export_name wasi_thread_start, wasi_thread_start

.globaltype __stack_pointer, PTR
.globaltype __tls_base, PTR

#ifndef NDEBUG
.globaltype __stack_base, PTR
.globaltype __stack_limit, PTR
#endif

.functype __wasi_thread_start_C (i32, PTR) -> ()

.hidden wasi_thread_start
.globl wasi_thread_start
.type wasi_thread_start,@function

wasi_thread_start:
.functype wasi_thread_start (i32, PTR) -> ()

# Set up the minimum C environment.
# Note: offsetof(start_arg, stack) == 0
local.get 1 # start_arg
PTR.load 0 # stack
global.set __stack_pointer

local.get 1 # start_arg
PTR.load PTRSIZE # tls_base
global.set __tls_base

#ifndef NDEBUG
# configure __stack_base and __stack_limit in debug mode
# to allow for stack overflow detection
local.get 1 # start_arg
PTR.load 0 # stack
global.set __stack_base

local.get 1 # start_arg
PTR.load DOUBLE_PTRSIZE # stack_limit
global.set __stack_limit
#endif

# Make the C function do the rest of work.
local.get 0 # tid
local.get 1 # start_arg
call __wasi_thread_start_C

end_function

#ifndef NDEBUG
.section .data,"",@

__stack_base:

__stack_limit:

#endif
31 changes: 0 additions & 31 deletions libc-top-half/musl/src/thread/wasm32/wasi_thread_start.s

This file was deleted.