Merge "libc fortify: make socket.h and stdlib.h use diagnose_if"
This commit is contained in:
commit
a821283d22
5 changed files with 70 additions and 65 deletions
|
@ -37,64 +37,55 @@ ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
|
||||||
|
|
||||||
#if defined(__BIONIC_FORTIFY)
|
#if defined(__BIONIC_FORTIFY)
|
||||||
|
|
||||||
#define __recvfrom_bad_size "recvfrom called with size bigger than buffer"
|
#define __recvfrom_bad_size "'recvfrom' called with size bigger than buffer"
|
||||||
#define __sendto_bad_size "sendto called with size bigger than buffer"
|
#define __sendto_bad_size "'sendto' called with size bigger than buffer"
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
#if __ANDROID_API__ >= __ANDROID_API_N__
|
#if __ANDROID_API__ >= __ANDROID_API_N__
|
||||||
__BIONIC_ERROR_FUNCTION_VISIBILITY
|
|
||||||
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(__recvfrom_bad_size);
|
|
||||||
|
|
||||||
__BIONIC_FORTIFY_INLINE
|
__BIONIC_FORTIFY_INLINE
|
||||||
ssize_t recvfrom(int fd, void* const buf __pass_object_size0, 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)
|
||||||
int flags, struct sockaddr* src_addr, socklen_t* addr_len)
|
__overloadable
|
||||||
__overloadable {
|
__clang_error_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos(buf) < len,
|
||||||
|
__recvfrom_bad_size) {
|
||||||
size_t bos = __bos0(buf);
|
size_t bos = __bos0(buf);
|
||||||
|
|
||||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||||
return __call_bypassing_fortify(recvfrom)(fd, buf, len, flags, src_addr,
|
return __call_bypassing_fortify(recvfrom)(fd, buf, len, flags, src_addr, addr_len);
|
||||||
addr_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
|
return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
|
||||||
}
|
}
|
||||||
#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
|
#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
|
||||||
|
|
||||||
#if __ANDROID_API__ >= __ANDROID_API_N_MR1__
|
#if __ANDROID_API__ >= __ANDROID_API_N_MR1__
|
||||||
__BIONIC_ERROR_FUNCTION_VISIBILITY
|
|
||||||
ssize_t sendto(int fd, const void* buf, size_t len, int flags,
|
|
||||||
const struct sockaddr* dest_addr, socklen_t addr_len)
|
|
||||||
__overloadable
|
|
||||||
__enable_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
|
|
||||||
__bos0(buf) < len, "selected when the buffer is too small")
|
|
||||||
__errorattr(__sendto_bad_size);
|
|
||||||
|
|
||||||
__BIONIC_FORTIFY_INLINE
|
__BIONIC_FORTIFY_INLINE
|
||||||
ssize_t sendto(int fd, const void* const buf __pass_object_size0, size_t len,
|
ssize_t sendto(int fd, const void* const buf __pass_object_size0, size_t len, int flags, const struct sockaddr* dest_addr, socklen_t addr_len)
|
||||||
int flags, const struct sockaddr* dest_addr, socklen_t addr_len)
|
__overloadable
|
||||||
__overloadable {
|
__clang_error_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(buf) < len,
|
||||||
|
__sendto_bad_size) {
|
||||||
size_t bos = __bos0(buf);
|
size_t bos = __bos0(buf);
|
||||||
|
|
||||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||||
return __call_bypassing_fortify(sendto)(fd, buf, len, flags, dest_addr,
|
return __call_bypassing_fortify(sendto)(fd, buf, len, flags, dest_addr, addr_len);
|
||||||
addr_len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
|
return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
__BIONIC_ERROR_FUNCTION_VISIBILITY
|
|
||||||
ssize_t send(int socket, const void* buf, size_t len, int flags)
|
|
||||||
__overloadable
|
|
||||||
__enable_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
|
|
||||||
__bos0(buf) < len, "selected when the buffer is too small")
|
|
||||||
__errorattr("send called with size bigger than buffer");
|
|
||||||
#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
|
#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
|
||||||
|
|
||||||
|
__BIONIC_FORTIFY_INLINE
|
||||||
|
ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len, int flags)
|
||||||
|
__overloadable
|
||||||
|
__clang_error_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(buf) < len,
|
||||||
|
"'recv' called with size bigger than buffer") {
|
||||||
|
return recvfrom(socket, buf, len, flags, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
__BIONIC_FORTIFY_INLINE
|
||||||
|
ssize_t send(int socket, const void* const buf __pass_object_size0, size_t len, int flags)
|
||||||
|
__overloadable
|
||||||
|
__clang_error_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(buf) < len,
|
||||||
|
"'send' called with size bigger than buffer") {
|
||||||
|
return sendto(socket, buf, len, flags, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#else /* defined(__clang__) */
|
#else /* defined(__clang__) */
|
||||||
ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
|
ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
|
||||||
__errordecl(__recvfrom_error, __recvfrom_bad_size);
|
__errordecl(__recvfrom_error, __recvfrom_bad_size);
|
||||||
|
@ -147,20 +138,17 @@ ssize_t sendto(int fd, const void* buf, size_t len, int flags,
|
||||||
}
|
}
|
||||||
#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
|
#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
|
||||||
|
|
||||||
#endif /* defined(__clang__) */
|
|
||||||
#undef __recvfrom_bad_size
|
|
||||||
#undef __sendto_bad_size
|
|
||||||
|
|
||||||
__BIONIC_FORTIFY_INLINE
|
__BIONIC_FORTIFY_INLINE
|
||||||
ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len,
|
ssize_t recv(int socket, void* buf, size_t len, int flags) {
|
||||||
int flags) __overloadable {
|
|
||||||
return recvfrom(socket, buf, len, flags, NULL, 0);
|
return recvfrom(socket, buf, len, flags, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
__BIONIC_FORTIFY_INLINE
|
__BIONIC_FORTIFY_INLINE
|
||||||
ssize_t send(int socket, const void* const buf __pass_object_size0, size_t len, int flags)
|
ssize_t send(int socket, const void* buf, size_t len, int flags) {
|
||||||
__overloadable {
|
|
||||||
return sendto(socket, buf, len, flags, NULL, 0);
|
return sendto(socket, buf, len, flags, NULL, 0);
|
||||||
}
|
}
|
||||||
|
#endif /* defined(__clang__) */
|
||||||
|
|
||||||
|
#undef __recvfrom_bad_size
|
||||||
|
#undef __sendto_bad_size
|
||||||
#endif /* __BIONIC_FORTIFY */
|
#endif /* __BIONIC_FORTIFY */
|
||||||
|
|
|
@ -32,22 +32,16 @@
|
||||||
|
|
||||||
#if defined(__BIONIC_FORTIFY)
|
#if defined(__BIONIC_FORTIFY)
|
||||||
#define __realpath_buf_too_small_str \
|
#define __realpath_buf_too_small_str \
|
||||||
"realpath output parameter must be NULL or a >= PATH_MAX bytes buffer"
|
"'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes"
|
||||||
|
|
||||||
/* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
|
/* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */
|
||||||
#define __PATH_MAX 4096
|
#define __PATH_MAX 4096
|
||||||
|
|
||||||
#if defined(__clang__)
|
#if defined(__clang__)
|
||||||
|
char* realpath(const char* path, char* resolved)
|
||||||
__BIONIC_ERROR_FUNCTION_VISIBILITY
|
__clang_error_if(__bos(resolved) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
|
||||||
char* realpath(const char* path, char* resolved) __overloadable
|
__bos(resolved) < __PATH_MAX, __realpath_buf_too_small_str);
|
||||||
__enable_if(__bos(resolved) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
|
/* No need for a definition; the only issues we can catch are at compile-time. */
|
||||||
__bos(resolved) < __PATH_MAX, __realpath_buf_too_small_str)
|
|
||||||
__errorattr(__realpath_buf_too_small_str);
|
|
||||||
|
|
||||||
/* No need for a FORTIFY version; the only things we can catch are at
|
|
||||||
* compile-time.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#else /* defined(__clang__) */
|
#else /* defined(__clang__) */
|
||||||
|
|
||||||
|
|
|
@ -83,8 +83,7 @@ int atoi(const char*) __attribute_pure__;
|
||||||
long atol(const char*) __attribute_pure__;
|
long atol(const char*) __attribute_pure__;
|
||||||
long long atoll(const char*) __attribute_pure__;
|
long long atoll(const char*) __attribute_pure__;
|
||||||
|
|
||||||
char * realpath(const char *path, char *resolved) __overloadable
|
char* realpath(const char* path, char* resolved);
|
||||||
__RENAME_CLANG(realpath);
|
|
||||||
int system(const char *string);
|
int system(const char *string);
|
||||||
|
|
||||||
void* bsearch(const void* key, const void* base0, size_t nmemb, size_t size,
|
void* bsearch(const void* key, const void* base0, size_t nmemb, size_t size,
|
||||||
|
|
|
@ -48,7 +48,7 @@ __FBSDID("$FreeBSD$");
|
||||||
* in which case the path which caused trouble is left in (resolved).
|
* in which case the path which caused trouble is left in (resolved).
|
||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
realpath(const char * __restrict path, char * __restrict resolved) __overloadable
|
realpath(const char * __restrict path, char * __restrict resolved)
|
||||||
{
|
{
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
char *p, *q, *s;
|
char *p, *q, *s;
|
||||||
|
|
|
@ -183,11 +183,20 @@ void test_recvfrom() {
|
||||||
sockaddr_in addr;
|
sockaddr_in addr;
|
||||||
|
|
||||||
// NOLINTNEXTLINE(whitespace/line_length)
|
// NOLINTNEXTLINE(whitespace/line_length)
|
||||||
// GCC: error: call to '__recvfrom_error' declared with attribute error: recvfrom called with size bigger than buffer
|
// GCC: error: call to '__recvfrom_error' declared with attribute error: 'recvfrom' called with size bigger than buffer
|
||||||
// CLANG: error: call to unavailable function 'recvfrom': recvfrom called with size bigger than buffer
|
// CLANG: error: 'recvfrom' called with size bigger than buffer
|
||||||
recvfrom(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), NULL);
|
recvfrom(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_recv() {
|
||||||
|
char buf[4] = {0};
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(whitespace/line_length)
|
||||||
|
// GCC: error: call to '__recvfrom_error' declared with attribute error: 'recvfrom' called with size bigger than buffer
|
||||||
|
// CLANG: error: 'recv' called with size bigger than buffer
|
||||||
|
recv(0, buf, 6, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void test_umask() {
|
void test_umask() {
|
||||||
// NOLINTNEXTLINE(whitespace/line_length)
|
// NOLINTNEXTLINE(whitespace/line_length)
|
||||||
// GCC: error: call to '__umask_invalid_mode' declared with attribute error: 'umask' called with invalid mode
|
// GCC: error: call to '__umask_invalid_mode' declared with attribute error: 'umask' called with invalid mode
|
||||||
|
@ -318,8 +327,8 @@ void test_sendto() {
|
||||||
sockaddr_in addr;
|
sockaddr_in addr;
|
||||||
|
|
||||||
// NOLINTNEXTLINE(whitespace/line_length)
|
// NOLINTNEXTLINE(whitespace/line_length)
|
||||||
// GCC: error: call to '__sendto_error' declared with attribute error: sendto called with size bigger than buffer
|
// GCC: error: call to '__sendto_error' declared with attribute error: 'sendto' called with size bigger than buffer
|
||||||
// CLANG: error: call to unavailable function 'sendto': sendto called with size bigger than buffer
|
// CLANG: error: 'sendto' called with size bigger than buffer
|
||||||
sendto(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), sizeof(sockaddr_in));
|
sendto(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), sizeof(sockaddr_in));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +336,22 @@ void test_send() {
|
||||||
char buf[4] = {0};
|
char buf[4] = {0};
|
||||||
|
|
||||||
// NOLINTNEXTLINE(whitespace/line_length)
|
// NOLINTNEXTLINE(whitespace/line_length)
|
||||||
// GCC: error: call to '__sendto_error' declared with attribute error: sendto called with size bigger than buffer
|
// GCC: error: call to '__sendto_error' declared with attribute error: 'sendto' called with size bigger than buffer
|
||||||
// CLANG: error: call to unavailable function 'send': send called with size bigger than buffer
|
// CLANG: error: 'send' called with size bigger than buffer
|
||||||
send(0, buf, 6, 0);
|
send(0, buf, 6, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_realpath() {
|
||||||
|
char buf[4] = {0};
|
||||||
|
// NOLINTNEXTLINE(whitespace/line_length)
|
||||||
|
// GCC: error: call to '__realpath_size_error' declared with attribute error: 'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes
|
||||||
|
// NOLINTNEXTLINE(whitespace/line_length)
|
||||||
|
// CLANG: error: 'realpath' output parameter must be NULL or a pointer to a buffer with >= PATH_MAX bytes
|
||||||
|
realpath(".", buf);
|
||||||
|
|
||||||
|
// This is fine.
|
||||||
|
realpath(".", NULL);
|
||||||
|
|
||||||
|
// FIXME: But we should warn on this.
|
||||||
|
realpath(NULL, buf);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue