Merge changes I557309b3,If5f47e0e
* changes:
fortify: add even more warnings
fortify: fix up a few diagnostics; add __wur to realpath
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
index 6e47daf..e766b20 100644
--- a/libc/include/bits/fortify/stdio.h
+++ b/libc/include/bits/fortify/stdio.h
@@ -39,6 +39,8 @@
#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)
+ __clang_error_if(__bos_unevaluated_lt(__bos(dest), size),
+ "in call to 'vsnprintf', size is larger than the destination buffer")
__overloadable {
return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
}
@@ -50,19 +52,10 @@
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
#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* dest, size_t size, 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(3, 4)
int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...)
+ __clang_error_if(__bos_unevaluated_lt(__bos(dest), size),
+ "in call to 'snprintf', size is larger than the destination buffer")
__overloadable {
va_list va;
va_start(va, format);
diff --git a/libc/include/bits/fortify/stdlib.h b/libc/include/bits/fortify/stdlib.h
index 0bb3d0d..623be58 100644
--- a/libc/include/bits/fortify/stdlib.h
+++ b/libc/include/bits/fortify/stdlib.h
@@ -36,10 +36,11 @@
#define __PATH_MAX 4096
char* realpath(const char* path, char* resolved)
+ __clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?")
__clang_error_if(__bos_unevaluated_lt(__bos(resolved), __PATH_MAX),
"'realpath' output parameter must be NULL or a pointer to a buffer "
- "with >= PATH_MAX bytes")
- __clang_error_if(!path, "'realpath': NULL path is never correct; flipped arguments?");
+ "with >= PATH_MAX bytes");
+
/* No need for a definition; the only issues we can catch are at compile-time. */
#undef __PATH_MAX
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index d5b8619..b66e3c6 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -90,7 +90,7 @@
long atol(const char* __s) __attribute_pure__;
long long atoll(const char* __s) __attribute_pure__;
-char* realpath(const char* __path, char* __resolved);
+__wur char* realpath(const char* __path, char* __resolved);
int system(const char* __command);
void* bsearch(const void* __key, const void* __base, size_t __nmemb, size_t __size, int (*__comparator)(const void* __lhs, const void* __rhs));
diff --git a/tests/Android.bp b/tests/Android.bp
index 97712d3..65c6035 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -284,6 +284,7 @@
name: "bionic_clang_fortify_tests_w_flags",
cflags: [
"-Wno-builtin-memcpy-chk-size",
+ "-Wno-format-security",
"-Wno-format-zero-length",
"-Wno-memset-transposed-args",
"-Wno-strlcpy-strlcat-size",
diff --git a/tests/clang_fortify_tests.cpp b/tests/clang_fortify_tests.cpp
index 4c4e510..e1ecfa5 100644
--- a/tests/clang_fortify_tests.cpp
+++ b/tests/clang_fortify_tests.cpp
@@ -55,6 +55,12 @@
#define __clang_error_if(...)
#undef __clang_warning_if
#define __clang_warning_if(...)
+
+// SOMETIMES_CONST allows clang to emit eager diagnostics when we're doing compilation tests, but
+// blocks them otherwise. This is needed for diagnostics emitted with __enable_if.
+#define SOMETIMES_CONST volatile
+#else
+#define SOMETIMES_CONST const
#endif
#include <err.h>
@@ -391,20 +397,17 @@
static void testStdlib() {
char path_buffer[PATH_MAX - 1];
-#if 0
- // expected-error@+2{{ignoring return value of function}}
-#endif
+ // expected-warning@+2{{ignoring return value of function}}
// expected-error@+1{{must be NULL or a pointer to a buffer with >= PATH_MAX bytes}}
realpath("/", path_buffer);
-#if 0
- // expected-error@+1{{ignoring return value of function}}
-#endif
+ // expected-warning@+1{{ignoring return value of function}}
realpath("/", nullptr);
- // FIXME: This should complain about flipped arguments, instead of objectsize.
- // expected-error@+1{{must be NULL or a pointer to a buffer with >= PATH_MAX bytes}}
+ // expected-warning@+2{{ignoring return value of function}}
+ // expected-error@+1{{flipped arguments?}}
realpath(nullptr, path_buffer);
+ // expected-warning@+2{{ignoring return value of function}}
// expected-error@+1{{flipped arguments?}}
realpath(nullptr, nullptr);
}
@@ -487,17 +490,18 @@
FORTIFY_TEST(stdio) {
char small_buffer[8] = {};
{
-#if 0
- // expected-error@+1{{may overflow the destination buffer}}
-#endif
+ // expected-error@+1{{size is larger than the destination buffer}}
EXPECT_FORTIFY_DEATH(snprintf(small_buffer, sizeof(small_buffer) + 1, ""));
va_list va;
-#if 0
- // expected-error@+1{{may overflow the destination buffer}}
-#endif
+ // expected-error@+2{{size is larger than the destination buffer}}
// expected-warning@+1{{format string is empty}}
EXPECT_FORTIFY_DEATH(vsnprintf(small_buffer, sizeof(small_buffer) + 1, "", va));
+
+ const char *SOMETIMES_CONST format_string = "aaaaaaaaa";
+
+ // expected-error@+1{{format string will always overflow}}
+ EXPECT_FORTIFY_DEATH(sprintf(small_buffer, format_string));
}
// expected-error@+1{{size should not be negative}}