libc: add clang FORTIFY support

This patch adds clang-style FORTIFY to Bionic. For more information on
FORTIFY, please see https://goo.gl/8HS2dW . This implementation works
for versions of clang that don't support diagnose_if, so please see the
"without diagnose_if" sections. We plan to swap to a diagnose_if-based
FORTIFY later this year (since it doesn't really add any features; it
just simplifies the implementation a lot, and it gives us much prettier
diagnostics)

Bug: 32073964
Test: Builds on angler, bullhead, marlin, sailfish. Bionic CTS tests
pass on Angler and Bullhead.

Change-Id: I607aecbeee81529709b1eee7bef5b0836151eb2b
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 63e782e..9492d92 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -181,12 +181,29 @@
 #define __wur __attribute__((__warn_unused_result__))
 
 #ifdef __clang__
-#define __errorattr(msg) __attribute__((unavailable(msg)))
+#  define __errorattr(msg) __attribute__((unavailable(msg)))
+#  define __warnattr(msg) __attribute__((deprecated(msg)))
+#  define __warnattr_real(msg) __attribute__((deprecated(msg)))
+#  define __enable_if(cond, msg) __attribute__((enable_if(cond, msg)))
 #else
-#define __errorattr(msg) __attribute__((__error__(msg)))
+#  define __errorattr(msg) __attribute__((__error__(msg)))
+#  define __warnattr(msg) __attribute__((__warning__(msg)))
+#  define __warnattr_real __warnattr
+/* enable_if doesn't exist on other compilers; give an error if it's used. */
+
+/* errordecls really don't work as well in clang as they do in GCC. */
+#  define __errordecl(name, msg) extern void name(void) __errorattr(msg)
 #endif
 
-#define __errordecl(name, msg) extern void name(void) __errorattr(msg)
+#if defined(ANDROID_STRICT)
+/*
+ * For things that are sketchy, but not necessarily an error. FIXME: Enable
+ * this.
+ */
+#  define __warnattr_strict(msg) /* __warnattr(msg) */
+#else
+#  define __warnattr_strict(msg)
+#endif
 
 /*
  * Some BSD source needs these macros.
@@ -242,21 +259,59 @@
  * See
  * http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html for details.
  */
+
+#define __BIONIC_FORTIFY_UNKNOWN_SIZE ((size_t) -1)
+
 #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0
 #  define __BIONIC_FORTIFY 1
 #  if _FORTIFY_SOURCE == 2
-#    define __bos(s) __builtin_object_size((s), 1)
+#    define __bos_level 1
 #  else
-#    define __bos(s) __builtin_object_size((s), 0)
+#    define __bos_level 0
 #  endif
-#  define __bos0(s) __builtin_object_size((s), 0)
+#  define __bosn(s, n) __builtin_object_size((s), (n))
+#  define __bos(s) __bosn((s), __bos_level)
+#  define __bos0(s) __bosn((s), 0)
 #  if defined(__clang__)
-#    define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline))
+#    define __pass_object_size_n(n) __attribute__((pass_object_size(n)))
+/*
+ * FORTIFY'ed functions all have either enable_if or pass_object_size, which
+ * makes taking their address impossible. Saying (&read)(foo, bar, baz); will
+ * therefore call the unFORTIFYed version of read.
+ */
+#    define __call_bypassing_fortify(fn) (&fn)
+/*
+ * Because clang-FORTIFY uses overloads, we can't mark functions as `extern
+ * inline` without making them available externally.
+ */
+#    define __BIONIC_FORTIFY_INLINE static __inline__ __always_inline
+/* Error functions don't have bodies, so they can just be static. */
+#    define __BIONIC_ERROR_FUNCTION_VISIBILITY static
 #  else
+/*
+ * Where they can, GCC and clang-style FORTIFY share implementations.
+ * So, make these nops in GCC.
+ */
+#    define __pass_object_size_n(n)
+#    define __call_bypassing_fortify(fn) (fn)
+/* __BIONIC_FORTIFY_NONSTATIC_INLINE is pointless in GCC's FORTIFY */
 #    define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__))
 #  endif
+#  define __pass_object_size __pass_object_size_n(__bos_level)
 #endif
-#define __BIONIC_FORTIFY_UNKNOWN_SIZE __BIONIC_CAST(static_cast, size_t, -1)
+
+/* Used to support clangisms with FORTIFY. This isn't in the FORTIFY section
+ * because these change how symbols are emitted. The linker must be kept happy.
+ */
+#ifdef __clang__
+#  define __overloadable __attribute__((overloadable))
+// Don't use __RENAME directly because on gcc, this could result in a number of
+// unnecessary renames.
+#  define __RENAME_CLANG(x) __RENAME(x)
+#else
+#  define __overloadable
+#  define __RENAME_CLANG(x)
+#endif
 
 /* Used to tag non-static symbols that are private and never exposed by the shared library. */
 #define __LIBC_HIDDEN__ __attribute__((visibility("hidden")))
@@ -303,5 +358,15 @@
  * build working.
  */
 #define __NDK_FPABI__
+#if defined(__clang__)
+/*
+ * Used when we need to check for overflow when multiplying x and y. This
+ * should only be used where __size_mul_overflow can not work, because it makes
+ * assumptions that __size_mul_overflow doesn't (x and y are positive, ...),
+ * *and* doesn't make use of compiler intrinsics, so it's probably slower than
+ * __size_mul_overflow.
+ */
+#define __unsafe_check_mul_overflow(x, y) ((__SIZE_TYPE__)-1 / (x) < (y))
+#endif
 
 #endif /* !_SYS_CDEFS_H_ */
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index f9f6764..997191e 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -317,25 +317,59 @@
 __socketcall int socket(int, int, int);
 __socketcall int socketpair(int, int, int, int*);
 
-ssize_t recv(int, void*, size_t, int);
+ssize_t recv(int, void*, size_t, int) __overloadable __RENAME_CLANG(recv);
 ssize_t send(int, const void*, size_t, int);
 
 __socketcall ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t);
-__socketcall ssize_t recvfrom(int, void*, size_t, int, struct sockaddr*, socklen_t*);
+__socketcall ssize_t recvfrom(int, void*, size_t, int, struct sockaddr*,
+        socklen_t*) __overloadable __RENAME_CLANG(recvfrom);
 
-__errordecl(__recvfrom_error, "recvfrom called with size bigger than buffer");
-ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*, socklen_t*)
-  __INTRODUCED_IN(21);
-ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
+ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
+        socklen_t*) __INTRODUCED_IN(21);
 
 #if defined(__BIONIC_FORTIFY)
 
+#if defined(__clang__)
 #if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t recvfrom(int fd, void* const buf __pass_object_size, size_t len,
+                 int flags, struct sockaddr* src_addr, socklen_t* addr_len)
+        __overloadable
+        __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+                    __bos(buf) < len, "selected when the buffer is too small")
+        __errorattr("size is larger than the destination buffer");
+
 __BIONIC_FORTIFY_INLINE
-ssize_t recvfrom(int fd, void* buf, size_t len, int flags, struct sockaddr* src_addr, socklen_t* addr_len) {
+ssize_t recvfrom(int fd, void* const buf __pass_object_size, size_t len,
+                 int flags, struct sockaddr* src_addr, socklen_t* addr_len)
+      __overloadable {
   size_t bos = __bos0(buf);
 
-#if !defined(__clang__)
+  if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+    return __call_bypassing_fortify(recvfrom)(fd, buf, len, flags, src_addr,
+              addr_len);
+  }
+
+  return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+__BIONIC_FORTIFY_INLINE
+ssize_t recv(int socket, void* const buf __pass_object_size, size_t len,
+             int flags) __overloadable {
+  return recvfrom(socket, buf, len, flags, NULL, 0);
+}
+
+#else /* defined(__clang__) */
+ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
+__errordecl(__recvfrom_error, "recvfrom called with size bigger than buffer");
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
+                 struct sockaddr* src_addr, socklen_t* addr_len) {
+  size_t bos = __bos0(buf);
+
   if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
     return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
   }
@@ -347,7 +381,6 @@
   if (__builtin_constant_p(len) && (len > bos)) {
     __recvfrom_error();
   }
-#endif
 
   return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
 }
@@ -358,6 +391,8 @@
   return recvfrom(socket, buf, len, flags, NULL, 0);
 }
 
+#endif /* defined(__clang__) */
+
 #endif /* __BIONIC_FORTIFY */
 
 #undef __socketcall
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index f961cf8..f8d854d 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -161,29 +161,52 @@
 int stat64(const char*, struct stat64*) __INTRODUCED_IN(21);
 
 int mknod(const char*, mode_t, dev_t);
-mode_t umask(mode_t);
+mode_t umask(mode_t) __overloadable __RENAME_CLANG(umask);
 
 mode_t __umask_chk(mode_t) __INTRODUCED_IN(18);
-mode_t __umask_real(mode_t) __RENAME(umask);
-__errordecl(__umask_invalid_mode, "umask called with invalid mode");
 
 #if defined(__BIONIC_FORTIFY)
+#define __umask_invalid_mode_str "umask called with invalid mode"
+
+#if defined(__clang__)
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
+/*
+ * Abuse enable_if to make these be seen as overloads of umask, rather than
+ * definitions.
+ */
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+mode_t umask(mode_t mode) __overloadable
+        __enable_if(1, "")
+        __enable_if(mode & ~0777, __umask_invalid_mode_str)
+        __errorattr(__umask_invalid_mode_str);
+
+__BIONIC_FORTIFY_INLINE
+mode_t umask(mode_t mode) __enable_if(1, "") __overloadable {
+  return __umask_chk(mode);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+
+#else /* defined(__clang__) */
+__errordecl(__umask_invalid_mode, __umask_invalid_mode_str);
+extern mode_t __umask_real(mode_t) __RENAME(umask);
 
 #if __ANDROID_API__ >= __ANDROID_API_J_MR2__
 __BIONIC_FORTIFY_INLINE
 mode_t umask(mode_t mode) {
-#if !defined(__clang__)
   if (__builtin_constant_p(mode)) {
     if ((mode & 0777) != mode) {
       __umask_invalid_mode();
     }
     return __umask_real(mode);
   }
-#endif
   return __umask_chk(mode);
 }
 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
 
+#endif /* defined(__clang__) */
+#undef __umask_invalid_mode_str
+
 #endif /* defined(__BIONIC_FORTIFY) */
 
 #if __ANDROID_API__ >= __ANDROID_API_L__