[compiler-rt] [sanitizer] Disable writes to log files for binaries in a secure context. (PR #92593)

via llvm-commits llvm-commits at lists.llvm.org
Mon May 20 13:06:42 PDT 2024


https://github.com/bigb4ng updated https://github.com/llvm/llvm-project/pull/92593

>From 15b4ea9511fba4f0387720d7eb0401940a508ebb Mon Sep 17 00:00:00 2001
From: bigb4ng <130478744+bigb4ng at users.noreply.github.com>
Date: Fri, 17 May 2024 07:26:39 +0300
Subject: [PATCH] [sanitizer] Disable using log_path with AT_SECURE and/or
 setuid binaries.

Fix for https://github.com/google/sanitizers/issues/1130.

An original issue described by Szabolcs Nagy at https://seclists.org/oss-sec/2016/q1/363.
---
 compiler-rt/lib/sanitizer_common/sanitizer_common.h |  5 +++++
 .../sanitizer_common/sanitizer_common_nolibc.cpp    |  1 +
 compiler-rt/lib/sanitizer_common/sanitizer_file.cpp | 10 ++++++++++
 .../sanitizer_common/sanitizer_posix_libcdep.cpp    | 13 +++++++++++++
 compiler-rt/lib/sanitizer_common/sanitizer_win.cpp  |  2 ++
 5 files changed, 31 insertions(+)

diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
index c451fc962c529..ef03b47e89929 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h
@@ -1096,6 +1096,11 @@ inline u32 GetNumberOfCPUsCached() {
   return NumberOfCPUsCached;
 }
 
+// Returns true if the our runtime has special privileges (e.g. setuid) and
+// should be treated with caution when dealing with untrusted user input.
+// For example, when writing files or executing user-specified binaries.
+bool ShouldTreatRuntimeSecurely();
+
 }  // namespace __sanitizer
 
 inline void *operator new(__sanitizer::usize size,
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_nolibc.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_common_nolibc.cpp
index 67e77a8777818..104f4634e875b 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_common_nolibc.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_nolibc.cpp
@@ -26,6 +26,7 @@ void LogMessageOnPrintf(const char *str) {}
 void WriteToSyslog(const char *buffer) {}
 void Abort() { internal__exit(1); }
 bool CreateDir(const char *pathname) { return false; }
+bool ShouldTreatRuntimeSecurely() { return false; }
 #endif // !SANITIZER_WINDOWS
 
 #if !SANITIZER_WINDOWS && !SANITIZER_APPLE
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
index 7ef499ce07b13..a4b89d8198a52 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_file.cpp
@@ -104,6 +104,16 @@ void ReportFile::SetReportPath(const char *path) {
     }
   }
 
+  if (path && ShouldTreatRuntimeSecurely() &&
+      internal_strcmp(path, "stderr") != 0 &&
+      internal_strcmp(path, "stdout") != 0) {
+    Report(
+        "ERROR: log_path must be 'stderr' or 'stdout' for AT_SECURE and/or "
+        "setuid binaries, is '%s'\n",
+        path);
+    Die();
+  }
+
   SpinMutexLock l(mu);
   if (fd != kStdoutFd && fd != kStderrFd && fd != kInvalidFd)
     CloseFile(fd);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
index ece2d7d63dd61..9d5bc69b25876 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp
@@ -43,6 +43,10 @@
 #define MAP_NORESERVE 0
 #endif
 
+#  if SANITIZER_LINUX
+#    include "sanitizer_getauxval.h"
+#  endif
+
 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
 
 namespace __sanitizer {
@@ -518,6 +522,15 @@ bool IsStateDetached(int state) {
   return state == PTHREAD_CREATE_DETACHED;
 }
 
+bool ShouldTreatRuntimeSecurely() {
+#  if SANITIZER_LINUX
+  // So we can use weak reference from sanitizer_getauxval.h
+  if (&getauxval)
+    return getauxval(/* AT_SECURE */ 23) != 0;
+#  endif
+  return getuid() != geteuid() || getgid() != getegid();
+}
+
 } // namespace __sanitizer
 
 #endif // SANITIZER_POSIX
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
index 4e5ad8e4693b4..be4b06442ca58 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp
@@ -1199,6 +1199,8 @@ void LogFullErrorReport(const char *buffer) {
 
 void InitializePlatformCommonFlags(CommonFlags *cf) {}
 
+bool ShouldTreatRuntimeSecurely() { return false; }
+
 }  // namespace __sanitizer
 
 #endif  // _WIN32



More information about the llvm-commits mailing list