Skip to content

Commit

Permalink
[runtime] Disable guard stack overflow guard page on darwin
Browse files Browse the repository at this point in the history
On macOS Mojave, it seems that changing the mapping of stack pages can lead to corruption bugs.

mono#10802
  • Loading branch information
BrzVlad committed Oct 1, 2018
1 parent 23c4de0 commit c79f751
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 1 deletion.
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ case "$host" in
need_link_unlink=yes
AC_DEFINE(PTHREAD_POINTER_ID)
AC_DEFINE(USE_MACH_SEMA, 1, [...])
AC_DEFINE(DISABLE_STACK_OVERFLOW_GUARD, 1, [Mapping of stack guard page is buggy on platform])
libdl=
libgc_threads=pthreads
has_dtrace=yes
Expand Down
6 changes: 6 additions & 0 deletions mono/mini/exceptions-amd64.c
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,7 @@ mono_arch_ip_from_context (void *sigctx)
#endif
}

#ifndef DISABLE_STACK_OVERFLOW_GUARD
static MonoObject*
restore_soft_guard_pages (void)
{
Expand Down Expand Up @@ -844,6 +845,7 @@ prepare_for_guard_pages (MonoContext *mctx)
mctx->gregs [AMD64_RIP] = (guint64)restore_soft_guard_pages;
mctx->gregs [AMD64_RSP] = (guint64)sp;
}
#endif

static void
altstack_handle_and_restore (MonoContext *ctx, MonoObject *obj, gboolean stack_ovf)
Expand All @@ -858,9 +860,13 @@ altstack_handle_and_restore (MonoContext *ctx, MonoObject *obj, gboolean stack_o

mono_handle_exception (&mctx, obj);
if (stack_ovf) {
#ifndef DISABLE_STACK_OVERFLOW_GUARD
MonoJitTlsData *jit_tls = mono_tls_get_jit_tls ();
jit_tls->stack_ovf_pending = 1;
prepare_for_guard_pages (&mctx);
#else
g_error ("Soft stack overflow should be disabled");
#endif
}
mono_restore_context (&mctx);
}
Expand Down
7 changes: 6 additions & 1 deletion mono/mini/exceptions-x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj)
#endif
}

#ifndef DISABLE_STACK_OVERFLOW_GUARD
static MonoObject*
restore_soft_guard_pages ()
{
Expand Down Expand Up @@ -1070,7 +1071,7 @@ prepare_for_guard_pages (MonoContext *mctx)
mctx->eip = (unsigned long)restore_soft_guard_pages;
mctx->esp = (unsigned long)sp;
}

#endif

static void
altstack_handle_and_restore (MonoContext *ctx, gpointer obj, gboolean stack_ovf)
Expand All @@ -1081,9 +1082,13 @@ altstack_handle_and_restore (MonoContext *ctx, gpointer obj, gboolean stack_ovf)

mono_handle_exception (&mctx, (MonoObject*)obj);
if (stack_ovf) {
#ifndef DISABLE_STACK_OVERFLOW_GUARD
MonoJitTlsData *jit_tls = mono_tls_get_jit_tls ();
jit_tls->stack_ovf_pending = 1;
prepare_for_guard_pages (&mctx);
#else
g_error ("Soft stack overflow should be disabled");
#endif
}
mono_restore_context (&mctx);
}
Expand Down
12 changes: 12 additions & 0 deletions mono/mini/mini-exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -2745,6 +2745,7 @@ mono_setup_altstack (MonoJitTlsData *tls)

/*g_print ("thread %p, stack_base: %p, stack_size: %d\n", (gpointer)pthread_self (), staddr, stsize);*/

#ifndef DISABLE_STACK_OVERFLOW_GUARD
tls->stack_ovf_guard_base = staddr + mono_pagesize ();
tls->stack_ovf_guard_size = ALIGN_TO (8 * 4096, mono_pagesize ());

Expand All @@ -2756,6 +2757,7 @@ mono_setup_altstack (MonoJitTlsData *tls)
g_assert (gaddr == tls->stack_ovf_guard_base);
tls->stack_ovf_valloced = TRUE;
}
#endif

/* Setup an alternate signal stack */
tls->signal_stack = mono_valloc (0, MONO_ARCH_SIGNAL_STACK_SIZE, MONO_MMAP_READ|MONO_MMAP_WRITE|MONO_MMAP_PRIVATE|MONO_MMAP_ANON, MONO_MEM_ACCOUNT_EXCEPTIONS);
Expand All @@ -2768,7 +2770,11 @@ mono_setup_altstack (MonoJitTlsData *tls)
sa.ss_flags = 0;
g_assert (sigaltstack (&sa, NULL) == 0);

#ifndef DISABLE_STACK_OVERFLOW_GUARD
mono_gc_register_altstack ((char*)tls->stack_ovf_guard_base + tls->stack_ovf_guard_size, (char*)staddr + stsize - ((char*)tls->stack_ovf_guard_base + tls->stack_ovf_guard_size), tls->signal_stack, tls->signal_stack_size);
#else
mono_gc_register_altstack (staddr, stsize, tls->signal_stack, tls->signal_stack_size);
#endif
}

void
Expand All @@ -2785,10 +2791,12 @@ mono_free_altstack (MonoJitTlsData *tls)

if (tls->signal_stack)
mono_vfree (tls->signal_stack, MONO_ARCH_SIGNAL_STACK_SIZE, MONO_MEM_ACCOUNT_EXCEPTIONS);
#ifndef DISABLE_STACK_OVERFLOW_GUARD
if (tls->stack_ovf_valloced)
mono_vfree (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size, MONO_MEM_ACCOUNT_EXCEPTIONS);
else
mono_mprotect (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size, MONO_MMAP_READ|MONO_MMAP_WRITE);
#endif
}

#else /* !MONO_ARCH_SIGSEGV_ON_ALTSTACK */
Expand All @@ -2808,6 +2816,9 @@ mono_free_altstack (MonoJitTlsData *tls)
gboolean
mono_handle_soft_stack_ovf (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, MONO_SIG_HANDLER_INFO_TYPE *siginfo, guint8* fault_addr)
{
#ifdef DISABLE_STACK_OVERFLOW_GUARD
return FALSE;
#else
if (mono_llvm_only)
return FALSE;

Expand Down Expand Up @@ -2847,6 +2858,7 @@ mono_handle_soft_stack_ovf (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx,
return TRUE;
}
return FALSE;
#endif
}

typedef struct {
Expand Down
2 changes: 2 additions & 0 deletions mono/mini/mini-runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,12 @@ struct MonoJitTlsData {
guint handling_stack_ovf : 1;
gpointer signal_stack;
guint32 signal_stack_size;
#ifndef DISABLE_STACK_OVERFLOW_GUARD
gpointer stack_ovf_guard_base;
guint32 stack_ovf_guard_size;
guint stack_ovf_valloced : 1;
guint stack_ovf_pending : 1;
#endif
MonoAbortFunction abort_func;
/* Used to implement --debug=casts */
MonoClass *class_cast_from, *class_cast_to;
Expand Down

0 comments on commit c79f751

Please sign in to comment.