stdio.h: enable vs?printf clang FORTIFY_SOURCE
Enable FORTIFY_SOURCE protections under clang for the following
functions:
* vsprintf
* vsnprintf
and add unittests.
Change-Id: I90f8a27f7b202c78b5dd8ebf53050bf9e33496f7
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index c453850..23fc944 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -454,7 +454,6 @@
__BEGIN_DECLS
-#if !defined(__clang__)
__BIONIC_FORTIFY_INLINE
__printflike(3, 0)
int vsnprintf(char *dest, size_t size, const char *format, __va_list ap)
@@ -468,7 +467,6 @@
{
return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
}
-#endif /* !defined(__clang__) */
#if defined(__clang__)
#define snprintf(dest, size, ...) __builtin___snprintf_chk(dest, size, 0, __bos(dest), __VA_ARGS__)
diff --git a/tests/fortify1_test.cpp b/tests/fortify1_test.cpp
index afc9b11..d4e9dd5 100644
--- a/tests/fortify1_test.cpp
+++ b/tests/fortify1_test.cpp
@@ -19,6 +19,7 @@
#include <gtest/gtest.h>
#include <string.h>
+#include <stdarg.h>
#if __BIONIC__
// We have to say "DeathTest" here so gtest knows to run this test (which exits)
@@ -106,6 +107,49 @@
ASSERT_EXIT(sprintf(buf, "aaaaa"), testing::KilledBySignal(SIGABRT), "");
}
+static int vsprintf_helper(const char *fmt, ...) {
+ char buf[10];
+ va_list va;
+ int result;
+
+ va_start(va, fmt);
+ result = vsprintf(buf, fmt, va); // should crash here
+ va_end(va);
+ return result;
+}
+
+TEST(Fortify1_DeathTest, vsprintf_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsprintf_helper("%s", "0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_DeathTest, vsprintf2_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsprintf_helper("0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+static int vsnprintf_helper(const char *fmt, ...) {
+ char buf[10];
+ va_list va;
+ int result;
+ size_t size = atoi("11");
+
+ va_start(va, fmt);
+ result = vsnprintf(buf, size, fmt, va); // should crash here
+ va_end(va);
+ return result;
+}
+
+TEST(Fortify1_DeathTest, vsnprintf_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsnprintf_helper("%s", "0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_DeathTest, vsnprintf2_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsnprintf_helper("0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
TEST(Fortify1_DeathTest, strncat_fortified) {
::testing::FLAGS_gtest_death_test_style = "threadsafe";
char buf[10];
diff --git a/tests/fortify1_test_clang.cpp b/tests/fortify1_test_clang.cpp
index 9f5b8b5..8759c41 100644
--- a/tests/fortify1_test_clang.cpp
+++ b/tests/fortify1_test_clang.cpp
@@ -19,6 +19,7 @@
#include <gtest/gtest.h>
#include <string.h>
+#include <stdarg.h>
#if __BIONIC__
// We have to say "DeathTest" here so gtest knows to run this test (which exits)
@@ -106,6 +107,49 @@
ASSERT_EXIT(sprintf(buf, "aaaaa"), testing::KilledBySignal(SIGABRT), "");
}
+static int vsprintf_helper(const char *fmt, ...) {
+ char buf[10];
+ va_list va;
+ int result;
+
+ va_start(va, fmt);
+ result = vsprintf(buf, fmt, va); // should crash here
+ va_end(va);
+ return result;
+}
+
+TEST(Fortify1_Clang_DeathTest, vsprintf_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsprintf_helper("%s", "0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_Clang_DeathTest, vsprintf2_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsprintf_helper("0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+static int vsnprintf_helper(const char *fmt, ...) {
+ char buf[10];
+ va_list va;
+ int result;
+ size_t size = atoi("11");
+
+ va_start(va, fmt);
+ result = vsnprintf(buf, size, fmt, va); // should crash here
+ va_end(va);
+ return result;
+}
+
+TEST(Fortify1_Clang_DeathTest, vsnprintf_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsnprintf_helper("%s", "0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify1_Clang_DeathTest, vsnprintf2_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsnprintf_helper("0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
TEST(Fortify1_Clang_DeathTest, strncat_fortified) {
::testing::FLAGS_gtest_death_test_style = "threadsafe";
char buf[10];
diff --git a/tests/fortify2_test.cpp b/tests/fortify2_test.cpp
index 9a13612..1fa34ca 100644
--- a/tests/fortify2_test.cpp
+++ b/tests/fortify2_test.cpp
@@ -19,6 +19,7 @@
#include <gtest/gtest.h>
#include <string.h>
+#include <stdarg.h>
struct foo {
char empty[0];
@@ -53,6 +54,49 @@
testing::KilledBySignal(SIGABRT), "");
}
+static int vsprintf_helper2(const char *fmt, ...) {
+ foo myfoo;
+ va_list va;
+ int result;
+
+ va_start(va, fmt);
+ result = vsprintf(myfoo.a, fmt, va); // should crash here
+ va_end(va);
+ return result;
+}
+
+TEST(Fortify2_DeathTest, vsprintf_fortified2) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsprintf_helper2("%s", "0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_DeathTest, vsprintf2_fortified2) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsprintf_helper2("0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+static int vsnprintf_helper2(const char *fmt, ...) {
+ foo myfoo;
+ va_list va;
+ int result;
+ size_t size = atoi("11");
+
+ va_start(va, fmt);
+ result = vsnprintf(myfoo.a, size, fmt, va); // should crash here
+ va_end(va);
+ return result;
+}
+
+TEST(Fortify2_DeathTest, vsnprintf_fortified2) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsnprintf_helper2("%s", "0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_DeathTest, vsnprintf2_fortified2) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsnprintf_helper2("0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
#if __BIONIC__
// zero sized target with "\0" source (should fail)
TEST(Fortify2_DeathTest, strcpy_fortified2) {
@@ -250,6 +294,49 @@
ASSERT_EXIT(sprintf(buf, "aaaaa"), testing::KilledBySignal(SIGABRT), "");
}
+static int vsprintf_helper(const char *fmt, ...) {
+ char buf[10];
+ va_list va;
+ int result;
+
+ va_start(va, fmt);
+ result = vsprintf(buf, fmt, va); // should crash here
+ va_end(va);
+ return result;
+}
+
+TEST(Fortify2_DeathTest, vsprintf_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsprintf_helper("%s", "0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_DeathTest, vsprintf2_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsprintf_helper("0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+static int vsnprintf_helper(const char *fmt, ...) {
+ char buf[10];
+ va_list va;
+ int result;
+ size_t size = atoi("11");
+
+ va_start(va, fmt);
+ result = vsnprintf(buf, size, fmt, va); // should crash here
+ va_end(va);
+ return result;
+}
+
+TEST(Fortify2_DeathTest, vsnprintf_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsnprintf_helper("%s", "0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_DeathTest, vsnprintf2_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsnprintf_helper("0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
TEST(Fortify2_DeathTest, strncat_fortified) {
::testing::FLAGS_gtest_death_test_style = "threadsafe";
char buf[10];
diff --git a/tests/fortify2_test_clang.cpp b/tests/fortify2_test_clang.cpp
index 7183bc0..83f57e8 100644
--- a/tests/fortify2_test_clang.cpp
+++ b/tests/fortify2_test_clang.cpp
@@ -19,6 +19,7 @@
#include <gtest/gtest.h>
#include <string.h>
+#include <stdarg.h>
struct foo {
char empty[0];
@@ -123,6 +124,49 @@
ASSERT_EXIT(sprintf(buf, "aaaaa"), testing::KilledBySignal(SIGABRT), "");
}
+static int vsprintf_helper(const char *fmt, ...) {
+ char buf[10];
+ va_list va;
+ int result;
+
+ va_start(va, fmt);
+ result = vsprintf(buf, fmt, va); // should crash here
+ va_end(va);
+ return result;
+}
+
+TEST(Fortify2_Clang_DeathTest, vsprintf_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsprintf_helper("%s", "0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_Clang_DeathTest, vsprintf2_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsprintf_helper("0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+static int vsnprintf_helper(const char *fmt, ...) {
+ char buf[10];
+ va_list va;
+ int result;
+ size_t size = atoi("11");
+
+ va_start(va, fmt);
+ result = vsnprintf(buf, size, fmt, va); // should crash here
+ va_end(va);
+ return result;
+}
+
+TEST(Fortify2_Clang_DeathTest, vsnprintf_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsnprintf_helper("%s", "0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
+TEST(Fortify2_Clang_DeathTest, vsnprintf2_fortified) {
+ ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+ ASSERT_EXIT(vsnprintf_helper("0123456789"), testing::KilledBySignal(SIGABRT), "");
+}
+
TEST(Fortify2_Clang_DeathTest, strncat_fortified) {
::testing::FLAGS_gtest_death_test_style = "threadsafe";
char buf[10];