Loading debuggerd/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -371,6 +371,11 @@ cc_test { }, }, sanitize: { memtag_heap: true, memtag_stack: true, }, shared_libs: [ "libbase", "libcutils", Loading debuggerd/debuggerd_test.cpp +50 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <linux/prctl.h> #include <malloc.h> #include <pthread.h> #include <setjmp.h> #include <stdlib.h> #include <sys/capability.h> #include <sys/mman.h> Loading Loading @@ -601,6 +602,55 @@ TEST_P(SizeParamCrasherTest, mte_underflow) { #endif } __attribute__((noinline)) void mte_illegal_setjmp_helper(jmp_buf& jump_buf) { // Because the detection of illegal setjmp is done relative to the SP in setjmp, // we need to make sure this stack frame is bigger than the one of setjmp. // TODO(fmayer): fix that bug and remove the workaround. volatile char buf[1024]; buf[0] = '1'; setjmp(jump_buf); } TEST_F(CrasherTest, mte_illegal_setjmp) { // This setjmp is illegal because it jumps back into a function that already returned. // Quoting man 3 setjmp: // If the function which called setjmp() returns before longjmp() is // called, the behavior is undefined. Some kind of subtle or // unsubtle chaos is sure to result. // https://man7.org/linux/man-pages/man3/longjmp.3.html #if defined(__aarch64__) if (!mte_supported()) { GTEST_SKIP() << "Requires MTE"; } int intercept_result; unique_fd output_fd; StartProcess([&]() { SetTagCheckingLevelSync(); jmp_buf jump_buf; mte_illegal_setjmp_helper(jump_buf); longjmp(jump_buf, 1); }); StartIntercept(&output_fd); FinishCrasher(); AssertDeath(SIGABRT); FinishIntercept(&intercept_result); ASSERT_EQ(1, intercept_result) << "tombstoned reported failure"; std::string result; ConsumeFd(std::move(output_fd), &result); // In our test-case, we have a NEGATIVE stack adjustment, which is being // interpreted as unsigned integer, and thus is "too large". // TODO(fmayer): fix the error message for this ASSERT_MATCH(result, R"(memtag_handle_longjmp: stack adjustment too large)"); #else GTEST_SKIP() << "Requires aarch64"; #endif } TEST_F(CrasherTest, mte_async) { #if defined(__aarch64__) if (!mte_supported()) { Loading Loading
debuggerd/Android.bp +5 −0 Original line number Diff line number Diff line Loading @@ -371,6 +371,11 @@ cc_test { }, }, sanitize: { memtag_heap: true, memtag_stack: true, }, shared_libs: [ "libbase", "libcutils", Loading
debuggerd/debuggerd_test.cpp +50 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <linux/prctl.h> #include <malloc.h> #include <pthread.h> #include <setjmp.h> #include <stdlib.h> #include <sys/capability.h> #include <sys/mman.h> Loading Loading @@ -601,6 +602,55 @@ TEST_P(SizeParamCrasherTest, mte_underflow) { #endif } __attribute__((noinline)) void mte_illegal_setjmp_helper(jmp_buf& jump_buf) { // Because the detection of illegal setjmp is done relative to the SP in setjmp, // we need to make sure this stack frame is bigger than the one of setjmp. // TODO(fmayer): fix that bug and remove the workaround. volatile char buf[1024]; buf[0] = '1'; setjmp(jump_buf); } TEST_F(CrasherTest, mte_illegal_setjmp) { // This setjmp is illegal because it jumps back into a function that already returned. // Quoting man 3 setjmp: // If the function which called setjmp() returns before longjmp() is // called, the behavior is undefined. Some kind of subtle or // unsubtle chaos is sure to result. // https://man7.org/linux/man-pages/man3/longjmp.3.html #if defined(__aarch64__) if (!mte_supported()) { GTEST_SKIP() << "Requires MTE"; } int intercept_result; unique_fd output_fd; StartProcess([&]() { SetTagCheckingLevelSync(); jmp_buf jump_buf; mte_illegal_setjmp_helper(jump_buf); longjmp(jump_buf, 1); }); StartIntercept(&output_fd); FinishCrasher(); AssertDeath(SIGABRT); FinishIntercept(&intercept_result); ASSERT_EQ(1, intercept_result) << "tombstoned reported failure"; std::string result; ConsumeFd(std::move(output_fd), &result); // In our test-case, we have a NEGATIVE stack adjustment, which is being // interpreted as unsigned integer, and thus is "too large". // TODO(fmayer): fix the error message for this ASSERT_MATCH(result, R"(memtag_handle_longjmp: stack adjustment too large)"); #else GTEST_SKIP() << "Requires aarch64"; #endif } TEST_F(CrasherTest, mte_async) { #if defined(__aarch64__) if (!mte_supported()) { Loading