diff options
Diffstat (limited to 'packaging/0001-Fix-alternate-stack-for-Alpine-docker-on-SELinux-179.patch')
-rw-r--r-- | packaging/0001-Fix-alternate-stack-for-Alpine-docker-on-SELinux-179.patch | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/packaging/0001-Fix-alternate-stack-for-Alpine-docker-on-SELinux-179.patch b/packaging/0001-Fix-alternate-stack-for-Alpine-docker-on-SELinux-179.patch new file mode 100644 index 0000000000..f0320931f0 --- /dev/null +++ b/packaging/0001-Fix-alternate-stack-for-Alpine-docker-on-SELinux-179.patch @@ -0,0 +1,75 @@ +From 9bfa48bafefa5735887570cbc219279513eef26d Mon Sep 17 00:00:00 2001 +From: Jan Vorlicek <janvorli@microsoft.com> +Date: Thu, 10 May 2018 15:33:54 +0200 +Subject: [PATCH] Fix alternate stack for Alpine docker on SELinux (#17936) + +For some reason, the Alpine docker container running on a SELinux host maps +heap as RWX. When we allocate alternate stack from the heap, we also +change the protection of the first page to PROT_NONE so that it can +serve as a guard page to catch stack overflow. And when we free the +alternate stack, we restore the protection back to PROT_READ | +PROT_WRITE. The restoration fails in Alpine docker container running on +a SELinux host with EPROT failure and the SELinux log reports that an +attempt to change heap to executable was made. So it looks like the +kernel has added the PERM_EXEC to the permissions we have passed to the +mprotect call. There is a code in the mprotect implementation that can +do that, although I don't fully understand the conditions under which it +happens. This is driven by the VM_MAYEXEC flag in the internal VMA block +structure. +To fix that, I've modified the alternate stack allocation to use mmap / +munmap instead of C heap allocation. +--- + src/pal/src/exception/signal.cpp | 18 ++++++------------ + 1 file changed, 6 insertions(+), 12 deletions(-) + +diff --git a/src/pal/src/exception/signal.cpp b/src/pal/src/exception/signal.cpp +index 430cd05..9a990cd 100644 +--- a/src/pal/src/exception/signal.cpp ++++ b/src/pal/src/exception/signal.cpp +@@ -158,9 +158,9 @@ BOOL EnsureSignalAlternateStack() + // (see kAltStackSize in compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cc) + altStackSize += SIGSTKSZ * 4; + #endif +- void* altStack; +- int st = posix_memalign(&altStack, VIRTUAL_PAGE_SIZE, altStackSize); +- if (st == 0) ++ altStackSize = ALIGN_UP(altStackSize, VIRTUAL_PAGE_SIZE); ++ void* altStack = mmap(NULL, altStackSize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_STACK | MAP_PRIVATE, -1, 0); ++ if (altStack != MAP_FAILED) + { + // create a guard page for the alternate stack + st = mprotect(altStack, VIRTUAL_PAGE_SIZE, PROT_NONE); +@@ -171,17 +171,12 @@ BOOL EnsureSignalAlternateStack() + ss.ss_size = altStackSize; + ss.ss_flags = 0; + st = sigaltstack(&ss, NULL); +- if (st != 0) +- { +- // Installation of the alternate stack failed, so revert the guard page protection +- int st2 = mprotect(altStack, VIRTUAL_PAGE_SIZE, PROT_READ | PROT_WRITE); +- _ASSERTE(st2 == 0); +- } + } + + if (st != 0) + { +- free(altStack); ++ int st2 = munmap(altStack, altStackSize); ++ _ASSERTE(st2 == 0); + } + } + } +@@ -208,9 +203,8 @@ void FreeSignalAlternateStack() + int st = sigaltstack(&ss, &oss); + if ((st == 0) && (oss.ss_flags != SS_DISABLE)) + { +- int st = mprotect(oss.ss_sp, VIRTUAL_PAGE_SIZE, PROT_READ | PROT_WRITE); ++ int st = munmap(oss.ss_sp, oss.ss_size); + _ASSERTE(st == 0); +- free(oss.ss_sp); + } + } + #endif // !HAVE_MACH_EXCEPTIONS +-- +2.7.4 + |