_FORTIFY_SOURCE: check for integer overflows

Ensure that strcat / strncat check for integer overflows
when computing the length of the resulting string.

Change-Id: Ib806ad33a0d3b50876f384bc17787a28f0dddc37
diff --git a/libc/Android.mk b/libc/Android.mk
index 70a5243..f2784fd 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -537,7 +537,8 @@
 libc_common_c_includes := \
 		$(LOCAL_PATH)/stdlib  \
 		$(LOCAL_PATH)/string  \
-		$(LOCAL_PATH)/stdio
+		$(LOCAL_PATH)/stdio   \
+		external/safe-iop/include
 
 # Needed to access private/__dso_handle.h from
 # crtbegin_xxx.S and crtend_xxx.S
diff --git a/libc/string/__strcat_chk.c b/libc/string/__strcat_chk.c
index 3e02052..7d8c89f 100644
--- a/libc/string/__strcat_chk.c
+++ b/libc/string/__strcat_chk.c
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <private/logd.h>
+#include <safe_iop.h>
 
 /*
  * Runtime implementation of __builtin____strcat_chk.
@@ -46,8 +47,12 @@
     // TODO: optimize so we don't scan src/dest twice.
     size_t src_len  = strlen(src);
     size_t dest_len = strlen(dest);
+    size_t sum;
 
-    if (src_len + dest_len + 1 > dest_buf_size) {
+    // sum = src_len + dest_len + 1 (with overflow protection)
+    if (!safe_add3(&sum, src_len, dest_len, 1U)) abort();
+
+    if (sum > dest_buf_size) {
         __libc_android_log_print(ANDROID_LOG_FATAL, "libc",
             "*** strcat buffer overflow detected ***\n");
         abort();
diff --git a/libc/string/__strncat_chk.c b/libc/string/__strncat_chk.c
index 9b0b84a..0387626 100644
--- a/libc/string/__strncat_chk.c
+++ b/libc/string/__strncat_chk.c
@@ -29,6 +29,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <private/logd.h>
+#include <safe_iop.h>
 
 /*
  * Runtime implementation of __builtin____strncat_chk.
@@ -51,7 +52,11 @@
         src_len = len;
     }
 
-    if (dest_len + src_len + 1 > dest_buf_size) {
+    size_t sum;
+    // sum = src_len + dest_len + 1 (with overflow protection)
+    if (!safe_add3(&sum, src_len, dest_len, 1U)) abort();
+
+    if (sum > dest_buf_size) {
         __libc_android_log_print(ANDROID_LOG_FATAL, "libc",
             "*** strncat buffer overflow detected ***\n");
         abort();