Implement setjmp cookies on ARM.
Reuse the top bits of _JB_SIGFLAG field previously used to store a
boolean to store a cookie that's validated by [sig]longjmp to make it
harder to use as a ROP gadget. Additionally, encrypt saved registers
with the cookie so that an attacker can't modify a register's value to
a specific value without knowing the cookie.
Bug: http://b/23942752
Change-Id: Id0eb8d06916e89d5d776bfcaa9458f8826717ba3
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index a3b5885..944dac8 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -212,3 +212,30 @@
CHECK_FREGS;
}
}
+
+#if defined(__arm__)
+#define __JB_SIGFLAG 0
+#elif defined(__aarch64__)
+#define __JB_SIGFLAG 0
+#elif defined(__i386__)
+#define __JB_SIGFLAG 7
+#elif defined(__x86_64)
+#define __JB_SIGFLAG 8
+#endif
+
+TEST(setjmp, setjmp_cookie) {
+#if !defined(__mips__)
+ jmp_buf jb;
+ int value = setjmp(jb);
+ ASSERT_EQ(0, value);
+
+ long* sigflag = reinterpret_cast<long*>(jb) + __JB_SIGFLAG;
+
+ // Make sure there's actually a cookie.
+ EXPECT_NE(0, *sigflag & ~1);
+
+ // Wipe it out
+ *sigflag &= 1;
+ EXPECT_DEATH(longjmp(jb, 0), "");
+#endif
+}