diff --git a/libc/include/bits/fortify/poll.h b/libc/include/bits/fortify/poll.h index e9b52c858..8363e35a6 100644 --- a/libc/include/bits/fortify/poll.h +++ b/libc/include/bits/fortify/poll.h @@ -37,42 +37,31 @@ int __ppoll_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*, #if defined(__BIONIC_FORTIFY) #if __ANDROID_API__ >= __ANDROID_API_M__ #if defined(__clang__) -__BIONIC_ERROR_FUNCTION_VISIBILITY -int poll(struct pollfd* fds, nfds_t fd_count, int timeout) __overloadable - __enable_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE && - __bos(fds) < sizeof(*fds) * fd_count, - "selected when there aren't fd_count fds") - __errorattr("too many fds specified"); - __BIONIC_FORTIFY_INLINE -int poll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, - int timeout) __overloadable { +int poll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, int timeout) + __overloadable + __clang_error_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE && + __bos(fds) < sizeof(*fds) * fd_count, + "in call to 'poll', fd_count is larger than the given buffer") { size_t bos_fds = __bos(fds); if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) { - return __call_bypassing_fortify(poll)(fds, fd_count, timeout); + return __call_bypassing_fortify(poll)(fds, fd_count, timeout); } - return __poll_chk(fds, fd_count, timeout, bos_fds); } -__BIONIC_ERROR_FUNCTION_VISIBILITY -int ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout, - const sigset_t* mask) __overloadable - __enable_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE && - __bos(fds) < sizeof(*fds) * fd_count, - "selected when there aren't fd_count fds") - __errorattr("too many fds specified"); - __BIONIC_FORTIFY_INLINE -int ppoll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, - const struct timespec* timeout, const sigset_t* mask) __overloadable { +int ppoll(struct pollfd* const fds __pass_object_size, nfds_t fd_count, const struct timespec* timeout, const sigset_t* mask) + __overloadable + __clang_error_if(__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE && + __bos(fds) < sizeof(*fds) * fd_count, + "in call to 'ppoll', fd_count is larger than the given buffer") { size_t bos_fds = __bos(fds); if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) { - return __call_bypassing_fortify(ppoll)(fds, fd_count, timeout, mask); + return __call_bypassing_fortify(ppoll)(fds, fd_count, timeout, mask); } - return __ppoll_chk(fds, fd_count, timeout, mask, bos_fds); } #else /* defined(__clang__) */ diff --git a/libc/include/bits/fortify/stat.h b/libc/include/bits/fortify/stat.h index d119e2cbf..c168c3808 100644 --- a/libc/include/bits/fortify/stat.h +++ b/libc/include/bits/fortify/stat.h @@ -33,23 +33,17 @@ mode_t __umask_chk(mode_t) __INTRODUCED_IN(18); #if defined(__BIONIC_FORTIFY) -#define __umask_invalid_mode_str "umask called with invalid mode" +#define __umask_invalid_mode_str "'umask' called with invalid mode" #if defined(__clang__) #if __ANDROID_API__ >= __ANDROID_API_J_MR2__ -/* - * Abuse enable_if to make these be seen as overloads of umask, rather than - * definitions. - */ -__BIONIC_ERROR_FUNCTION_VISIBILITY -mode_t umask(mode_t mode) __overloadable - __enable_if(1, "") - __enable_if(mode & ~0777, __umask_invalid_mode_str) - __errorattr(__umask_invalid_mode_str); - +/* Abuse enable_if to make this an overload of umask. */ __BIONIC_FORTIFY_INLINE -mode_t umask(mode_t mode) __enable_if(1, "") __overloadable { +mode_t umask(mode_t mode) + __overloadable + __enable_if(1, "") + __clang_error_if(mode & ~0777, __umask_invalid_mode_str) { return __umask_chk(mode); } #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */ diff --git a/tests/fortify_compilation_test.cpp b/tests/fortify_compilation_test.cpp index bb2b7706c..8cc22674d 100644 --- a/tests/fortify_compilation_test.cpp +++ b/tests/fortify_compilation_test.cpp @@ -190,8 +190,8 @@ void test_recvfrom() { void test_umask() { // NOLINTNEXTLINE(whitespace/line_length) - // GCC: error: call to '__umask_invalid_mode' declared with attribute error: umask called with invalid mode - // CLANG: error: call to unavailable function 'umask': umask called with invalid mode + // GCC: error: call to '__umask_invalid_mode' declared with attribute error: 'umask' called with invalid mode + // CLANG: error: 'umask' called with invalid mode umask(01777); } @@ -219,7 +219,7 @@ void test_poll() { pollfd fds[1]; // NOLINTNEXTLINE(whitespace/line_length) // GCC: error: call to '__poll_too_small_error' declared with attribute error: poll: pollfd array smaller than fd count - // CLANG: error: call to unavailable function 'poll': too many fds specified + // CLANG: error: in call to 'poll', fd_count is larger than the given buffer poll(fds, 2, 0); } @@ -228,7 +228,7 @@ void test_ppoll() { timespec timeout; // NOLINTNEXTLINE(whitespace/line_length) // GCC: error: call to '__ppoll_too_small_error' declared with attribute error: ppoll: pollfd array smaller than fd count - // CLANG: error: call to unavailable function 'ppoll': too many fds specified + // CLANG: error: in call to 'ppoll', fd_count is larger than the given buffer ppoll(fds, 2, &timeout, NULL); }