From 78d6d9888c24c50f65d694dc8283afdcb58db84c Mon Sep 17 00:00:00 2001
From: Nick Kralevich <nnk@google.com>
Date: Mon, 29 Apr 2013 16:29:37 -0700
Subject: [PATCH] libc: upgrade sprintf to _FORTIFY_SOURCE=2

Upgrade sprintf to fortify_source level 2, to catch
additional security bugs.

Change-Id: Ibc957d65e4cb96152de84b3745a04e00fa22659e
---
 libc/include/stdio.h     |  2 +-
 libc/include/sys/cdefs.h |  4 ++--
 tests/fortify1_test.cpp  |  8 ++++++++
 tests/fortify2_test.cpp  | 23 ++++++++++++++++++++++-
 4 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index fdf747d1f..fddad2f2e 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -494,7 +494,7 @@ __attribute__((__nonnull__ (2)))
 int sprintf(char *dest, const char *format, ...)
 {
     return __builtin___sprintf_chk(dest, 0,
-        __builtin_object_size(dest, 0), format, __builtin_va_arg_pack());
+        __bos(dest), format, __builtin_va_arg_pack());
 }
 
 extern char *__fgets_real(char *, int, FILE *)
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 1288b28a2..6d4abbd83 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -518,9 +518,9 @@
 #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 && !defined(__clang__)
 #define __BIONIC_FORTIFY 1
 #if _FORTIFY_SOURCE == 2
-#define __bos(s) __builtin_object_size((s), 1);
+#define __bos(s) __builtin_object_size((s), 1)
 #else
-#define __bos(s) __builtin_object_size((s), 0);
+#define __bos(s) __builtin_object_size((s), 0)
 #endif
 
 #define __BIONIC_FORTIFY_INLINE \
diff --git a/tests/fortify1_test.cpp b/tests/fortify1_test.cpp
index 0cbb8cf67..e23719309 100644
--- a/tests/fortify1_test.cpp
+++ b/tests/fortify1_test.cpp
@@ -52,3 +52,11 @@ TEST(Fortify1_DeathTest, strrchr_fortified) {
   ASSERT_EXIT(printf("%s", strrchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
 }
 #endif
+
+TEST(Fortify1_DeathTest, sprintf_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  char source_buf[15];
+  memcpy(source_buf, "12345678901234", 15);
+  ASSERT_EXIT(sprintf(buf, "%s", source_buf), testing::KilledBySignal(SIGSEGV), "");
+}
diff --git a/tests/fortify2_test.cpp b/tests/fortify2_test.cpp
index 9bedbe504..f1a2eb9ea 100644
--- a/tests/fortify2_test.cpp
+++ b/tests/fortify2_test.cpp
@@ -27,7 +27,7 @@ struct foo {
 
 // We have to say "DeathTest" here so gtest knows to run this test (which exits)
 // in its own process.
-TEST(Fortify2_DeathTest, strncpy_fortified) {
+TEST(Fortify2_DeathTest, strncpy_fortified2) {
   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
   foo myfoo;
   int copy_amt = atoi("11");
@@ -35,6 +35,19 @@ TEST(Fortify2_DeathTest, strncpy_fortified) {
               testing::KilledBySignal(SIGSEGV), "");
 }
 
+TEST(Fortify2_DeathTest, sprintf_fortified2) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  foo myfoo;
+  char source_buf[15];
+  memcpy(source_buf, "12345678901234", 15);
+  ASSERT_EXIT(sprintf(myfoo.a, "%s", source_buf),
+              testing::KilledBySignal(SIGSEGV), "");
+}
+
+/***********************************************************/
+/* TESTS BELOW HERE DUPLICATE TESTS FROM fortify1_test.cpp */
+/***********************************************************/
+
 #if __BIONIC__
 TEST(Fortify2_DeathTest, strcpy_fortified) {
   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
@@ -65,3 +78,11 @@ TEST(Fortify2_DeathTest, strrchr_fortified) {
   ASSERT_EXIT(printf("%s", strrchr(buf, 'a')), testing::KilledBySignal(SIGSEGV), "");
 }
 #endif
+
+TEST(Fortify2_DeathTest, sprintf_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[10];
+  char source_buf[15];
+  memcpy(source_buf, "12345678901234", 15);
+  ASSERT_EXIT(sprintf(buf, "%s", source_buf), testing::KilledBySignal(SIGSEGV), "");
+}