Merge "add fortified implementations of send/sendto"
This commit is contained in:
commit
c54937b972
12 changed files with 111 additions and 3 deletions
|
@ -224,6 +224,13 @@ ssize_t __recvfrom_chk(int socket, void* buf, size_t len, size_t buf_size,
|
|||
return recvfrom(socket, buf, len, flags, src_addr, addrlen);
|
||||
}
|
||||
|
||||
ssize_t __sendto_chk(int socket, const void* buf, size_t len, size_t buflen,
|
||||
int flags, const struct sockaddr* dest_addr,
|
||||
socklen_t addrlen) {
|
||||
__check_buffer_access("sendto", "read from", len, buflen);
|
||||
return sendto(socket, buf, len, flags, dest_addr, addrlen);
|
||||
}
|
||||
|
||||
// Runtime implementation of __builtin____stpcpy_chk (used directly by compiler, not in headers)..
|
||||
extern "C" char* __stpcpy_chk(char* dst, const char* src, size_t dst_len) {
|
||||
// TODO: optimize so we don't scan src twice.
|
||||
|
|
|
@ -28,6 +28,6 @@
|
|||
|
||||
#include <sys/socket.h>
|
||||
|
||||
ssize_t send(int socket, const void* buf, 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);
|
||||
}
|
||||
|
|
|
@ -318,18 +318,22 @@ __socketcall int socket(int, int, int);
|
|||
__socketcall int socketpair(int, int, int, int*);
|
||||
|
||||
ssize_t recv(int, void*, size_t, int) __overloadable __RENAME_CLANG(recv);
|
||||
ssize_t send(int, const void*, size_t, int);
|
||||
ssize_t send(int, const void*, size_t, int) __overloadable __RENAME_CLANG(send);
|
||||
|
||||
__socketcall ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t);
|
||||
__socketcall ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t)
|
||||
__overloadable __RENAME_CLANG(sendto);
|
||||
__socketcall ssize_t recvfrom(int, void*, size_t, int, struct sockaddr*,
|
||||
socklen_t*) __overloadable __RENAME_CLANG(recvfrom);
|
||||
|
||||
extern ssize_t __sendto_chk(int, const void*, size_t, size_t, int, const struct sockaddr*,
|
||||
socklen_t) __INTRODUCED_IN_FUTURE;
|
||||
ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
|
||||
socklen_t*) __INTRODUCED_IN(21);
|
||||
|
||||
#if defined(__BIONIC_FORTIFY)
|
||||
|
||||
#define __recvfrom_bad_size "recvfrom called with size bigger than buffer"
|
||||
#define __sendto_bad_size "sendto called with size bigger than buffer"
|
||||
#if defined(__clang__)
|
||||
#if __ANDROID_API__ >= __ANDROID_API_N__
|
||||
__BIONIC_ERROR_FUNCTION_VISIBILITY
|
||||
|
@ -355,10 +359,45 @@ ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len,
|
|||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
|
||||
|
||||
#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
|
||||
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)
|
||||
__overloadable {
|
||||
size_t bos = __bos0(buf);
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __call_bypassing_fortify(sendto)(fd, buf, len, 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__ */
|
||||
|
||||
#else /* defined(__clang__) */
|
||||
ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
|
||||
__errordecl(__recvfrom_error, __recvfrom_bad_size);
|
||||
|
||||
extern ssize_t __sendto_real(int, const void*, size_t, int, const struct sockaddr*, socklen_t)
|
||||
__RENAME(sendto);
|
||||
__errordecl(__sendto_error, __sendto_bad_size);
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_N__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
|
||||
|
@ -380,8 +419,32 @@ 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__ */
|
||||
|
||||
#if __ANDROID_API__ >= __ANDROID_API_N_MR1__
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t sendto(int fd, const void* buf, size_t len, int flags,
|
||||
const struct sockaddr* dest_addr, socklen_t addr_len) {
|
||||
size_t bos = __bos0(buf);
|
||||
|
||||
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
|
||||
return __sendto_real(fd, buf, len, flags, dest_addr, addr_len);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(len) && (len <= bos)) {
|
||||
return __sendto_real(fd, buf, len, flags, dest_addr, addr_len);
|
||||
}
|
||||
|
||||
if (__builtin_constant_p(len) && (len > bos)) {
|
||||
__sendto_error();
|
||||
}
|
||||
|
||||
return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
|
||||
}
|
||||
#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
|
||||
|
||||
#endif /* defined(__clang__) */
|
||||
#undef __recvfrom_bad_size
|
||||
#undef __sendto_bad_size
|
||||
|
||||
__BIONIC_FORTIFY_INLINE
|
||||
ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len,
|
||||
|
@ -389,6 +452,12 @@ ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len,
|
|||
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 {
|
||||
return sendto(socket, buf, len, flags, NULL, 0);
|
||||
}
|
||||
|
||||
#endif /* __BIONIC_FORTIFY */
|
||||
|
||||
#undef __socketcall
|
||||
|
|
|
@ -1265,6 +1265,7 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce
|
|||
|
||||
LIBC_O {
|
||||
global:
|
||||
__sendto_chk; # future
|
||||
__system_property_read_callback; # future
|
||||
__system_property_wait; # future
|
||||
bsd_signal; # arm x86 mips versioned=26
|
||||
|
|
|
@ -1188,6 +1188,7 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce
|
|||
|
||||
LIBC_O {
|
||||
global:
|
||||
__sendto_chk; # future
|
||||
__system_property_read_callback; # future
|
||||
__system_property_wait; # future
|
||||
catclose; # future
|
||||
|
|
|
@ -1290,6 +1290,7 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce
|
|||
|
||||
LIBC_O {
|
||||
global:
|
||||
__sendto_chk; # future
|
||||
__system_property_read_callback; # future
|
||||
__system_property_wait; # future
|
||||
bsd_signal; # arm x86 mips versioned=26
|
||||
|
|
|
@ -1249,6 +1249,7 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce
|
|||
|
||||
LIBC_O {
|
||||
global:
|
||||
__sendto_chk; # future
|
||||
__system_property_read_callback; # future
|
||||
__system_property_wait; # future
|
||||
bsd_signal; # arm x86 mips versioned=26
|
||||
|
|
|
@ -1188,6 +1188,7 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce
|
|||
|
||||
LIBC_O {
|
||||
global:
|
||||
__sendto_chk; # future
|
||||
__system_property_read_callback; # future
|
||||
__system_property_wait; # future
|
||||
catclose; # future
|
||||
|
|
|
@ -1247,6 +1247,7 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce
|
|||
|
||||
LIBC_O {
|
||||
global:
|
||||
__sendto_chk; # future
|
||||
__system_property_read_callback; # future
|
||||
__system_property_wait; # future
|
||||
bsd_signal; # arm x86 mips versioned=26
|
||||
|
|
|
@ -1188,6 +1188,7 @@ LIBC_N { # introduced-arm64=24 introduced-mips=24 introduced-mips64=24 introduce
|
|||
|
||||
LIBC_O {
|
||||
global:
|
||||
__sendto_chk; # future
|
||||
__system_property_read_callback; # future
|
||||
__system_property_wait; # future
|
||||
catclose; # future
|
||||
|
|
|
@ -310,3 +310,22 @@ void test_memset_args_flipped() {
|
|||
// CLANG: 'memset' is deprecated: will set 0 bytes; maybe the arguments got flipped? (Add __bionic_zero_size_is_okay as a fourth argument to silence this.)
|
||||
memset(from, sizeof(from), 0);
|
||||
}
|
||||
|
||||
void test_sendto() {
|
||||
char buf[4] = {0};
|
||||
sockaddr_in addr;
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// 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
|
||||
sendto(0, buf, 6, 0, reinterpret_cast<sockaddr*>(&addr), sizeof(sockaddr_in));
|
||||
}
|
||||
|
||||
void test_send() {
|
||||
char buf[4] = {0};
|
||||
|
||||
// NOLINTNEXTLINE(whitespace/line_length)
|
||||
// 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
|
||||
send(0, buf, 6, 0);
|
||||
}
|
||||
|
|
|
@ -623,6 +623,12 @@ TEST_F(DEATHTEST, recv_fortified) {
|
|||
ASSERT_FORTIFY(recv(0, buf, data_len, 0));
|
||||
}
|
||||
|
||||
TEST_F(DEATHTEST, send_fortified) {
|
||||
size_t data_len = atoi("11"); // suppress compiler optimizations
|
||||
char buf[10] = {0};
|
||||
ASSERT_FORTIFY(send(0, buf, data_len, 0));
|
||||
}
|
||||
|
||||
TEST_F(DEATHTEST, FD_ISSET_fortified) {
|
||||
#if defined(__BIONIC__) // glibc catches this at compile-time.
|
||||
fd_set set;
|
||||
|
|
Loading…
Reference in a new issue