Merge "Suppress -Wformat warning"
diff --git a/benchmarks/spawn/Android.bp b/benchmarks/spawn/Android.bp
index 89d22e3..61e7bf6 100644
--- a/benchmarks/spawn/Android.bp
+++ b/benchmarks/spawn/Android.bp
@@ -43,6 +43,9 @@
linux_glibc_x86: {
enabled: false,
},
+ linux_musl_x86: {
+ enabled: false,
+ },
},
}
@@ -103,6 +106,11 @@
"-Wl,--rpath,${ORIGIN}/../../lib64",
],
},
+ linux_musl_x86_64: {
+ ldflags: [
+ "-Wl,--rpath,${ORIGIN}/../../lib64",
+ ],
+ },
},
}
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 08fb187..121b26f 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -45,7 +45,6 @@
#include "private/bionic_defs.h"
#include "private/bionic_globals.h"
#include "platform/bionic/macros.h"
-#include "platform/bionic/pac.h"
#include "private/bionic_ssp.h"
#include "private/bionic_systrace.h"
#include "private/bionic_tls.h"
@@ -332,9 +331,11 @@
extern "C" int __rt_sigprocmask(int, const sigset64_t*, sigset64_t*, size_t);
__attribute__((no_sanitize("hwaddress")))
+#ifdef __aarch64__
// This function doesn't return, but it does appear in stack traces. Avoid using return PAC in this
// function because we may end up resetting IA, which may confuse unwinders due to mismatching keys.
-__BIONIC_DISABLE_PAUTH
+__attribute__((target("branch-protection=bti")))
+#endif
static int __pthread_start(void* arg) {
pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(arg);
diff --git a/libc/platform/bionic/pac.h b/libc/platform/bionic/pac.h
index c311651..34efc48 100644
--- a/libc/platform/bionic/pac.h
+++ b/libc/platform/bionic/pac.h
@@ -29,7 +29,6 @@
#pragma once
#include <stddef.h>
-#include <sys/prctl.h>
inline uintptr_t __bionic_clear_pac_bits(uintptr_t ptr) {
#if defined(__aarch64__)
@@ -41,39 +40,3 @@
return ptr;
#endif
}
-
-#ifdef __aarch64__
-// The default setting for branch-protection enables both PAC and BTI, so by
-// overriding it to only enable BTI we disable PAC.
-#define __BIONIC_DISABLE_PAUTH __attribute__((target("branch-protection=bti")))
-#else
-#define __BIONIC_DISABLE_PAUTH
-#endif
-
-#ifdef __aarch64__
-// Disable PAC (i.e. make the signing and authentication instructions into no-ops) for the lifetime
-// of this object.
-class ScopedDisablePAC {
- int prev_enabled_keys_;
-
- public:
- // Disabling IA will invalidate the return address in this function if it is signed, so we need to
- // make sure that this function does not sign its return address. Likewise for the destructor.
- __BIONIC_DISABLE_PAUTH
- ScopedDisablePAC() {
- // These prctls will fail (resulting in a no-op, the intended behavior) if PAC is not supported.
- prev_enabled_keys_ = prctl(PR_PAC_GET_ENABLED_KEYS, 0, 0, 0, 0);
- prctl(PR_PAC_SET_ENABLED_KEYS, prev_enabled_keys_, 0, 0, 0);
- }
-
- __BIONIC_DISABLE_PAUTH
- ~ScopedDisablePAC() {
- prctl(PR_PAC_SET_ENABLED_KEYS, prev_enabled_keys_, prev_enabled_keys_, 0, 0);
- }
-};
-#else
-struct ScopedDisablePAC {
- // Silence unused variable warnings in non-aarch64 builds.
- ScopedDisablePAC() {}
-};
-#endif
diff --git a/linker/Android.bp b/linker/Android.bp
index dbefcf6..d5e7367 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -28,16 +28,11 @@
name: "linker_wrapper",
host_supported: true,
device_supported: false,
+ enabled: false,
target: {
linux_bionic: {
enabled: true,
},
- linux_glibc: {
- enabled: false,
- },
- darwin: {
- enabled: false,
- },
},
cflags: [
diff --git a/tests/heap_tagging_level_test.cpp b/tests/heap_tagging_level_test.cpp
index cfb2490..c493e1d 100644
--- a/tests/heap_tagging_level_test.cpp
+++ b/tests/heap_tagging_level_test.cpp
@@ -81,10 +81,20 @@
#endif // defined(__BIONIC__)
}
+namespace {
#if defined(__BIONIC__) && defined(__aarch64__)
void ExitWithSiCode(int, siginfo_t* info, void*) {
_exit(info->si_code);
}
+
+template <typename Pred>
+class Or {
+ Pred A, B;
+
+ public:
+ Or(Pred A, Pred B) : A(A), B(B) {}
+ bool operator()(int exit_status) { return A(exit_status) || B(exit_status); }
+};
#endif
TEST(heap_tagging_level, sync_async_bad_accesses_die) {
@@ -94,6 +104,7 @@
}
std::unique_ptr<int[]> p = std::make_unique<int[]>(4);
+ volatile int sink ATTRIBUTE_UNUSED;
// We assume that scudo is used on all MTE enabled hardware; scudo inserts a header with a
// mismatching tag before each allocation.
@@ -104,6 +115,12 @@
p[-1] = 42;
},
testing::ExitedWithCode(SEGV_MTESERR), "");
+ EXPECT_EXIT(
+ {
+ ScopedSignalHandler ssh(SIGSEGV, ExitWithSiCode, SA_SIGINFO);
+ sink = p[-1];
+ },
+ testing::ExitedWithCode(SEGV_MTESERR), "");
EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC));
EXPECT_EXIT(
@@ -111,14 +128,21 @@
ScopedSignalHandler ssh(SIGSEGV, ExitWithSiCode, SA_SIGINFO);
p[-1] = 42;
},
- testing::ExitedWithCode(SEGV_MTEAERR), "");
+ Or(testing::ExitedWithCode(SEGV_MTESERR), testing::ExitedWithCode(SEGV_MTEAERR)), "");
+ EXPECT_EXIT(
+ {
+ ScopedSignalHandler ssh(SIGSEGV, ExitWithSiCode, SA_SIGINFO);
+ sink = p[-1];
+ },
+ Or(testing::ExitedWithCode(SEGV_MTESERR), testing::ExitedWithCode(SEGV_MTEAERR)), "");
EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_NONE));
- volatile int oob ATTRIBUTE_UNUSED = p[-1];
+ sink = p[-1];
#else
GTEST_SKIP() << "bionic/arm64 only";
#endif
}
+} // namespace
TEST(heap_tagging_level, none_pointers_untagged) {
#if defined(__BIONIC__)
@@ -205,7 +229,9 @@
const char* kNoteSuffix[] = {"disabled", "async", "sync"};
const char* kExpectedOutputHWASAN[] = {".*tag-mismatch.*", ".*tag-mismatch.*",
".*tag-mismatch.*"};
- const char* kExpectedOutputMTE[] = {"normal exit\n", "SEGV_MTEAERR\n", "SEGV_MTESERR\n"};
+ // Note that we do not check the exact si_code of the "async" variant, as it may be auto-upgraded
+ // to asymm or even sync.
+ const char* kExpectedOutputMTE[] = {"normal exit\n", "SEGV_MTE[AS]ERR\n", "SEGV_MTESERR\n"};
const char* kExpectedOutputNonMTE[] = {"normal exit\n", "normal exit\n", "normal exit\n"};
const char** kExpectedOutput =
withHWASAN ? kExpectedOutputHWASAN : (withMTE ? kExpectedOutputMTE : kExpectedOutputNonMTE);
@@ -215,7 +241,6 @@
bool isStatic = std::get<1>(GetParam());
std::string helper_base = std::string("heap_tagging_") + (isStatic ? "static_" : "") +
kNoteSuffix[static_cast<int>(note)] + "_helper";
- fprintf(stderr, "=== %s\n", helper_base.c_str());
std::string helper = GetTestlibRoot() + "/" + helper_base;
chmod(helper.c_str(), 0755);
ExecTestHelper eth;
diff --git a/tests/libs/heap_tagging_helper.cpp b/tests/libs/heap_tagging_helper.cpp
index 1a970f2..16a8c8b 100644
--- a/tests/libs/heap_tagging_helper.cpp
+++ b/tests/libs/heap_tagging_helper.cpp
@@ -16,7 +16,9 @@
#include <signal.h>
#include <stdio.h>
+#include <sys/auxv.h>
#include <sys/cdefs.h>
+#include <sys/mman.h>
#include <unistd.h>
#include <memory>
@@ -37,6 +39,11 @@
_exit(0);
}
+void action2(int signo, siginfo_t* info __unused, void*) {
+ fprintf(stderr, "unexpected signal %d\n", signo);
+ _exit(0);
+}
+
__attribute__((optnone)) int main() {
struct sigaction sa = {};
sa.sa_sigaction = action;
@@ -47,6 +54,37 @@
volatile int oob = p[-1];
(void)oob;
+#if defined(__BIONIC__) && defined(__aarch64__)
+ // If we get here, bad access on system heap memory did not trigger a fault.
+ // This suggests that MTE is disabled. Make sure that explicitly tagged PROT_MTE memory does not
+ // trigger a fault either.
+ if (getauxval(AT_HWCAP2) & HWCAP2_MTE) {
+ sa.sa_sigaction = action2;
+ sigaction(SIGSEGV, &sa, nullptr);
+
+ size_t page_size = static_cast<size_t>(sysconf(_SC_PAGESIZE));
+ void* p = mmap(nullptr, page_size, PROT_READ | PROT_WRITE | PROT_MTE,
+ MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+ if (!p) {
+ fprintf(stderr, "mmap failed\n");
+ return 1;
+ }
+
+ void* q = p;
+ __asm__ __volatile__(
+ ".arch_extension memtag\n"
+ "irg %[Ptr], %[Ptr], xzr\n"
+ "stg %[Ptr], [%[Ptr]]\n"
+ "addg %[Ptr], %[Ptr], 0, 1\n"
+ "str xzr, [%[Ptr]]\n"
+ : [Ptr] "+&r"(q)
+ :
+ : "memory");
+
+ munmap(p, page_size);
+ }
+#endif // __aarch64__
+
fprintf(stderr, "normal exit\n");
return 0;
}