[llvm] [llvm][Support][Memory] Add memfd based fallback for strict W^X Linux systems (PR #98538)
Jannik Glückert via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 1 13:03:04 PDT 2024
================
@@ -251,5 +320,50 @@ void Memory::InvalidateInstructionCache(const void *Addr, size_t Len) {
ValgrindDiscardTranslations(Addr, Len);
}
+static inline bool isPermissionError(int err) {
+ // PaX uses EPERM, SELinux uses EACCES
+ return err == EPERM || err == EACCES;
+}
+
+bool Memory::execProtectionChangeNeedsNewMapping() {
+#if defined(__linux__)
+ static int status = -1;
+
+ if (status != -1)
+ return status;
+
+ // Try to get the status from /proc/self/status, looking for PaX flags.
+ if (auto file = MemoryBuffer::getFileAsStream("/proc/self/status")) {
+ auto pax_flags =
+ (*file)->getBuffer().rsplit("PaX:").second.split('\n').first.trim();
+ if (!pax_flags.empty())
+ // 'M' indicates MPROTECT is enabled
+ return (status = pax_flags.find('M') != StringRef::npos);
+ }
+
+ // Create a temporary writable mapping and try to make it executable. If
+ // this fails, test 'errno' to ensure it failed because we were not allowed
+ // to create such a mapping and not because of some transient error.
+ size_t size = Process::getPageSizeEstimate();
+ void *addr = ::mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (addr == MAP_FAILED) {
+ // Must be low on memory or have too many mappings already, not much we can
+ // do here.
+ status = 0;
+ } else {
+ if (::mprotect(addr, size, PROT_READ | PROT_EXEC) < 0)
+ status = isPermissionError(errno);
----------------
Jannik2099 wrote:
I (and I bet everyone else who works on selinux policies) would still much prefer being overly cautious rather than causing an AVC denial to detect `execmem` support.
It means we'd have to add a suppression for everything that uses the llvm jit, which means losing any information / audit logging on when a program unintentionally tries to use `execmem`.
https://github.com/llvm/llvm-project/pull/98538
More information about the llvm-commits
mailing list