Get the program name for MTE property check.
The property check in is_permissive_mte() uses getprogname() which
doesn't get the correct program name. Instead use the libbase
GetExecutablePath() function instead.
Add a new test for the fallback path that runs in minijail to verify
that there is no SIGSYS raised.
Add the readlinkat syscall for MTE but only on aarch64.
Test: Verified that the property check actually sees the executable name.
Test: All unit tests pass on an MTE enabled device.
Change-Id: I44276f6cdc4860a88e1f48a2011ca4c4e4f1dc2a
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 34f2c45..4a24a83 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -1841,6 +1841,43 @@
ASSERT_BACKTRACE_FRAME(result, "bar");
}
+TEST_F(CrasherTest, seccomp_mte) {
+#if defined(__aarch64__)
+ if (!mte_supported() || !mte_enabled()) {
+ GTEST_SKIP() << "Requires MTE";
+ }
+
+ LogcatCollector logcat_collector;
+
+ size_t allocation_size = 1;
+ int intercept_result;
+ unique_fd output_fd;
+ StartProcess(
+ [&]() {
+ SetTagCheckingLevelSync();
+ volatile int* p = (volatile int*)malloc(allocation_size);
+ free((void*)p);
+ p[0] = 42;
+ },
+ &seccomp_fork);
+
+ StartIntercept(&output_fd);
+ FinishCrasher();
+ AssertDeath(SIGSEGV);
+ FinishIntercept(&intercept_result);
+
+ ASSERT_EQ(1, intercept_result) << "tombstoned reported failure";
+
+ // The fallback path does not support getting MTE error data, so simply check
+ // that we get the correct type of crash.
+ std::string result;
+ ConsumeFd(std::move(output_fd), &result);
+ ASSERT_MATCH(result, R"(signal 11 \(SIGSEGV\), code 9 \(SEGV_MTESERR)");
+#else
+ GTEST_SKIP() << "Requires aarch64";
+#endif
+}
+
TEST_F(CrasherTest, competing_tracer) {
int intercept_result;
unique_fd output_fd;
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index 88278ca..fdc5179 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -39,6 +39,7 @@
#include <time.h>
#include <unistd.h>
+#include <android-base/file.h>
#include <android-base/macros.h>
#include <android-base/parsebool.h>
#include <android-base/parseint.h>
@@ -108,7 +109,7 @@
char process_sysprop_name[512];
async_safe_format_buffer(process_sysprop_name, sizeof(process_sysprop_name),
"persist.device_config.memory_safety_native.permissive.process.%s",
- getprogname());
+ android::base::Basename(android::base::GetExecutablePath()).c_str());
// DO NOT REPLACE this with GetBoolProperty. That uses std::string which allocates, so it is
// not async-safe, and this function gets used in a signal handler.
return property_parse_bool("persist.sys.mte.permissive") ||
diff --git a/debuggerd/seccomp_policy/crash_dump.arm64.policy b/debuggerd/seccomp_policy/crash_dump.arm64.policy
index 4c8271c..e0188d0 100644
--- a/debuggerd/seccomp_policy/crash_dump.arm64.policy
+++ b/debuggerd/seccomp_policy/crash_dump.arm64.policy
@@ -42,3 +42,4 @@
getgid: 1
getegid: 1
getgroups: 1
+readlinkat: 1
diff --git a/debuggerd/seccomp_policy/crash_dump.no_mmap_mprotect_prctl.arm64.policy b/debuggerd/seccomp_policy/crash_dump.no_mmap_mprotect_prctl.arm64.policy
index efb764e..8880c33 100644
--- a/debuggerd/seccomp_policy/crash_dump.no_mmap_mprotect_prctl.arm64.policy
+++ b/debuggerd/seccomp_policy/crash_dump.no_mmap_mprotect_prctl.arm64.policy
@@ -39,3 +39,4 @@
getgid: 1
getegid: 1
getgroups: 1
+readlinkat: 1
diff --git a/debuggerd/seccomp_policy/crash_dump.policy.def b/debuggerd/seccomp_policy/crash_dump.policy.def
index 06e0c32..77cff82 100644
--- a/debuggerd/seccomp_policy/crash_dump.policy.def
+++ b/debuggerd/seccomp_policy/crash_dump.policy.def
@@ -101,3 +101,8 @@
getegid32: 1
getgroups32: 1
#endif
+
+// MTE specific syscalls
+#if defined(__aarch64__)
+readlinkat: 1
+#endif