fortify: fix overflow checks in unistd

We should only be calling _real versions of the functions that use this
if the input size is verifiably <= SSIZE_MAX. Otherwise, just fall
through to _chk and let that handle it.

Bug: 131861088
Test: mma && bionic-unit-tests
Change-Id: Iba04e486ef91ea1b3539ab6df6260429264e66b4
diff --git a/libc/include/bits/fortify/unistd.h b/libc/include/bits/fortify/unistd.h
index 543c3c7..547a168 100644
--- a/libc/include/bits/fortify/unistd.h
+++ b/libc/include/bits/fortify/unistd.h
@@ -67,7 +67,8 @@
                      "in call to '" #fn "', '" #what "' bytes overflows the given object")
 
 #define __bos_trivially_not_lt_no_overflow(bos_val, index)  \
-      __bos_dynamic_check_impl_and((bos_val), >=, (index), (bos_val) <= SSIZE_MAX)
+      ((__bos_dynamic_check_impl_and((bos_val), >=, (index), (bos_val) <= SSIZE_MAX) && \
+        __builtin_constant_p(index) && (index) <= SSIZE_MAX))
 
 #if __ANDROID_API__ >= __ANDROID_API_N__
 __BIONIC_FORTIFY_INLINE
diff --git a/tests/clang_fortify_tests.cpp b/tests/clang_fortify_tests.cpp
index e1ecfa5..5f87098 100644
--- a/tests/clang_fortify_tests.cpp
+++ b/tests/clang_fortify_tests.cpp
@@ -591,8 +591,6 @@
   EXPECT_FORTIFY_DEATH_STRUCT(getcwd(split.tiny_buffer, sizeof(split)));
 
   {
-    // FIXME: These should all die in FORTIFY. Headers are bugged.
-#ifdef COMPILATION_TESTS
     char* volatile unknown = small_buffer;
     const size_t count = static_cast<size_t>(SSIZE_MAX) + 1;
     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
@@ -607,7 +605,6 @@
     EXPECT_FORTIFY_DEATH(pwrite(kBogusFD, unknown, count, 0));
     // expected-error@+1{{'count' must be <= SSIZE_MAX}}
     EXPECT_FORTIFY_DEATH(pwrite64(kBogusFD, unknown, count, 0));
-#endif
   }
 }