From 740ff3642c8c6321dcf0a058d99d40831af16c0b Mon Sep 17 00:00:00 2001 From: Vlad Brezae Date: Mon, 1 Oct 2018 17:29:23 +0300 Subject: [PATCH] [runtime] Disable stack guard for main thread on osx On macOS Mojave, it seems that changing the mapping of stack pages for main thread can lead to corruption bugs. https://github.com/mono/mono/issues/10802 --- mono/mini/mini-exceptions.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/mono/mini/mini-exceptions.c b/mono/mini/mini-exceptions.c index 6297bacf7042..1f88a31cc7ba 100644 --- a/mono/mini/mini-exceptions.c +++ b/mono/mini/mini-exceptions.c @@ -2732,6 +2732,15 @@ mono_setup_altstack (MonoJitTlsData *tls) size_t stsize = 0; stack_t sa; guint8 *staddr = NULL; +#ifdef TARGET_OSX + /* + * On macOS Mojave we are encountering a bug when changing mapping for main thread + * stack pages. Stack overflow on main thread will kill the app. + */ + gboolean disable_stack_guard = pthread_main_np (); +#else + gboolean disable_stack_guard = FALSE; +#endif if (mono_running_on_valgrind ()) return; @@ -2745,16 +2754,18 @@ mono_setup_altstack (MonoJitTlsData *tls) /*g_print ("thread %p, stack_base: %p, stack_size: %d\n", (gpointer)pthread_self (), staddr, stsize);*/ - tls->stack_ovf_guard_base = staddr + mono_pagesize (); - tls->stack_ovf_guard_size = ALIGN_TO (8 * 4096, mono_pagesize ()); + if (!disable_stack_guard) { + tls->stack_ovf_guard_base = staddr + mono_pagesize (); + tls->stack_ovf_guard_size = ALIGN_TO (8 * 4096, mono_pagesize ()); - g_assert ((guint8*)&sa >= (guint8*)tls->stack_ovf_guard_base + tls->stack_ovf_guard_size); + g_assert ((guint8*)&sa >= (guint8*)tls->stack_ovf_guard_base + tls->stack_ovf_guard_size); - if (mono_mprotect (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size, MONO_MMAP_NONE)) { - /* mprotect can fail for the main thread stack */ - gpointer gaddr = mono_valloc (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size, MONO_MMAP_NONE|MONO_MMAP_PRIVATE|MONO_MMAP_ANON|MONO_MMAP_FIXED, MONO_MEM_ACCOUNT_EXCEPTIONS); - g_assert (gaddr == tls->stack_ovf_guard_base); - tls->stack_ovf_valloced = TRUE; + if (mono_mprotect (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size, MONO_MMAP_NONE)) { + /* mprotect can fail for the main thread stack */ + gpointer gaddr = mono_valloc (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size, MONO_MMAP_NONE|MONO_MMAP_PRIVATE|MONO_MMAP_ANON|MONO_MMAP_FIXED, MONO_MEM_ACCOUNT_EXCEPTIONS); + g_assert (gaddr == tls->stack_ovf_guard_base); + tls->stack_ovf_valloced = TRUE; + } } /* Setup an alternate signal stack */ @@ -2785,6 +2796,9 @@ mono_free_altstack (MonoJitTlsData *tls) if (tls->signal_stack) mono_vfree (tls->signal_stack, MONO_ARCH_SIGNAL_STACK_SIZE, MONO_MEM_ACCOUNT_EXCEPTIONS); + + if (!tls->stack_ovf_guard_base) + return; if (tls->stack_ovf_valloced) mono_vfree (tls->stack_ovf_guard_base, tls->stack_ovf_guard_size, MONO_MEM_ACCOUNT_EXCEPTIONS); else