add fortified implementations of send/sendto
Bug: None
Test: Bullhead builds+boots; CtsBionicTestCases passes.
Change-Id: I2f137a100f679f7f2145d84b2f29ddd3e96a36ae
diff --git a/libc/bionic/fortify.cpp b/libc/bionic/fortify.cpp
index 117de48..cf2d1c2 100644
--- a/libc/bionic/fortify.cpp
+++ b/libc/bionic/fortify.cpp
@@ -224,6 +224,13 @@
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.
diff --git a/libc/bionic/send.cpp b/libc/bionic/send.cpp
index 2e5d457..8f175d3 100644
--- a/libc/bionic/send.cpp
+++ b/libc/bionic/send.cpp
@@ -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);
}
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 0813423..c87465f 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -318,18 +318,22 @@
__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 @@
}
#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 @@
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 @@
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
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index 4319429..47292e1 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1265,6 +1265,7 @@
LIBC_O {
global:
+ __sendto_chk; # future
__system_property_read_callback; # future
bsd_signal; # arm x86 mips versioned=26
catclose; # future
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index f88c284..061c8ba 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1188,6 +1188,7 @@
LIBC_O {
global:
+ __sendto_chk; # future
__system_property_read_callback; # future
catclose; # future
catgets; # future
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 46087e6..07dd63c 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1290,6 +1290,7 @@
LIBC_O {
global:
+ __sendto_chk; # future
__system_property_read_callback; # future
bsd_signal; # arm x86 mips versioned=26
catclose; # future
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index 075746c..34da820 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1249,6 +1249,7 @@
LIBC_O {
global:
+ __sendto_chk; # future
__system_property_read_callback; # future
bsd_signal; # arm x86 mips versioned=26
catclose; # future
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index f88c284..061c8ba 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1188,6 +1188,7 @@
LIBC_O {
global:
+ __sendto_chk; # future
__system_property_read_callback; # future
catclose; # future
catgets; # future
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index 75c7757..640fa4a 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1247,6 +1247,7 @@
LIBC_O {
global:
+ __sendto_chk; # future
__system_property_read_callback; # future
bsd_signal; # arm x86 mips versioned=26
catclose; # future
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index f88c284..061c8ba 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1188,6 +1188,7 @@
LIBC_O {
global:
+ __sendto_chk; # future
__system_property_read_callback; # future
catclose; # future
catgets; # future