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
+}