FORTIFY_SOURCE: introduce __strncpy_chk2

This change detects programs reading beyond the end of "src" when
calling strncpy.

Change-Id: Ie1b42de923385d62552b22c27b2d4713ab77ee03
diff --git a/libc/include/string.h b/libc/include/string.h
index 7801ee9..5409391 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -119,14 +119,26 @@
 }
 
 __errordecl(__strncpy_error, "strncpy called with size bigger than buffer");
+extern char* __strncpy_chk2(char* __restrict, const char* __restrict, size_t, size_t, size_t);
 
 __BIONIC_FORTIFY_INLINE
 char* strncpy(char* __restrict dest, const char* __restrict src, size_t n) {
-    size_t bos = __bos(dest);
-    if (__builtin_constant_p(n) && (n > bos)) {
+    size_t bos_dest = __bos(dest);
+    size_t bos_src = __bos(src);
+    if (__builtin_constant_p(n) && (n > bos_dest)) {
         __strncpy_error();
     }
-    return __builtin___strncpy_chk(dest, src, n, bos);
+
+    if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+        return __builtin___strncpy_chk(dest, src, n, bos_dest);
+    }
+
+    size_t slen = __builtin_strlen(src);
+    if (__builtin_constant_p(slen)) {
+        return __builtin___strncpy_chk(dest, src, n, bos_dest);
+    }
+
+    return __strncpy_chk2(dest, src, n, bos_dest, bos_src);
 }
 
 __BIONIC_FORTIFY_INLINE