summaryrefslogtreecommitdiff
path: root/packaging/0001-Fix-alternate-stack-for-Alpine-docker-on-SELinux-179.patch
diff options
context:
space:
mode:
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.patch75
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
+