Merge "Add test for invalid setjmp in MTE" into main
This commit is contained in:
commit
851c857420
|
@ -371,6 +371,11 @@ cc_test {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
sanitize: {
|
||||||
|
memtag_heap: true,
|
||||||
|
memtag_stack: true,
|
||||||
|
},
|
||||||
|
|
||||||
shared_libs: [
|
shared_libs: [
|
||||||
"libbase",
|
"libbase",
|
||||||
"libcutils",
|
"libcutils",
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <linux/prctl.h>
|
#include <linux/prctl.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <setjmp.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/capability.h>
|
#include <sys/capability.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
@ -601,6 +602,55 @@ TEST_P(SizeParamCrasherTest, mte_underflow) {
|
||||||
#endif
|
#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) {
|
TEST_F(CrasherTest, mte_async) {
|
||||||
#if defined(__aarch64__)
|
#if defined(__aarch64__)
|
||||||
if (!mte_supported()) {
|
if (!mte_supported()) {
|
||||||
|
|
Loading…
Reference in New Issue