libc: Split FORTIFY into its own headers
This patch cleans up our standard headers by moving most of the FORTIFY
cruft out in to its own sandbox. In order to include the *_chk and
*_real declarations, you can either enable FORTIFY, or `#define
__BIONIC_DECLARE_FORTIFY_HELPERS`.
Both sys/select.h and strings.h are explicitly ignored by this patch.
Both of these files have very small __BIONIC_FORTIFY blocks, and don't
define any actual FORTIFY'ed functions (just macros, and 3 *_chk
functions).
This patch also makes the versioner ignore the FORTIFY implementation
headers, since we're guaranteed to pick the FORTIFY'ed headers up when
looking at the regular headers. (...Not to mention that making the
FORTIFY'ed headers freestanding would be annoying to do and maintain for
~no benefit).
We bake the knowledge of where FORTIFY headers live directly into the
versioner. We could go with a more general approach (e.g. adding an -X
IGNORED_FILE flag that tells the versioner to ignore
$HEADER_PATH/$IGNORED_FILE), but we'd then have to repeat that for every
test, every manual invocation of the versioner, etc. for no benefit
that's obvious to me.
Bug: 12231437
Test: m checkbuild on bullhead internal master + CtsBionicTestCases. no
new errors.
Change-Id: Iffc0cc609009b33d989cdaddde0a809282131a5b
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index ca56437..d2f2bd2 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -259,265 +259,9 @@
#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
#endif /* __USE_BSD */
-char* __fgets_chk(char*, int, FILE*, size_t) __INTRODUCED_IN(17);
-size_t __fread_chk(void* __restrict, size_t, size_t, FILE* __restrict, size_t)
- __INTRODUCED_IN(24);
-size_t __fwrite_chk(const void* __restrict, size_t, size_t, FILE* __restrict, size_t)
- __INTRODUCED_IN(24);
-
-#if defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY)
-
-#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 *_Nonnull 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 *_Nonnull format,
- __va_list ap) __overloadable {
- return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if defined(__clang__)
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-/*
- * Simple case: `format` can't have format specifiers, so we can just compare
- * its length to the length of `dest`
- */
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int snprintf(char *__restrict dest, size_t size, const char *__restrict format)
- __overloadable
- __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __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 *__restrict const __pass_object_size dest,
- size_t size, const char *__restrict format, ...) __overloadable {
- va_list va;
- va_start(va, format);
- int result = __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, va);
- va_end(va);
- return result;
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int sprintf(char *__restrict dest, const char *__restrict format) __overloadable
- __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos(dest) < __builtin_strlen(format),
- "format string will always overflow destination buffer")
- __errorattr("format string will always overflow destination buffer");
-
-__BIONIC_FORTIFY_INLINE
-__printflike(2, 3)
-int sprintf(char *__restrict const __pass_object_size dest,
- const char *__restrict 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__
-__BIONIC_FORTIFY_INLINE
-size_t fread(void *__restrict buf, size_t size, size_t count,
- FILE *__restrict stream) __overloadable
- __enable_if(__unsafe_check_mul_overflow(size, count), "size * count overflows")
- __errorattr("size * count overflows");
-
-__BIONIC_FORTIFY_INLINE
-size_t fread(void *__restrict buf, size_t size, size_t count,
- FILE *__restrict 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 *__restrict const __pass_object_size0 buf, size_t size,
- size_t count, FILE *__restrict stream) __overloadable {
- 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 * __restrict buf, size_t size,
- size_t count, FILE * __restrict stream) __overloadable
- __enable_if(__unsafe_check_mul_overflow(size, count),
- "size * count overflows")
- __errorattr("size * count overflows");
-
-size_t fwrite(const void * __restrict buf, size_t size,
- size_t count, FILE * __restrict 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 * __restrict const __pass_object_size0 buf,
- size_t size, size_t count, FILE * __restrict stream)
- __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(fwrite)(buf, size, count, stream);
- }
-
- return __fwrite_chk(buf, size, count, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char *fgets(char* __restrict 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* __restrict const __pass_object_size dest,
- int size, FILE* stream) __overloadable {
- size_t bos = __bos(dest);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(fgets)(dest, size, stream);
- }
-
- return __fgets_chk(dest, size, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#else /* defined(__clang__) */
-
-size_t __fread_real(void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fread);
-__errordecl(__fread_too_big_error, "fread called with size * count bigger than buffer");
-__errordecl(__fread_overflow, "fread called with overflowing size * count");
-
-char* __fgets_real(char*, int, FILE*) __RENAME(fgets);
-__errordecl(__fgets_too_big_error, "fgets called with size bigger than buffer");
-__errordecl(__fgets_too_small_error, "fgets called with size less than zero");
-
-size_t __fwrite_real(const void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fwrite);
-__errordecl(__fwrite_too_big_error, "fwrite called with size * count bigger than buffer");
-__errordecl(__fwrite_overflow, "fwrite called with overflowing size * count");
-
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE __printflike(3, 4)
-int snprintf(char *__restrict dest, size_t size, const char* _Nonnull format, ...)
-{
- return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format,
- __builtin_va_arg_pack());
-}
-
-__BIONIC_FORTIFY_INLINE __printflike(2, 3)
-int sprintf(char *__restrict dest, const char* _Nonnull format, ...) {
- return __builtin___sprintf_chk(dest, 0, __bos(dest), format,
- __builtin_va_arg_pack());
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-size_t fread(void *__restrict buf, size_t size, size_t count, FILE * __restrict stream) {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __fread_real(buf, size, count, stream);
- }
-
- if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
- size_t total;
- if (__size_mul_overflow(size, count, &total)) {
- __fread_overflow();
- }
-
- if (total > bos) {
- __fread_too_big_error();
- }
-
- return __fread_real(buf, size, count, stream);
- }
-
- return __fread_chk(buf, size, count, stream, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict stream) {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __fwrite_real(buf, size, count, stream);
- }
-
- if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
- size_t total;
- if (__size_mul_overflow(size, count, &total)) {
- __fwrite_overflow();
- }
-
- if (total > bos) {
- __fwrite_too_big_error();
- }
-
- return __fwrite_real(buf, size, count, stream);
- }
-
- return __fwrite_chk(buf, size, count, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-char *fgets(char* dest, int size, FILE* stream) {
- size_t bos = __bos(dest);
-
- // Compiler can prove, at compile time, that the passed in size
- // is always negative. Force a compiler error.
- if (__builtin_constant_p(size) && (size < 0)) {
- __fgets_too_small_error();
- }
-
- // Compiler doesn't know destination size. Don't call __fgets_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __fgets_real(dest, size, stream);
- }
-
- // Compiler can prove, at compile time, that the passed in size
- // is always <= the actual object size. Don't call __fgets_chk
- if (__builtin_constant_p(size) && (size <= (int) bos)) {
- return __fgets_real(dest, size, stream);
- }
-
- // Compiler can prove, at compile time, that the passed in size
- // is always > the actual object size. Force a compiler error.
- if (__builtin_constant_p(size) && (size > (int) bos)) {
- __fgets_too_big_error();
- }
-
- return __fgets_chk(dest, size, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#endif /* defined(__clang__) */
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/stdio.h>
+#endif
#if defined(__clang__)
#pragma clang diagnostic pop