Merge "fortify: account for new clang diagnostics"
am: e6c3f0628c
Change-Id: I3ba482efe59627720f4793e44dc9fc7f87856bcf
This commit is contained in:
commit
41e6d0ca78
3 changed files with 33 additions and 40 deletions
|
@ -37,10 +37,9 @@ size_t __fwrite_chk(const void*, size_t, size_t, FILE*, size_t) __INTRODUCED_IN(
|
||||||
#if defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY)
|
#if defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY)
|
||||||
|
|
||||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
||||||
|
/* No diag -- clang diagnoses misuses of this on its own. */
|
||||||
__BIONIC_FORTIFY_INLINE __printflike(3, 0)
|
__BIONIC_FORTIFY_INLINE __printflike(3, 0)
|
||||||
int vsnprintf(char* const __pass_object_size dest, size_t size, const char* format, va_list ap)
|
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 {
|
__overloadable {
|
||||||
return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
|
return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
|
||||||
}
|
}
|
||||||
|
@ -52,10 +51,9 @@ int vsprintf(char* const __pass_object_size dest, const char* format, va_list ap
|
||||||
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
|
#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
|
||||||
|
|
||||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
||||||
|
/* No diag -- clang diagnoses misuses of this on its own. */
|
||||||
__BIONIC_FORTIFY_VARIADIC __printflike(3, 4)
|
__BIONIC_FORTIFY_VARIADIC __printflike(3, 4)
|
||||||
int snprintf(char* const __pass_object_size dest, size_t size, const char* format, ...)
|
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 {
|
__overloadable {
|
||||||
va_list va;
|
va_list va;
|
||||||
va_start(va, format);
|
va_start(va, format);
|
||||||
|
|
|
@ -41,11 +41,10 @@ size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
|
||||||
extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
|
extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
|
||||||
|
|
||||||
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
|
||||||
|
/* No diag -- clang diagnoses misuses of this on its own. */
|
||||||
__BIONIC_FORTIFY_INLINE
|
__BIONIC_FORTIFY_INLINE
|
||||||
void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
|
void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
|
||||||
__overloadable
|
__overloadable {
|
||||||
__clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
|
|
||||||
"'memcpy' called with size bigger than buffer") {
|
|
||||||
size_t bos_dst = __bos0(dst);
|
size_t bos_dst = __bos0(dst);
|
||||||
if (__bos_trivially_not_lt(bos_dst, copy_amount)) {
|
if (__bos_trivially_not_lt(bos_dst, copy_amount)) {
|
||||||
return __builtin_memcpy(dst, src, copy_amount);
|
return __builtin_memcpy(dst, src, copy_amount);
|
||||||
|
@ -53,11 +52,9 @@ void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_a
|
||||||
return __builtin___memcpy_chk(dst, src, copy_amount, bos_dst);
|
return __builtin___memcpy_chk(dst, src, copy_amount, bos_dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No diag -- clang diagnoses misuses of this on its own. */
|
||||||
__BIONIC_FORTIFY_INLINE
|
__BIONIC_FORTIFY_INLINE
|
||||||
void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
|
void* memmove(void* const dst __pass_object_size0, const void* src, size_t len) __overloadable {
|
||||||
__overloadable
|
|
||||||
__clang_error_if(__bos_unevaluated_lt(__bos0(dst), len),
|
|
||||||
"'memmove' called with size bigger than buffer") {
|
|
||||||
size_t bos_dst = __bos0(dst);
|
size_t bos_dst = __bos0(dst);
|
||||||
if (__bos_trivially_not_lt(bos_dst, len)) {
|
if (__bos_trivially_not_lt(bos_dst, len)) {
|
||||||
return __builtin_memmove(dst, src, len);
|
return __builtin_memmove(dst, src, len);
|
||||||
|
@ -117,19 +114,15 @@ char* strcat(char* const dst __pass_object_size, const char* src)
|
||||||
return __builtin___strcat_chk(dst, src, __bos(dst));
|
return __builtin___strcat_chk(dst, src, __bos(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No diag -- clang diagnoses misuses of this on its own. */
|
||||||
__BIONIC_FORTIFY_INLINE
|
__BIONIC_FORTIFY_INLINE
|
||||||
char* strncat(char* const dst __pass_object_size, const char* src, size_t n)
|
char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable {
|
||||||
__overloadable
|
|
||||||
__clang_error_if(__bos_unevaluated_lt(__bos(dst), n),
|
|
||||||
"'strncat' called with size bigger than buffer") {
|
|
||||||
return __builtin___strncat_chk(dst, src, n, __bos(dst));
|
return __builtin___strncat_chk(dst, src, n, __bos(dst));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No diag -- clang diagnoses misuses of this on its own. */
|
||||||
__BIONIC_FORTIFY_INLINE
|
__BIONIC_FORTIFY_INLINE
|
||||||
void* memset(void* const s __pass_object_size0, int c, size_t n)
|
void* memset(void* const s __pass_object_size0, int c, size_t n) __overloadable
|
||||||
__overloadable
|
|
||||||
__clang_error_if(__bos_unevaluated_lt(__bos0(s), n),
|
|
||||||
"'memset' called with size bigger than buffer")
|
|
||||||
/* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
|
/* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
|
||||||
__clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
|
__clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
|
||||||
size_t bos = __bos0(s);
|
size_t bos = __bos0(s);
|
||||||
|
@ -165,11 +158,10 @@ void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n)
|
||||||
#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
|
#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
|
||||||
|
|
||||||
#if __ANDROID_API__ >= __ANDROID_API_L__
|
#if __ANDROID_API__ >= __ANDROID_API_L__
|
||||||
|
/* No diag -- clang diagnoses misuses of this on its own. */
|
||||||
__BIONIC_FORTIFY_INLINE
|
__BIONIC_FORTIFY_INLINE
|
||||||
char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
|
char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
|
||||||
__overloadable
|
__overloadable {
|
||||||
__clang_error_if(__bos_unevaluated_lt(__bos(dst), n),
|
|
||||||
"'stpncpy' called with size bigger than buffer") {
|
|
||||||
size_t bos_dst = __bos(dst);
|
size_t bos_dst = __bos(dst);
|
||||||
size_t bos_src = __bos(src);
|
size_t bos_src = __bos(src);
|
||||||
|
|
||||||
|
@ -181,11 +173,10 @@ char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_o
|
||||||
return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
|
return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* No diag -- clang diagnoses misuses of this on its own. */
|
||||||
__BIONIC_FORTIFY_INLINE
|
__BIONIC_FORTIFY_INLINE
|
||||||
char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
|
char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
|
||||||
__overloadable
|
__overloadable {
|
||||||
__clang_error_if(__bos_unevaluated_lt(__bos(dst), n),
|
|
||||||
"'strncpy' called with size bigger than buffer") {
|
|
||||||
size_t bos_dst = __bos(dst);
|
size_t bos_dst = __bos(dst);
|
||||||
size_t bos_src = __bos(src);
|
size_t bos_src = __bos(src);
|
||||||
|
|
||||||
|
|
|
@ -35,12 +35,14 @@
|
||||||
//
|
//
|
||||||
// Similarly, there are a few overload tricks we have to emit errors. Ignore any notes from those.
|
// Similarly, there are a few overload tricks we have to emit errors. Ignore any notes from those.
|
||||||
// expected-note@* 0+{{candidate function}}
|
// expected-note@* 0+{{candidate function}}
|
||||||
|
//
|
||||||
// FIXME(b/138701943): Silence warnings produced by -Wfortify-source since they're expected.
|
// And finally, all explicitly-unavailable-here complaints from headers are
|
||||||
// expected-warning@* 0+{{will always overflow}}
|
// uninteresting
|
||||||
// expected-warning@* 0+{{size argument is too large}}
|
|
||||||
// expected-note@* 0+{{has been explicitly marked unavailable here}}
|
// expected-note@* 0+{{has been explicitly marked unavailable here}}
|
||||||
|
|
||||||
|
// Note that some of these diags come from clang itself, while others come from
|
||||||
|
// `diagnose_if`s sprinkled throughout Bionic.
|
||||||
|
|
||||||
#ifndef _FORTIFY_SOURCE
|
#ifndef _FORTIFY_SOURCE
|
||||||
#error "_FORTIFY_SOURCE must be defined"
|
#error "_FORTIFY_SOURCE must be defined"
|
||||||
#endif
|
#endif
|
||||||
|
@ -60,12 +62,14 @@
|
||||||
#define __clang_error_if(...)
|
#define __clang_error_if(...)
|
||||||
#undef __clang_warning_if
|
#undef __clang_warning_if
|
||||||
#define __clang_warning_if(...)
|
#define __clang_warning_if(...)
|
||||||
|
#pragma clang diagnostic ignored "-Wfortify-source"
|
||||||
|
|
||||||
// SOMETIMES_CONST allows clang to emit eager diagnostics when we're doing compilation tests, but
|
// 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.
|
// blocks them otherwise. This is needed for diagnostics emitted with __enable_if.
|
||||||
#define SOMETIMES_CONST volatile
|
#define SOMETIMES_CONST volatile
|
||||||
#else
|
#else
|
||||||
#define SOMETIMES_CONST const
|
#define SOMETIMES_CONST const
|
||||||
|
#pragma clang diagnostic error "-Wfortify-source"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
|
@ -160,13 +164,13 @@ FORTIFY_TEST(string) {
|
||||||
|
|
||||||
{
|
{
|
||||||
char large_buffer[sizeof(small_buffer) + 1] = {};
|
char large_buffer[sizeof(small_buffer) + 1] = {};
|
||||||
// expected-error@+1{{size bigger than buffer}}
|
// expected-error@+1{{will always overflow}}
|
||||||
EXPECT_FORTIFY_DEATH(memcpy(small_buffer, large_buffer, sizeof(large_buffer)));
|
EXPECT_FORTIFY_DEATH(memcpy(small_buffer, large_buffer, sizeof(large_buffer)));
|
||||||
// expected-error@+1{{size bigger than buffer}}
|
// expected-error@+1{{will always overflow}}
|
||||||
EXPECT_FORTIFY_DEATH(memmove(small_buffer, large_buffer, sizeof(large_buffer)));
|
EXPECT_FORTIFY_DEATH(memmove(small_buffer, large_buffer, sizeof(large_buffer)));
|
||||||
// expected-error@+1{{size bigger than buffer}}
|
// expected-error@+1{{size bigger than buffer}}
|
||||||
EXPECT_FORTIFY_DEATH(mempcpy(small_buffer, large_buffer, sizeof(large_buffer)));
|
EXPECT_FORTIFY_DEATH(mempcpy(small_buffer, large_buffer, sizeof(large_buffer)));
|
||||||
// expected-error@+1{{size bigger than buffer}}
|
// expected-error@+1{{will always overflow}}
|
||||||
EXPECT_FORTIFY_DEATH(memset(small_buffer, 0, sizeof(large_buffer)));
|
EXPECT_FORTIFY_DEATH(memset(small_buffer, 0, sizeof(large_buffer)));
|
||||||
// expected-warning@+1{{arguments got flipped?}}
|
// expected-warning@+1{{arguments got flipped?}}
|
||||||
EXPECT_NO_DEATH(memset(small_buffer, sizeof(small_buffer), 0));
|
EXPECT_NO_DEATH(memset(small_buffer, sizeof(small_buffer), 0));
|
||||||
|
@ -184,13 +188,13 @@ FORTIFY_TEST(string) {
|
||||||
EXPECT_FORTIFY_DEATH(strcpy(small_buffer, large_string));
|
EXPECT_FORTIFY_DEATH(strcpy(small_buffer, large_string));
|
||||||
// expected-error@+1{{string bigger than buffer}}
|
// expected-error@+1{{string bigger than buffer}}
|
||||||
EXPECT_FORTIFY_DEATH(stpcpy(small_buffer, large_string));
|
EXPECT_FORTIFY_DEATH(stpcpy(small_buffer, large_string));
|
||||||
// expected-error@+1{{size bigger than buffer}}
|
// expected-error@+1{{size argument is too large}}
|
||||||
EXPECT_FORTIFY_DEATH(strncpy(small_buffer, large_string, sizeof(large_string)));
|
EXPECT_FORTIFY_DEATH(strncpy(small_buffer, large_string, sizeof(large_string)));
|
||||||
// expected-error@+1{{size bigger than buffer}}
|
// expected-error@+1{{size argument is too large}}
|
||||||
EXPECT_FORTIFY_DEATH(stpncpy(small_buffer, large_string, sizeof(large_string)));
|
EXPECT_FORTIFY_DEATH(stpncpy(small_buffer, large_string, sizeof(large_string)));
|
||||||
// expected-error@+1{{string bigger than buffer}}
|
// expected-error@+1{{string bigger than buffer}}
|
||||||
EXPECT_FORTIFY_DEATH(strcat(small_buffer, large_string));
|
EXPECT_FORTIFY_DEATH(strcat(small_buffer, large_string));
|
||||||
// expected-error@+1{{size bigger than buffer}}
|
// expected-error@+1{{size argument is too large}}
|
||||||
EXPECT_FORTIFY_DEATH(strncat(small_buffer, large_string, sizeof(large_string)));
|
EXPECT_FORTIFY_DEATH(strncat(small_buffer, large_string, sizeof(large_string)));
|
||||||
// expected-error@+1{{size bigger than buffer}}
|
// expected-error@+1{{size bigger than buffer}}
|
||||||
EXPECT_FORTIFY_DEATH(strlcpy(small_buffer, large_string, sizeof(large_string)));
|
EXPECT_FORTIFY_DEATH(strlcpy(small_buffer, large_string, sizeof(large_string)));
|
||||||
|
@ -227,12 +231,12 @@ FORTIFY_TEST(string) {
|
||||||
EXPECT_FORTIFY_DEATH_STRUCT(stpcpy(split.tiny_buffer, small_string));
|
EXPECT_FORTIFY_DEATH_STRUCT(stpcpy(split.tiny_buffer, small_string));
|
||||||
|
|
||||||
#if _FORTIFY_SOURCE > 1
|
#if _FORTIFY_SOURCE > 1
|
||||||
// expected-error@+2{{size bigger than buffer}}
|
// expected-error@+2{{size argument is too large}}
|
||||||
#endif
|
#endif
|
||||||
EXPECT_FORTIFY_DEATH_STRUCT(strncpy(split.tiny_buffer, small_string, sizeof(small_string)));
|
EXPECT_FORTIFY_DEATH_STRUCT(strncpy(split.tiny_buffer, small_string, sizeof(small_string)));
|
||||||
|
|
||||||
#if _FORTIFY_SOURCE > 1
|
#if _FORTIFY_SOURCE > 1
|
||||||
// expected-error@+2{{size bigger than buffer}}
|
// expected-error@+2{{size argument is too large}}
|
||||||
#endif
|
#endif
|
||||||
EXPECT_FORTIFY_DEATH_STRUCT(stpncpy(split.tiny_buffer, small_string, sizeof(small_string)));
|
EXPECT_FORTIFY_DEATH_STRUCT(stpncpy(split.tiny_buffer, small_string, sizeof(small_string)));
|
||||||
|
|
||||||
|
@ -242,7 +246,7 @@ FORTIFY_TEST(string) {
|
||||||
EXPECT_FORTIFY_DEATH_STRUCT(strcat(split.tiny_buffer, small_string));
|
EXPECT_FORTIFY_DEATH_STRUCT(strcat(split.tiny_buffer, small_string));
|
||||||
|
|
||||||
#if _FORTIFY_SOURCE > 1
|
#if _FORTIFY_SOURCE > 1
|
||||||
// expected-error@+2{{size bigger than buffer}}
|
// expected-error@+2{{size argument is too large}}
|
||||||
#endif
|
#endif
|
||||||
EXPECT_FORTIFY_DEATH_STRUCT(strncat(split.tiny_buffer, small_string, sizeof(small_string)));
|
EXPECT_FORTIFY_DEATH_STRUCT(strncat(split.tiny_buffer, small_string, sizeof(small_string)));
|
||||||
|
|
||||||
|
@ -491,11 +495,11 @@ FORTIFY_TEST(sys_stat) {
|
||||||
FORTIFY_TEST(stdio) {
|
FORTIFY_TEST(stdio) {
|
||||||
char small_buffer[8] = {};
|
char small_buffer[8] = {};
|
||||||
{
|
{
|
||||||
// expected-error@+1{{size is larger than the destination buffer}}
|
// expected-error@+1{{size argument is too large}}
|
||||||
EXPECT_FORTIFY_DEATH(snprintf(small_buffer, sizeof(small_buffer) + 1, ""));
|
EXPECT_FORTIFY_DEATH(snprintf(small_buffer, sizeof(small_buffer) + 1, ""));
|
||||||
|
|
||||||
va_list va;
|
va_list va;
|
||||||
// expected-error@+2{{size is larger than the destination buffer}}
|
// expected-error@+2{{size argument is too large}}
|
||||||
// expected-warning@+1{{format string is empty}}
|
// expected-warning@+1{{format string is empty}}
|
||||||
EXPECT_FORTIFY_DEATH(vsnprintf(small_buffer, sizeof(small_buffer) + 1, "", va));
|
EXPECT_FORTIFY_DEATH(vsnprintf(small_buffer, sizeof(small_buffer) + 1, "", va));
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue