fortify(stdio): emit diagnostics regardless of API level
Bug: 141267932
Test: m checkbuild on internal-master
Change-Id: I875a072c74f578d4404576c5bb42fd8ea30ff68d
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
index 8bb5b68..528d5fb 100644
--- a/libc/include/bits/fortify/stdio.h
+++ b/libc/include/bits/fortify/stdio.h
@@ -50,7 +50,23 @@
}
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int sprintf(char* dest, const char* format)
+ __overloadable
+ __enable_if(__bos_unevaluated_lt(__bos(dest), __builtin_strlen(format)),
+ "format string will always overflow destination buffer")
+ __errorattr("format string will always overflow destination buffer");
+
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_VARIADIC __printflike(2, 3)
+int sprintf(char* const __pass_object_size dest, const char* format, ...) __overloadable {
+ va_list va;
+ va_start(va, format);
+ int result = __builtin___vsprintf_chk(dest, 0, __bos(dest), format, va);
+ va_end(va);
+ return result;
+}
+
/* No diag -- clang diagnoses misuses of this on its own. */
__BIONIC_FORTIFY_VARIADIC __printflike(3, 4)
int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...)
@@ -61,26 +77,9 @@
va_end(va);
return result;
}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int sprintf(char* dest, const char* format)
- __overloadable
- __enable_if(__bos_unevaluated_lt(__bos(dest), __builtin_strlen(format)),
- "format string will always overflow destination buffer")
- __errorattr("format string will always overflow destination buffer");
-
-__BIONIC_FORTIFY_VARIADIC __printflike(2, 3)
-int sprintf(char* const __pass_object_size dest, const char* format, ...) __overloadable {
- va_list va;
- va_start(va, format);
- int result = __builtin___vsprintf_chk(dest, 0, __bos(dest), format, va);
- va_end(va);
- return result;
-}
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-#if __ANDROID_API__ >= __ANDROID_API_N__
-#define __bos_trivially_not_lt_mul(bos_val, size, count) \
+#define __bos_trivially_ge_mul(bos_val, size, count) \
__bos_dynamic_check_impl_and(bos_val, >=, (size) * (count), \
!__unsafe_check_mul_overflow(size, count))
@@ -91,12 +90,14 @@
"in call to 'fread', size * count overflows")
__clang_error_if(__bos_unevaluated_lt(__bos0(buf), size * count),
"in call to 'fread', size * count is too large for the given buffer") {
+#if __ANDROID_API__ >= __ANDROID_API_N__
size_t bos = __bos0(buf);
- if (__bos_trivially_not_lt_mul(bos, size, count)) {
- return __call_bypassing_fortify(fread)(buf, size, count, stream);
+ if (!__bos_trivially_ge_mul(bos, size, count)) {
+ return __fread_chk(buf, size, count, stream, bos);
}
- return __fread_chk(buf, size, count, stream, bos);
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+ return __call_bypassing_fortify(fread)(buf, size, count, stream);
}
__BIONIC_FORTIFY_INLINE
@@ -106,32 +107,31 @@
"in call to 'fwrite', size * count overflows")
__clang_error_if(__bos_unevaluated_lt(__bos0(buf), size * count),
"in call to 'fwrite', size * count is too large for the given buffer") {
+#if __ANDROID_API__ >= __ANDROID_API_N__
size_t bos = __bos0(buf);
- if (__bos_trivially_not_lt_mul(bos, size, count)) {
- return __call_bypassing_fortify(fwrite)(buf, size, count, stream);
+ if (!__bos_trivially_ge_mul(bos, size, count)) {
+ return __fwrite_chk(buf, size, count, stream, bos);
}
-
- return __fwrite_chk(buf, size, count, stream, bos);
-}
-#undef __bos_trivially_not_lt_mul
#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+ return __call_bypassing_fortify(fwrite)(buf, size, count, stream);
+}
+#undef __bos_trivially_ge_mul
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
__BIONIC_FORTIFY_INLINE
char* fgets(char* const __pass_object_size dest, int size, FILE* stream)
__overloadable
__clang_error_if(size < 0, "in call to 'fgets', size should not be negative")
__clang_error_if(__bos_unevaluated_lt(__bos(dest), size),
"in call to 'fgets', size is larger than the destination buffer") {
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
size_t bos = __bos(dest);
- if (__bos_dynamic_check_impl_and(bos, >=, (size_t)size, size >= 0)) {
- return __call_bypassing_fortify(fgets)(dest, size, stream);
+ if (!__bos_dynamic_check_impl_and(bos, >=, (size_t)size, size >= 0)) {
+ return __fgets_chk(dest, size, stream, bos);
}
-
- return __fgets_chk(dest, size, stream, bos);
-}
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+ return __call_bypassing_fortify(fgets)(dest, size, stream);
+}
#endif /* defined(__BIONIC_FORTIFY) */