OSDN Git Service

Add stack canaries / strcpy tests.
authorNick Kralevich <nnk@google.com>
Fri, 11 Jan 2013 01:12:29 +0000 (17:12 -0800)
committerNick Kralevich <nnk@google.com>
Fri, 11 Jan 2013 18:52:36 +0000 (10:52 -0800)
Add a test to ensure that stack canaries are working
correctly. Since stack canaries aren't normally generated
on non-string functions, we have to enable stack-protector-all.

Add a test to ensure that an out of bounds strcpy generates
a runtime failure.

Change-Id: Id0d3e59fc4b9602da019e4d35c5c653e1a57fae4

tests/Android.mk
tests/stack_protector_test.cpp
tests/string_test.cpp

index a50232e..635c021 100644 (file)
@@ -47,7 +47,7 @@ include $(BUILD_EXECUTABLE)
 # -----------------------------------------------------------------------------
 
 test_c_flags = \
-    -fstack-protector \
+    -fstack-protector-all \
     -g \
     -Wall -Wextra \
     -Werror \
index 9d86506..9cf3c38 100644 (file)
@@ -114,4 +114,24 @@ TEST(stack_protector, global_guard) {
   ASSERT_NE(0U, reinterpret_cast<uintptr_t>(__stack_chk_guard));
 }
 
+/*
+ * When this function returns, the stack canary will be inconsistent
+ * with the previous value, which will generate a call to __stack_chk_fail(),
+ * eventually resulting in a SIGABRT.
+ *
+ * This must be marked with "__attribute__ ((noinline))", to ensure the
+ * compiler generates the proper stack guards around this function.
+ */
+__attribute__ ((noinline))
+static void do_modify_stack_chk_guard() {
+  __stack_chk_guard = (void *) 0x12345678;
+}
+
+// We have to say "DeathTest" here so gtest knows to run this test (which exits)
+// in its own process.
+TEST(stack_protector_DeathTest, modify_stack_protector) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  ASSERT_EXIT(do_modify_stack_chk_guard(), testing::KilledBySignal(SIGABRT), "");
+}
+
 #endif
index d55771c..3f7d500 100644 (file)
@@ -305,6 +305,19 @@ TEST(string, strcpy) {
   }
 }
 
+
+#if __BIONIC__
+// We have to say "DeathTest" here so gtest knows to run this test (which exits)
+// in its own process.
+TEST(string_DeathTest, strcpy_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  char *orig = strdup("0123456789");
+  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
+  free(orig);
+}
+#endif
+
 #if __BIONIC__
 TEST(string, strlcat) {
   StringTestState state(SMALL);