Merge "libc fortify: make socket.h and stdlib.h use diagnose_if"
diff --git a/libc/include/bits/fortify/socket.h b/libc/include/bits/fortify/socket.h
index c9e9436..3e610d6 100644
--- a/libc/include/bits/fortify/socket.h
+++ b/libc/include/bits/fortify/socket.h
@@ -37,64 +37,55 @@
#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"
+#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
-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
-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 {
+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
+ __clang_error_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos(buf) < len,
+ __recvfrom_bad_size) {
size_t bos = __bos0(buf);
if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(recvfrom)(fd, buf, len, flags, src_addr,
- addr_len);
+ return __call_bypassing_fortify(recvfrom)(fd, buf, len, flags, src_addr, addr_len);
}
-
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_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 {
+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
+ __clang_error_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(buf) < len,
+ __sendto_bad_size) {
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 __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__ */
+__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__) */
ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
__errordecl(__recvfrom_error, __recvfrom_bad_size);
@@ -147,20 +138,17 @@
}
#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,
- int flags) __overloadable {
+ssize_t recv(int socket, void* buf, size_t len, int flags) {
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 {
+ssize_t send(int socket, const void* buf, size_t len, int flags) {
return sendto(socket, buf, len, flags, NULL, 0);
}
+#endif /* defined(__clang__) */
+#undef __recvfrom_bad_size
+#undef __sendto_bad_size
#endif /* __BIONIC_FORTIFY */
diff --git a/libc/include/bits/fortify/stdlib.h b/libc/include/bits/fortify/stdlib.h
index bda1d45..cf4b7ea 100644
--- a/libc/include/bits/fortify/stdlib.h
+++ b/libc/include/bits/fortify/stdlib.h
@@ -32,22 +32,16 @@
#if defined(__BIONIC_FORTIFY)
#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 */
#define __PATH_MAX 4096
#if defined(__clang__)
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char* realpath(const char* path, char* resolved) __overloadable
- __enable_if(__bos(resolved) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __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.
- */
+char* realpath(const char* path, char* resolved)
+ __clang_error_if(__bos(resolved) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+ __bos(resolved) < __PATH_MAX, __realpath_buf_too_small_str);
+/* No need for a definition; the only issues we can catch are at compile-time. */
#else /* defined(__clang__) */
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 55e0fa2..13c9d37 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -83,8 +83,7 @@
long atol(const char*) __attribute_pure__;
long long atoll(const char*) __attribute_pure__;
-char * realpath(const char *path, char *resolved) __overloadable
- __RENAME_CLANG(realpath);
+char* realpath(const char* path, char* resolved);
int system(const char *string);
void* bsearch(const void* key, const void* base0, size_t nmemb, size_t size,
diff --git a/libc/upstream-freebsd/lib/libc/stdlib/realpath.c b/libc/upstream-freebsd/lib/libc/stdlib/realpath.c
index 914ecc9..c4bd953 100644
--- a/libc/upstream-freebsd/lib/libc/stdlib/realpath.c
+++ b/libc/upstream-freebsd/lib/libc/stdlib/realpath.c
@@ -48,7 +48,7 @@
* in which case the path which caused trouble is left in (resolved).
*/
char *
-realpath(const char * __restrict path, char * __restrict resolved) __overloadable
+realpath(const char * __restrict path, char * __restrict resolved)
{
struct stat sb;
char *p, *q, *s;
diff --git a/tests/fortify_compilation_test.cpp b/tests/fortify_compilation_test.cpp
index 40b3fc2..17dfacf 100644
--- a/tests/fortify_compilation_test.cpp
+++ b/tests/fortify_compilation_test.cpp
@@ -183,11 +183,20 @@
sockaddr_in addr;
// 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': 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: 'recvfrom' called with size bigger than buffer
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() {
// NOLINTNEXTLINE(whitespace/line_length)
// GCC: error: call to '__umask_invalid_mode' declared with attribute error: 'umask' called with invalid mode
@@ -318,8 +327,8 @@
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
+ // GCC: error: call to '__sendto_error' declared with attribute error: '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));
}
@@ -327,7 +336,22 @@
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
+ // GCC: error: call to '__sendto_error' declared with attribute error: 'sendto' called with size bigger than buffer
+ // CLANG: error: 'send' called with size bigger than buffer
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);
+}