Match __bos0 to __pass_object_size0 in FORTIFY

pass_object_size(N) forwards the result of __builtin_object_size(param,
N) to a function. So, a function that looks like:

  size_t foo(void *const p __pass_object_size) { return __bos0(p); }
  int bar = foo(baz);

would effectively be turned into

  size_t foo(void *const p, size_t sz) { return sz; }
  int bar = foo(baz, __bos(baz)); // note that this is not __bos0

This is bad, since if we're using __bos0, we want more relaxed
objectsize checks.

__bos0 should be more permissive than __bos in all cases, so this
change Should Be Fine™.

This change also makes GCC and clang share another function's
implementation (recv). I just realized we need to add special
diagnostic-related overloads bits for clang to it, but I can do that in
another patch.

Bug: None
Test: Bullhead builds and boots; CtsBionicTestCases passes.
Change-Id: I6818d0041328ab5fd0946a1e57321a977c1e1250
This commit is contained in:
George Burgess IV 2017-02-10 13:56:22 -08:00
parent e86a8d605b
commit 156d5a8ae9
6 changed files with 28 additions and 30 deletions

View file

@ -341,7 +341,7 @@ size_t fread(void *__restrict buf, size_t size, size_t count,
__errorattr("size * count is too large");
__BIONIC_FORTIFY_INLINE
size_t fread(void *__restrict const __pass_object_size buf, size_t size,
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);
@ -366,8 +366,9 @@ size_t fwrite(const void * __restrict buf, size_t size,
__errorattr("size * count is too large");
__BIONIC_FORTIFY_INLINE
size_t fwrite(const void * __restrict const __pass_object_size buf, size_t size,
size_t count, FILE * __restrict stream) __overloadable {
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) {

View file

@ -168,13 +168,13 @@ struct __bionic_zero_size_is_okay_t {};
// trickery...
#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
__BIONIC_FORTIFY_INLINE
void* memcpy(void* _Nonnull __restrict const dst __pass_object_size,
void* memcpy(void* _Nonnull __restrict const dst __pass_object_size0,
const void* _Nonnull __restrict src, size_t copy_amount) __overloadable {
return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
}
__BIONIC_FORTIFY_INLINE
void* memmove(void* const _Nonnull dst __pass_object_size,
void* memmove(void* const _Nonnull dst __pass_object_size0,
const void* _Nonnull src, size_t len) __overloadable {
return __builtin___memmove_chk(dst, src, len, __bos0(dst));
}
@ -209,7 +209,7 @@ char* strncat(char* const _Nonnull __restrict dst __pass_object_size,
}
__BIONIC_FORTIFY_INLINE
void* memset(void* const _Nonnull s __pass_object_size, int c, size_t n)
void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n)
__overloadable {
return __builtin___memset_chk(s, c, n, __bos0(s));
}
@ -343,7 +343,7 @@ size_t strlen(const char* const _Nonnull s __pass_object_size)
}
__BIONIC_FORTIFY_INLINE
size_t strlen(const char* const _Nonnull s __pass_object_size_n(0))
size_t strlen(const char* const _Nonnull s __pass_object_size0)
__overloadable {
size_t bos = __bos0(s);
@ -358,7 +358,7 @@ size_t strlen(const char* const _Nonnull s __pass_object_size_n(0))
#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
__BIONIC_FORTIFY_INLINE
char* strchr(const char* const _Nonnull s __pass_object_size_n(0), int c)
char* strchr(const char* const _Nonnull s __pass_object_size0, int c)
__overloadable {
size_t bos = __bos0(s);
@ -395,7 +395,7 @@ void* memset(void* _Nonnull s, int c, size_t n,
__error_if_overflows_dst(memset, s, n, "size");
__BIONIC_FORTIFY_INLINE
void* memset(void* const _Nonnull s __pass_object_size, int c, size_t n,
void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n,
struct __bionic_zero_size_is_okay_t ok __attribute__((unused)))
__overloadable {
return __builtin___memset_chk(s, c, n, __bos0(s));

View file

@ -298,6 +298,7 @@
# define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__))
# endif
# define __pass_object_size __pass_object_size_n(__bos_level)
# define __pass_object_size0 __pass_object_size_n(0)
#endif
/* Used to support clangisms with FORTIFY. This isn't in the FORTIFY section

View file

@ -329,18 +329,19 @@ ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
#if defined(__BIONIC_FORTIFY)
#define __recvfrom_bad_size "recvfrom called with size bigger than buffer"
#if defined(__clang__)
#if __ANDROID_API__ >= __ANDROID_API_N__
__BIONIC_ERROR_FUNCTION_VISIBILITY
ssize_t recvfrom(int fd, void* const buf __pass_object_size, size_t len,
ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len,
int flags, struct sockaddr* src_addr, socklen_t* addr_len)
__overloadable
__enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
__bos(buf) < len, "selected when the buffer is too small")
__errorattr("size is larger than the destination buffer");
__errorattr(__recvfrom_bad_size);
__BIONIC_FORTIFY_INLINE
ssize_t recvfrom(int fd, void* const buf __pass_object_size, size_t len,
ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len,
int flags, struct sockaddr* src_addr, socklen_t* addr_len)
__overloadable {
size_t bos = __bos0(buf);
@ -354,15 +355,9 @@ ssize_t recvfrom(int fd, void* const buf __pass_object_size, size_t len,
}
#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
__BIONIC_FORTIFY_INLINE
ssize_t recv(int socket, void* const buf __pass_object_size, size_t len,
int flags) __overloadable {
return recvfrom(socket, buf, len, flags, NULL, 0);
}
#else /* defined(__clang__) */
ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
__errordecl(__recvfrom_error, "recvfrom called with size bigger than buffer");
__errordecl(__recvfrom_error, __recvfrom_bad_size);
#if __ANDROID_API__ >= __ANDROID_API_N__
__BIONIC_FORTIFY_INLINE
@ -385,14 +380,15 @@ ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
}
#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
#endif /* defined(__clang__) */
#undef __recvfrom_bad_size
__BIONIC_FORTIFY_INLINE
ssize_t recv(int socket, void* buf, size_t len, int flags) {
ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len,
int flags) __overloadable {
return recvfrom(socket, buf, len, flags, NULL, 0);
}
#endif /* defined(__clang__) */
#endif /* __BIONIC_FORTIFY */
#undef __socketcall

View file

@ -322,7 +322,7 @@ ssize_t pread(int fd, void* buf, size_t count, off_t offset) __overloadable
__error_if_overflows_objectsize(count, __bos0(buf));
__BIONIC_FORTIFY_INLINE
ssize_t pread(int fd, void* const __pass_object_size buf, size_t count,
ssize_t pread(int fd, void* const __pass_object_size0 buf, size_t count,
off_t offset) __overloadable {
size_t bos = __bos0(buf);
@ -343,7 +343,7 @@ ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) __overloadable
__error_if_overflows_objectsize(count, __bos0(buf));
__BIONIC_FORTIFY_INLINE
ssize_t pread64(int fd, void* const __pass_object_size buf, size_t count,
ssize_t pread64(int fd, void* const __pass_object_size0 buf, size_t count,
off64_t offset) __overloadable {
size_t bos = __bos0(buf);
@ -368,7 +368,7 @@ ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset)
__error_if_overflows_objectsize(count, __bos0(buf));
__BIONIC_FORTIFY_INLINE
ssize_t pwrite(int fd, const void* const __pass_object_size buf, size_t count,
ssize_t pwrite(int fd, const void* const __pass_object_size0 buf, size_t count,
off_t offset) __overloadable {
size_t bos = __bos0(buf);
@ -391,8 +391,8 @@ ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset)
__error_if_overflows_objectsize(count, __bos0(buf));
__BIONIC_FORTIFY_INLINE
ssize_t pwrite64(int fd, const void* const __pass_object_size buf, size_t count,
off64_t offset) __overloadable {
ssize_t pwrite64(int fd, const void* const __pass_object_size0 buf,
size_t count, off64_t offset) __overloadable {
size_t bos = __bos0(buf);
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
@ -413,7 +413,7 @@ ssize_t read(int fd, void* buf, size_t count) __overloadable
__error_if_overflows_objectsize(count, __bos0(buf));
__BIONIC_FORTIFY_INLINE
ssize_t read(int fd, void* const __pass_object_size buf, size_t count)
ssize_t read(int fd, void* const __pass_object_size0 buf, size_t count)
__overloadable {
size_t bos = __bos0(buf);
@ -434,7 +434,7 @@ ssize_t write(int fd, const void* buf, size_t count) __overloadable
__error_if_overflows_objectsize(count, __bos0(buf));
__BIONIC_FORTIFY_INLINE
ssize_t write(int fd, const void* const __pass_object_size buf, size_t count)
ssize_t write(int fd, const void* const __pass_object_size0 buf, size_t count)
__overloadable {
size_t bos = __bos0(buf);

View file

@ -184,7 +184,7 @@ void test_recvfrom() {
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__recvfrom_error' declared with attribute error: recvfrom called with size bigger than buffer
// CLANG: error: call to unavailable function 'recvfrom': size is larger than the destination buffer
// CLANG: error: call to unavailable function 'recvfrom': recvfrom called with size bigger than buffer
recvfrom(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), NULL);
}