Annotate vfork for hwasan.
Call a hwasan hook in the parent return path for vfork() to let hwasan
update its shadow. See https://github.com/google/sanitizers/issues/925
for more details.
Bug: 112438058
Test: bionic-unit-tests
Change-Id: I9a06800962913e822bd66e072012d0a2c5be453d
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index cb94e45..10c1710 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -628,6 +628,45 @@
ASSERT_NE(static_cast<uint64_t>(parent_tid), reinterpret_cast<uint64_t>(result));
}
+static void optimization_barrier(void* arg) {
+ asm volatile("" : : "r"(arg) : "memory");
+}
+
+__attribute__((noinline)) static void HwasanVforkTestChild() {
+ // Allocate a tagged region on stack and leave it there.
+ char x[10000];
+ optimization_barrier(x);
+ _exit(0);
+}
+
+__attribute__((noinline)) static void HwasanReadMemory(const char* p, size_t size) {
+ // Read memory byte-by-byte. This will blow up if the pointer tag in p does not match any memory
+ // tag in [p, p+size).
+ volatile char z;
+ for (size_t i = 0; i < size; ++i) {
+ z = p[i];
+ }
+}
+
+__attribute__((noinline, no_sanitize("hwaddress"))) static void HwasanVforkTestParent() {
+ // Allocate a region on stack, but don't tag it (see the function attribute).
+ // This depends on unallocated stack space at current function entry being untagged.
+ char x[10000];
+ optimization_barrier(x);
+ // Verify that contents of x[] are untagged.
+ HwasanReadMemory(x, sizeof(x));
+}
+
+TEST(UNISTD_TEST, hwasan_vfork) {
+ // Test hwasan annotation in vfork. This test is only interesting when built with hwasan, but it
+ // is supposed to work correctly either way.
+ if (vfork()) {
+ HwasanVforkTestParent();
+ } else {
+ HwasanVforkTestChild();
+ }
+}
+
class UNISTD_DEATHTEST : public BionicDeathTest {};
TEST_F(UNISTD_DEATHTEST, abort) {