libc fortify: make stdio.h use diagnose_if
This also throws in some reformatting to match the GCC FORTIFY style in
this file (e.g. 4 space standard indent).
Per b/36984245, some function protos are unwrapped beyond 100 chars, as
well.
Bug: 12231437
Test: m checkbuild on bionic internal master; CtsBionicTestCases show
no new failures.
Change-Id: I6dce60ec14d5cd703d9e724699634a197ca11023
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
index 4acefd7..cfc78d7 100644
--- a/libc/include/bits/fortify/stdio.h
+++ b/libc/include/bits/fortify/stdio.h
@@ -38,13 +38,13 @@
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
__BIONIC_FORTIFY_INLINE __printflike(3, 0)
-int vsnprintf(char *const __pass_object_size dest, size_t size,
- const char * format, va_list ap) __overloadable {
+int vsnprintf(char* const __pass_object_size dest, size_t size, const char* format, va_list ap)
+ __overloadable {
return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
}
__BIONIC_FORTIFY_INLINE __printflike(2, 0)
-int vsprintf(char *const __pass_object_size dest, const char* format, va_list ap) __overloadable {
+int vsprintf(char* const __pass_object_size dest, const char* format, va_list ap) __overloadable {
return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
}
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
@@ -59,14 +59,14 @@
int snprintf(char* dest, size_t size, const char* format)
__overloadable
__enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos(dest) < __builtin_strlen(format),
+ __bos(dest) < __builtin_strlen(format),
"format string will always overflow destination buffer")
__errorattr("format string will always overflow destination buffer");
__BIONIC_FORTIFY_INLINE
__printflike(3, 4)
-int snprintf(char* const __pass_object_size dest,
- size_t size, const char* format, ...) __overloadable {
+int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...)
+ __overloadable {
va_list va;
va_start(va, format);
int result = __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, va);
@@ -75,7 +75,8 @@
}
__BIONIC_ERROR_FUNCTION_VISIBILITY
-int sprintf(char* dest, const char* format) __overloadable
+int sprintf(char* dest, const char* format)
+ __overloadable
__enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
__bos(dest) < __builtin_strlen(format),
"format string will always overflow destination buffer")
@@ -94,44 +95,27 @@
#if __ANDROID_API__ >= __ANDROID_API_N__
__BIONIC_FORTIFY_INLINE
-size_t fread(void* buf, size_t size, size_t count,
- FILE* stream) __overloadable
- __enable_if(__unsafe_check_mul_overflow(size, count), "size * count overflows")
- __errorattr("size * count overflows");
-
-__BIONIC_FORTIFY_INLINE
-size_t fread(void* buf, size_t size, size_t count, FILE* stream) __overloadable
- __enable_if(!__unsafe_check_mul_overflow(size, count), "no overflow")
- __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- size * count > __bos(buf), "size * count is too large")
- __errorattr("size * count is too large");
-
-__BIONIC_FORTIFY_INLINE
-size_t fread(void* const __pass_object_size0 buf, size_t size,
- size_t count, FILE* stream) __overloadable {
+size_t fread(void* const __pass_object_size0 buf, size_t size, size_t count, FILE* stream)
+ __overloadable
+ __clang_error_if(__unsafe_check_mul_overflow(size, count),
+ "in call to 'fread', size * count overflows")
+ __clang_error_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && size * count > __bos(buf),
+ "in call to 'fread', size * count is too large for the given buffer") {
size_t bos = __bos0(buf);
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
return __call_bypassing_fortify(fread)(buf, size, count, stream);
}
-
return __fread_chk(buf, size, count, stream, bos);
}
-size_t fwrite(const void* buf, size_t size, size_t count, FILE* stream) __overloadable
- __enable_if(__unsafe_check_mul_overflow(size, count),
- "size * count overflows")
- __errorattr("size * count overflows");
-
-size_t fwrite(const void* buf, size_t size, size_t count, FILE* stream) __overloadable
- __enable_if(!__unsafe_check_mul_overflow(size, count), "no overflow")
- __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- size * count > __bos(buf), "size * count is too large")
- __errorattr("size * count is too large");
-
__BIONIC_FORTIFY_INLINE
size_t fwrite(const void* const __pass_object_size0 buf, size_t size, size_t count, FILE* stream)
- __overloadable {
+ __overloadable
+ __clang_error_if(__unsafe_check_mul_overflow(size, count),
+ "in call to 'fwrite', size * count overflows")
+ __clang_error_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && size * count > __bos(buf),
+ "in call to 'fwrite', size * count is too large for the given buffer") {
size_t bos = __bos0(buf);
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
@@ -143,19 +127,12 @@
#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char *fgets(char* dest, int size, FILE* stream) __overloadable
- __enable_if(size < 0, "size is negative")
- __errorattr("size is negative");
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char *fgets(char* dest, int size, FILE* stream) __overloadable
- __enable_if(size >= 0 && size > __bos(dest),
- "size is larger than the destination buffer")
- __errorattr("size is larger than the destination buffer");
-
__BIONIC_FORTIFY_INLINE
-char *fgets(char* const __pass_object_size dest, int size, FILE* stream) __overloadable {
+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(size > __bos(dest),
+ "in call to 'fgets', size is larger than the destination buffer") {
size_t bos = __bos(dest);
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
diff --git a/tests/fortify_compilation_test.cpp b/tests/fortify_compilation_test.cpp
index bb2b770..74229e0 100644
--- a/tests/fortify_compilation_test.cpp
+++ b/tests/fortify_compilation_test.cpp
@@ -169,12 +169,12 @@
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__fgets_too_small_error' declared with attribute error: fgets called with size less than zero
- // CLANG: error: call to unavailable function 'fgets': size is negative
+ // CLANG: error: in call to 'fgets', size should not be negative
fgets(buf, -1, stdin);
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__fgets_too_big_error' declared with attribute error: fgets called with size bigger than buffer
- // CLANG: error: call to unavailable function 'fgets': size is larger than the destination buffer
+ // CLANG: error: in call to 'fgets', size is larger than the destination buffer
fgets(buf, 6, stdin);
}
@@ -236,7 +236,7 @@
char buf[4];
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__fread_overflow' declared with attribute error: fread called with overflowing size * count
- // CLANG: error: call to unavailable function 'fread': size * count overflows
+ // CLANG: error: in call to 'fread', size * count overflows
fread(buf, 2, (size_t)-1, stdin);
}
@@ -244,7 +244,8 @@
char buf[4];
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__fread_too_big_error' declared with attribute error: fread called with size * count bigger than buffer
- // CLANG: error: call to unavailable function 'fread': size * count is too large
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // CLANG: error: in call to 'fread', size * count is too large for the given buffer
fread(buf, 1, 5, stdin);
}
@@ -252,7 +253,7 @@
char buf[4] = {0};
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__fwrite_overflow' declared with attribute error: fwrite called with overflowing size * count
- // CLANG: error: call to unavailable function 'fwrite': size * count overflows
+ // CLANG: error: in call to 'fwrite', size * count overflows
fwrite(buf, 2, (size_t)-1, stdout);
}
@@ -260,7 +261,8 @@
char buf[4] = {0};
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__fwrite_too_big_error' declared with attribute error: fwrite called with size * count bigger than buffer
- // CLANG: error: call to unavailable function 'fwrite': size * count is too large
+ // NOLINTNEXTLINE(whitespace/line_length)
+ // CLANG: error: in call to 'fwrite', size * count is too large for the given buffer
fwrite(buf, 1, 5, stdout);
}