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:
parent
e86a8d605b
commit
156d5a8ae9
6 changed files with 28 additions and 30 deletions
|
@ -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) {
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue