libc: Split FORTIFY into its own headers
This patch cleans up our standard headers by moving most of the FORTIFY
cruft out in to its own sandbox. In order to include the *_chk and
*_real declarations, you can either enable FORTIFY, or `#define
__BIONIC_DECLARE_FORTIFY_HELPERS`.
Both sys/select.h and strings.h are explicitly ignored by this patch.
Both of these files have very small __BIONIC_FORTIFY blocks, and don't
define any actual FORTIFY'ed functions (just macros, and 3 *_chk
functions).
This patch also makes the versioner ignore the FORTIFY implementation
headers, since we're guaranteed to pick the FORTIFY'ed headers up when
looking at the regular headers. (...Not to mention that making the
FORTIFY'ed headers freestanding would be annoying to do and maintain for
~no benefit).
We bake the knowledge of where FORTIFY headers live directly into the
versioner. We could go with a more general approach (e.g. adding an -X
IGNORED_FILE flag that tells the versioner to ignore
$HEADER_PATH/$IGNORED_FILE), but we'd then have to repeat that for every
test, every manual invocation of the versioner, etc. for no benefit
that's obvious to me.
Bug: 12231437
Test: m checkbuild on bullhead internal master + CtsBionicTestCases. no
new errors.
Change-Id: Iffc0cc609009b33d989cdaddde0a809282131a5b
diff --git a/libc/Android.bp b/libc/Android.bp
index d9b8a2b..f77dadf 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -787,7 +787,7 @@
// Disable FORTIFY for the compilation of these, so we don't end up having
// FORTIFY silently call itself.
- cflags: ["-U_FORTIFY_SOURCE"],
+ cflags: ["-U_FORTIFY_SOURCE", "-D__BIONIC_DECLARE_FORTIFY_HELPERS"],
arch: {
arm: {
diff --git a/libc/include/bits/fortify/fcntl.h b/libc/include/bits/fortify/fcntl.h
new file mode 100644
index 0000000..1d3d7bc
--- /dev/null
+++ b/libc/include/bits/fortify/fcntl.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _FCNTL_H
+#error "Never include this file directly; instead, include <fcntl.h>"
+#endif
+
+int __open_2(const char*, int) __INTRODUCED_IN(17);
+int __openat_2(int, const char*, int) __INTRODUCED_IN(17);
+/*
+ * These are the easiest way to call the real open even in clang FORTIFY.
+ */
+int __open_real(const char*, int, ...) __RENAME(open);
+int __openat_real(int, const char*, int, ...) __RENAME(openat);
+
+#if defined(__BIONIC_FORTIFY)
+#define __open_too_many_args_error "too many arguments"
+#define __open_too_few_args_error "called with O_CREAT, but missing mode"
+#if defined(__clang__)
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int open(const char* pathname, int flags, mode_t modes, ...) __overloadable
+ __errorattr(__open_too_many_args_error);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int open(const char* pathname, int flags) __overloadable
+ __enable_if(flags & O_CREAT, __open_too_few_args_error)
+ __errorattr(__open_too_few_args_error);
+
+/*
+ * pass_object_size serves two purposes here, neither of which involve __bos: it
+ * disqualifies this function from having its address taken (so &open works),
+ * and it makes overload resolution prefer open(const char *, int) over
+ * open(const char *, int, ...).
+ */
+__BIONIC_FORTIFY_INLINE
+int open(const char* const __pass_object_size pathname,
+ int flags) __overloadable {
+ return __open_2(pathname, flags);
+}
+
+__BIONIC_FORTIFY_INLINE
+int open(const char* const __pass_object_size pathname, int flags, mode_t modes)
+ __overloadable {
+ return __open_real(pathname, flags, modes);
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int openat(int dirfd, const char* pathname, int flags) __overloadable
+ __enable_if(flags & O_CREAT, __open_too_few_args_error)
+ __errorattr(__open_too_few_args_error);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int openat(int dirfd, const char* pathname, int flags, mode_t modes, ...)
+ __overloadable
+ __errorattr(__open_too_many_args_error);
+
+__BIONIC_FORTIFY_INLINE
+int openat(int dirfd, const char* const __pass_object_size pathname,
+ int flags) __overloadable {
+ return __openat_2(dirfd, pathname, flags);
+}
+
+__BIONIC_FORTIFY_INLINE
+int openat(int dirfd, const char* const __pass_object_size pathname, int flags,
+ mode_t modes) __overloadable {
+ return __openat_real(dirfd, pathname, flags, modes);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#else /* defined(__clang__) */
+__errordecl(__creat_missing_mode, __open_too_few_args_error);
+__errordecl(__creat_too_many_args, __open_too_many_args_error);
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+int open(const char* pathname, int flags, ...) {
+ if (__builtin_constant_p(flags)) {
+ if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) {
+ __creat_missing_mode(); /* Compile time error. */
+ }
+ }
+
+ if (__builtin_va_arg_pack_len() > 1) {
+ __creat_too_many_args(); /* Compile time error. */
+ }
+
+ if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
+ return __open_2(pathname, flags);
+ }
+
+ return __open_real(pathname, flags, __builtin_va_arg_pack());
+}
+
+__BIONIC_FORTIFY_INLINE
+int openat(int dirfd, const char* pathname, int flags, ...) {
+ if (__builtin_constant_p(flags)) {
+ if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) {
+ __creat_missing_mode(); /* Compile time error. */
+ }
+ }
+
+ if (__builtin_va_arg_pack_len() > 1) {
+ __creat_too_many_args(); /* Compile time error. */
+ }
+
+ if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
+ return __openat_2(dirfd, pathname, flags);
+ }
+
+ return __openat_real(dirfd, pathname, flags, __builtin_va_arg_pack());
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#endif /* defined(__clang__) */
+
+#undef __open_too_many_args_error
+#undef __open_too_few_args_error
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/poll.h b/libc/include/bits/fortify/poll.h
new file mode 100644
index 0000000..e9b52c8
--- /dev/null
+++ b/libc/include/bits/fortify/poll.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _POLL_H_
+#error "Never include this file directly; instead, include <poll.h>"
+#endif
+
+int __poll_chk(struct pollfd*, nfds_t, int, size_t) __INTRODUCED_IN(23);
+int __ppoll_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*, size_t)
+ __INTRODUCED_IN(23);
+
+#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 {
+ size_t bos_fds = __bos(fds);
+
+ if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ 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 {
+ size_t bos_fds = __bos(fds);
+
+ if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(ppoll)(fds, fd_count, timeout, mask);
+ }
+
+ return __ppoll_chk(fds, fd_count, timeout, mask, bos_fds);
+}
+#else /* defined(__clang__) */
+int __poll_real(struct pollfd*, nfds_t, int) __RENAME(poll);
+__errordecl(__poll_too_small_error, "poll: pollfd array smaller than fd count");
+
+int __ppoll_real(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*) __RENAME(ppoll)
+ __INTRODUCED_IN(21);
+__errordecl(__ppoll_too_small_error, "ppoll: pollfd array smaller than fd count");
+
+__BIONIC_FORTIFY_INLINE
+int poll(struct pollfd* fds, nfds_t fd_count, int timeout) {
+ if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ if (!__builtin_constant_p(fd_count)) {
+ return __poll_chk(fds, fd_count, timeout, __bos(fds));
+ } else if (__bos(fds) / sizeof(*fds) < fd_count) {
+ __poll_too_small_error();
+ }
+ }
+ return __poll_real(fds, fd_count, timeout);
+}
+
+__BIONIC_FORTIFY_INLINE
+int ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout,
+ const sigset_t* mask) {
+ if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ if (!__builtin_constant_p(fd_count)) {
+ return __ppoll_chk(fds, fd_count, timeout, mask, __bos(fds));
+ } else if (__bos(fds) / sizeof(*fds) < fd_count) {
+ __ppoll_too_small_error();
+ }
+ }
+ return __ppoll_real(fds, fd_count, timeout, mask);
+}
+
+#endif /* defined(__clang__) */
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/socket.h b/libc/include/bits/fortify/socket.h
new file mode 100644
index 0000000..c9e9436
--- /dev/null
+++ b/libc/include/bits/fortify/socket.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _SYS_SOCKET_H_
+#error "Never include this file directly; instead, include <sys/socket.h>"
+#endif
+
+extern ssize_t __sendto_chk(int, const void*, size_t, size_t, int, const struct sockaddr*,
+ socklen_t) __INTRODUCED_IN(26);
+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
+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 {
+ 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 __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 {
+ 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,
+ struct sockaddr* src_addr, socklen_t* addr_len) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
+ }
+
+ if (__builtin_constant_p(len) && (len <= bos)) {
+ return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
+ }
+
+ if (__builtin_constant_p(len) && (len > bos)) {
+ __recvfrom_error();
+ }
+
+ 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,
+ int flags) __overloadable {
+ 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 */
diff --git a/libc/include/bits/fortify/stat.h b/libc/include/bits/fortify/stat.h
new file mode 100644
index 0000000..d119e2c
--- /dev/null
+++ b/libc/include/bits/fortify/stat.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _SYS_STAT_H_
+#error "Never include this file directly; instead, include <sys/stat.h>"
+#endif
+
+mode_t __umask_chk(mode_t) __INTRODUCED_IN(18);
+
+#if defined(__BIONIC_FORTIFY)
+#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);
+
+__BIONIC_FORTIFY_INLINE
+mode_t umask(mode_t mode) __enable_if(1, "") __overloadable {
+ return __umask_chk(mode);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+
+#else /* defined(__clang__) */
+__errordecl(__umask_invalid_mode, __umask_invalid_mode_str);
+extern mode_t __umask_real(mode_t) __RENAME(umask);
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
+__BIONIC_FORTIFY_INLINE
+mode_t umask(mode_t mode) {
+ if (__builtin_constant_p(mode)) {
+ if ((mode & 0777) != mode) {
+ __umask_invalid_mode();
+ }
+ return __umask_real(mode);
+ }
+ return __umask_chk(mode);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+
+#endif /* defined(__clang__) */
+#undef __umask_invalid_mode_str
+
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/stdio.h b/libc/include/bits/fortify/stdio.h
new file mode 100644
index 0000000..dce056a
--- /dev/null
+++ b/libc/include/bits/fortify/stdio.h
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _STDIO_H_
+#error "Never include this file directly; instead, include <stdio.h>"
+#endif
+
+char* __fgets_chk(char*, int, FILE*, size_t) __INTRODUCED_IN(17);
+size_t __fread_chk(void* __restrict, size_t, size_t, FILE* __restrict, size_t)
+ __INTRODUCED_IN(24);
+size_t __fwrite_chk(const void* __restrict, size_t, size_t, FILE* __restrict, size_t)
+ __INTRODUCED_IN(24);
+
+#if defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY)
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE __printflike(3, 0)
+int vsnprintf(char *const __pass_object_size dest, size_t size,
+ const char *_Nonnull format, __va_list ap) __overloadable {
+ return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
+}
+
+__BIONIC_FORTIFY_INLINE __printflike(2, 0)
+int vsprintf(char *const __pass_object_size dest, const char *_Nonnull format,
+ __va_list ap) __overloadable {
+ return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if defined(__clang__)
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+/*
+ * Simple case: `format` can't have format specifiers, so we can just compare
+ * its length to the length of `dest`
+ */
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int snprintf(char *__restrict dest, size_t size, const char *__restrict format)
+ __overloadable
+ __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+ __bos(dest) < __builtin_strlen(format),
+ "format string will always overflow destination buffer")
+ __errorattr("format string will always overflow destination buffer");
+
+__BIONIC_FORTIFY_INLINE
+__printflike(3, 4)
+int snprintf(char *__restrict const __pass_object_size dest,
+ size_t size, const char *__restrict format, ...) __overloadable {
+ va_list va;
+ va_start(va, format);
+ int result = __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, va);
+ va_end(va);
+ return result;
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+int sprintf(char *__restrict dest, const char *__restrict format) __overloadable
+ __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+ __bos(dest) < __builtin_strlen(format),
+ "format string will always overflow destination buffer")
+ __errorattr("format string will always overflow destination buffer");
+
+__BIONIC_FORTIFY_INLINE
+__printflike(2, 3)
+int sprintf(char *__restrict const __pass_object_size dest,
+ const char *__restrict format, ...) __overloadable {
+ va_list va;
+ va_start(va, format);
+ int result = __builtin___vsprintf_chk(dest, 0, __bos(dest), format, va);
+ va_end(va);
+ return result;
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+size_t fread(void *__restrict buf, size_t size, size_t count,
+ FILE *__restrict stream) __overloadable
+ __enable_if(__unsafe_check_mul_overflow(size, count), "size * count overflows")
+ __errorattr("size * count overflows");
+
+__BIONIC_FORTIFY_INLINE
+size_t fread(void *__restrict buf, size_t size, size_t count,
+ FILE *__restrict stream) __overloadable
+ __enable_if(!__unsafe_check_mul_overflow(size, count), "no overflow")
+ __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+ size * count > __bos(buf), "size * count is too large")
+ __errorattr("size * count is too large");
+
+__BIONIC_FORTIFY_INLINE
+size_t fread(void *__restrict const __pass_object_size0 buf, size_t size,
+ size_t count, FILE *__restrict stream) __overloadable {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(fread)(buf, size, count, stream);
+ }
+
+ return __fread_chk(buf, size, count, stream, bos);
+}
+
+size_t fwrite(const void * __restrict buf, size_t size,
+ size_t count, FILE * __restrict stream) __overloadable
+ __enable_if(__unsafe_check_mul_overflow(size, count),
+ "size * count overflows")
+ __errorattr("size * count overflows");
+
+size_t fwrite(const void * __restrict buf, size_t size,
+ size_t count, FILE * __restrict stream) __overloadable
+ __enable_if(!__unsafe_check_mul_overflow(size, count), "no overflow")
+ __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
+ size * count > __bos(buf), "size * count is too large")
+ __errorattr("size * count is too large");
+
+__BIONIC_FORTIFY_INLINE
+size_t fwrite(const void * __restrict const __pass_object_size0 buf,
+ size_t size, size_t count, FILE * __restrict stream)
+ __overloadable {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(fwrite)(buf, size, count, stream);
+ }
+
+ return __fwrite_chk(buf, size, count, stream, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+char *fgets(char* __restrict dest, int size, FILE* stream) __overloadable
+ __enable_if(size < 0, "size is negative")
+ __errorattr("size is negative");
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+char *fgets(char* dest, int size, FILE* stream) __overloadable
+ __enable_if(size >= 0 && size > __bos(dest),
+ "size is larger than the destination buffer")
+ __errorattr("size is larger than the destination buffer");
+
+__BIONIC_FORTIFY_INLINE
+char *fgets(char* __restrict const __pass_object_size dest,
+ int size, FILE* stream) __overloadable {
+ size_t bos = __bos(dest);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(fgets)(dest, size, stream);
+ }
+
+ return __fgets_chk(dest, size, stream, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#else /* defined(__clang__) */
+
+size_t __fread_real(void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fread);
+__errordecl(__fread_too_big_error, "fread called with size * count bigger than buffer");
+__errordecl(__fread_overflow, "fread called with overflowing size * count");
+
+char* __fgets_real(char*, int, FILE*) __RENAME(fgets);
+__errordecl(__fgets_too_big_error, "fgets called with size bigger than buffer");
+__errordecl(__fgets_too_small_error, "fgets called with size less than zero");
+
+size_t __fwrite_real(const void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fwrite);
+__errordecl(__fwrite_too_big_error, "fwrite called with size * count bigger than buffer");
+__errordecl(__fwrite_overflow, "fwrite called with overflowing size * count");
+
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE __printflike(3, 4)
+int snprintf(char *__restrict dest, size_t size, const char* _Nonnull format, ...)
+{
+ return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format,
+ __builtin_va_arg_pack());
+}
+
+__BIONIC_FORTIFY_INLINE __printflike(2, 3)
+int sprintf(char *__restrict dest, const char* _Nonnull format, ...) {
+ return __builtin___sprintf_chk(dest, 0, __bos(dest), format,
+ __builtin_va_arg_pack());
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+size_t fread(void *__restrict buf, size_t size, size_t count, FILE * __restrict stream) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __fread_real(buf, size, count, stream);
+ }
+
+ if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
+ size_t total;
+ if (__size_mul_overflow(size, count, &total)) {
+ __fread_overflow();
+ }
+
+ if (total > bos) {
+ __fread_too_big_error();
+ }
+
+ return __fread_real(buf, size, count, stream);
+ }
+
+ return __fread_chk(buf, size, count, stream, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict stream) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __fwrite_real(buf, size, count, stream);
+ }
+
+ if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
+ size_t total;
+ if (__size_mul_overflow(size, count, &total)) {
+ __fwrite_overflow();
+ }
+
+ if (total > bos) {
+ __fwrite_too_big_error();
+ }
+
+ return __fwrite_real(buf, size, count, stream);
+ }
+
+ return __fwrite_chk(buf, size, count, stream, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+char *fgets(char* dest, int size, FILE* stream) {
+ size_t bos = __bos(dest);
+
+ // Compiler can prove, at compile time, that the passed in size
+ // is always negative. Force a compiler error.
+ if (__builtin_constant_p(size) && (size < 0)) {
+ __fgets_too_small_error();
+ }
+
+ // Compiler doesn't know destination size. Don't call __fgets_chk
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __fgets_real(dest, size, stream);
+ }
+
+ // Compiler can prove, at compile time, that the passed in size
+ // is always <= the actual object size. Don't call __fgets_chk
+ if (__builtin_constant_p(size) && (size <= (int) bos)) {
+ return __fgets_real(dest, size, stream);
+ }
+
+ // Compiler can prove, at compile time, that the passed in size
+ // is always > the actual object size. Force a compiler error.
+ if (__builtin_constant_p(size) && (size > (int) bos)) {
+ __fgets_too_big_error();
+ }
+
+ return __fgets_chk(dest, size, stream, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#endif /* defined(__clang__) */
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/stdlib.h b/libc/include/bits/fortify/stdlib.h
new file mode 100644
index 0000000..bda1d45
--- /dev/null
+++ b/libc/include/bits/fortify/stdlib.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _STDLIB_H
+#error "Never include this file directly; instead, include <stdlib.h>"
+#endif
+
+#if defined(__BIONIC_FORTIFY)
+#define __realpath_buf_too_small_str \
+ "realpath output parameter must be NULL or a >= PATH_MAX bytes buffer"
+
+/* 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.
+ */
+
+#else /* defined(__clang__) */
+
+char* __realpath_real(const char*, char*) __RENAME(realpath);
+__errordecl(__realpath_size_error, __realpath_buf_too_small_str);
+
+__BIONIC_FORTIFY_INLINE
+char* realpath(const char* path, char* resolved) {
+ size_t bos = __bos(resolved);
+
+ if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < __PATH_MAX) {
+ __realpath_size_error();
+ }
+
+ return __realpath_real(path, resolved);
+}
+
+#endif /* defined(__clang__) */
+
+#undef __PATH_MAX
+#undef __realpath_buf_too_small_str
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/string.h b/libc/include/bits/fortify/string.h
new file mode 100644
index 0000000..74e87a4
--- /dev/null
+++ b/libc/include/bits/fortify/string.h
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _STRING_H
+#error "Never include this file directly; instead, include <string.h>"
+#endif
+
+void* __memchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
+void* __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
+char* __stpncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
+ __INTRODUCED_IN(21);
+char* __strncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
+ __INTRODUCED_IN(21);
+size_t __strlcpy_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
+size_t __strlcat_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
+
+/* Only used with FORTIFY, but some headers that need it undef FORTIFY, so we
+ * have the definition out here.
+ */
+struct __bionic_zero_size_is_okay_t {};
+
+#if defined(__BIONIC_FORTIFY)
+// These can share their implementation between gcc and clang with minimal
+// trickery...
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+void* memcpy(void* _Nonnull __restrict const dst __pass_object_size0, const void* _Nonnull __restrict src, size_t copy_amount)
+ __overloadable {
+ return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memmove(void* const _Nonnull dst __pass_object_size0, const void* _Nonnull src, size_t len)
+ __overloadable {
+ return __builtin___memmove_chk(dst, src, len, __bos0(dst));
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_FORTIFY_INLINE
+char* stpcpy(char* _Nonnull __restrict const dst __pass_object_size, const char* _Nonnull __restrict src)
+ __overloadable {
+ return __builtin___stpcpy_chk(dst, src, __bos(dst));
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+char* strcpy(char* _Nonnull __restrict const dst __pass_object_size, const char* _Nonnull __restrict src)
+ __overloadable {
+ return __builtin___strcpy_chk(dst, src, __bos(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strcat(char* _Nonnull __restrict const dst __pass_object_size, const char* _Nonnull __restrict src)
+ __overloadable {
+ return __builtin___strcat_chk(dst, src, __bos(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strncat(char* const _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t n)
+ __overloadable {
+ return __builtin___strncat_chk(dst, src, n, __bos(dst));
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n) __overloadable {
+ return __builtin___memset_chk(s, c, n, __bos0(s));
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+
+#if defined(__clang__)
+
+#define __error_if_overflows_dst(name, dst, n, what) \
+ __enable_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \
+ __bos0(dst) < (n), "selected when the buffer is too small") \
+ __errorattr(#name " called with " what " bigger than buffer")
+
+/*
+ * N.B. _Nonnull isn't necessary on params, since these functions just emit
+ * errors.
+ */
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+void* memcpy(void* dst, const void* src, size_t copy_amount) __overloadable
+ __error_if_overflows_dst(memcpy, dst, copy_amount, "size");
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+void* memmove(void *dst, const void* src, size_t len) __overloadable
+ __error_if_overflows_dst(memmove, dst, len, "size");
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+void* memset(void* s, int c, size_t n) __overloadable
+ __error_if_overflows_dst(memset, s, n, "size");
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+char* stpcpy(char* dst, const char* src) __overloadable
+ __error_if_overflows_dst(stpcpy, dst, __builtin_strlen(src), "string");
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+char* strcpy(char* dst, const char* src) __overloadable
+ __error_if_overflows_dst(strcpy, dst, __builtin_strlen(src), "string");
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+void* memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
+ __overloadable {
+ size_t bos = __bos(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_memchr(s, c, n);
+ }
+
+ return __memchr_chk(s, c, n, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memrchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
+ __overloadable {
+ size_t bos = __bos(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(memrchr)(s, c, n);
+ }
+
+ return __memrchr_chk(s, c, n, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_FORTIFY_INLINE
+char* stpncpy(char* __restrict const _Nonnull dst __pass_object_size, const char* __restrict const _Nonnull src __pass_object_size, size_t n)
+ __overloadable {
+ size_t bos_dst = __bos(dst);
+ size_t bos_src = __bos(src);
+
+ /* Ignore dst size checks; they're handled in strncpy_chk */
+ if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin___stpncpy_chk(dst, src, n, bos_dst);
+ }
+
+ return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strncpy(char* __restrict const _Nonnull dst __pass_object_size, const char* __restrict const _Nonnull src __pass_object_size, size_t n)
+ __overloadable {
+ size_t bos_dst = __bos(dst);
+ size_t bos_src = __bos(src);
+
+ /* Ignore dst size checks; they're handled in strncpy_chk */
+ if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin___strncpy_chk(dst, src, n, bos_dst);
+ }
+
+ return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+size_t strlcpy(char* const _Nonnull __restrict dst __pass_object_size, const char *_Nonnull __restrict src, size_t size)
+ __overloadable {
+ size_t bos = __bos(dst);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(strlcpy)(dst, src, size);
+ }
+
+ return __strlcpy_chk(dst, src, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t strlcat(char* const _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t size)
+ __overloadable {
+ size_t bos = __bos(dst);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(strlcat)(dst, src, size);
+ }
+
+ return __strlcat_chk(dst, src, size, bos);
+}
+
+/*
+ * If we can evaluate the size of s at compile-time, just call __builtin_strlen
+ * on it directly. This makes it way easier for compilers to fold things like
+ * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
+ * because it's large.
+ */
+__BIONIC_FORTIFY_INLINE
+size_t strlen(const char* const _Nonnull s __pass_object_size)
+ __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
+ "enabled if s is a known good string.") {
+ return __builtin_strlen(s);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t strlen(const char* const _Nonnull s __pass_object_size0)
+ __overloadable {
+ size_t bos = __bos0(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_strlen(s);
+ }
+
+ // return __builtin_strlen(s);
+ return __strlen_chk(s, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
+__BIONIC_FORTIFY_INLINE
+char* strchr(const char* const _Nonnull s __pass_object_size, int c)
+ __overloadable {
+ size_t bos = __bos(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_strchr(s, c);
+ }
+
+ return __strchr_chk(s, c, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strrchr(const char* const _Nonnull s __pass_object_size, int c)
+ __overloadable {
+ size_t bos = __bos(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_strrchr(s, c);
+ }
+
+ return __strrchr_chk(s, c, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+/* In *many* cases, memset(foo, sizeof(foo), 0) is a mistake where the user has
+ * flipped the size + value arguments. However, there may be cases (e.g. with
+ * macros) where it's okay for the size to fold to zero. We should warn on this,
+ * but we should also provide a FORTIFY'ed escape hatch.
+ */
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+void* memset(void* _Nonnull s, int c, size_t n, struct __bionic_zero_size_is_okay_t ok)
+ __overloadable
+ __error_if_overflows_dst(memset, s, n, "size");
+
+__BIONIC_FORTIFY_INLINE
+void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n, struct __bionic_zero_size_is_okay_t ok __attribute__((unused)))
+ __overloadable {
+ return __builtin___memset_chk(s, c, n, __bos0(s));
+}
+
+extern struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay;
+/* We verify that `c` is non-zero, because as pointless as memset(foo, 0, 0) is,
+ * flipping size + count will do nothing.
+ */
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+void* memset(void* _Nonnull s, int c, size_t n) __overloadable
+ __enable_if(c && !n, "selected when we'll set zero bytes")
+ __RENAME_CLANG(memset)
+ __warnattr_real("will set 0 bytes; maybe the arguments got flipped? "
+ "(Add __bionic_zero_size_is_okay as a fourth argument "
+ "to silence this.)");
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#undef __error_zero_size
+#undef __error_if_overflows_dst
+#else // defined(__clang__)
+extern char* __strncpy_real(char* __restrict, const char*, size_t) __RENAME(strncpy);
+extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
+extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t)
+ __RENAME(strlcpy);
+extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t)
+ __RENAME(strlcat);
+
+__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
+__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+void* memchr(const void *_Nonnull s __pass_object_size, int c, size_t n) {
+ size_t bos = __bos(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_memchr(s, c, n);
+ }
+
+ if (__builtin_constant_p(n) && (n > bos)) {
+ __memchr_buf_size_error();
+ }
+
+ if (__builtin_constant_p(n) && (n <= bos)) {
+ return __builtin_memchr(s, c, n);
+ }
+
+ return __memchr_chk(s, c, n, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+void* memrchr(const void* s, int c, size_t n) {
+ size_t bos = __bos(s);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __memrchr_real(s, c, n);
+ }
+
+ if (__builtin_constant_p(n) && (n > bos)) {
+ __memrchr_buf_size_error();
+ }
+
+ if (__builtin_constant_p(n) && (n <= bos)) {
+ return __memrchr_real(s, c, n);
+ }
+
+ return __memrchr_chk(s, c, n, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_FORTIFY_INLINE
+char* stpncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
+ size_t bos_dst = __bos(dst);
+ size_t bos_src = __bos(src);
+
+ if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin___stpncpy_chk(dst, src, n, bos_dst);
+ }
+
+ if (__builtin_constant_p(n) && (n <= bos_src)) {
+ return __builtin___stpncpy_chk(dst, src, n, bos_dst);
+ }
+
+ size_t slen = __builtin_strlen(src);
+ if (__builtin_constant_p(slen)) {
+ return __builtin___stpncpy_chk(dst, src, n, bos_dst);
+ }
+
+ return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
+ size_t bos_dst = __bos(dst);
+ size_t bos_src = __bos(src);
+
+ if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __strncpy_real(dst, src, n);
+ }
+
+ if (__builtin_constant_p(n) && (n <= bos_src)) {
+ return __builtin___strncpy_chk(dst, src, n, bos_dst);
+ }
+
+ size_t slen = __builtin_strlen(src);
+ if (__builtin_constant_p(slen)) {
+ return __builtin___strncpy_chk(dst, src, n, bos_dst);
+ }
+
+ return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
+__BIONIC_FORTIFY_INLINE
+size_t strlcpy(char* _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t size) {
+ size_t bos = __bos(dst);
+
+ // Compiler doesn't know destination size. Don't call __strlcpy_chk
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __strlcpy_real(dst, src, size);
+ }
+
+ // Compiler can prove, at compile time, that the passed in size
+ // is always <= the actual object size. Don't call __strlcpy_chk
+ if (__builtin_constant_p(size) && (size <= bos)) {
+ return __strlcpy_real(dst, src, size);
+ }
+
+ return __strlcpy_chk(dst, src, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t strlcat(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t size) {
+ size_t bos = __bos(dst);
+
+ // Compiler doesn't know destination size. Don't call __strlcat_chk
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __strlcat_real(dst, src, size);
+ }
+
+ // Compiler can prove, at compile time, that the passed in size
+ // is always <= the actual object size. Don't call __strlcat_chk
+ if (__builtin_constant_p(size) && (size <= bos)) {
+ return __strlcat_real(dst, src, size);
+ }
+
+ return __strlcat_chk(dst, src, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+size_t strlen(const char* _Nonnull s) __overloadable {
+ size_t bos = __bos(s);
+
+ // Compiler doesn't know destination size. Don't call __strlen_chk
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_strlen(s);
+ }
+
+ size_t slen = __builtin_strlen(s);
+ if (__builtin_constant_p(slen)) {
+ return slen;
+ }
+
+ return __strlen_chk(s, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
+__BIONIC_FORTIFY_INLINE
+char* strchr(const char* _Nonnull s, int c) {
+ size_t bos = __bos(s);
+
+ // Compiler doesn't know destination size. Don't call __strchr_chk
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_strchr(s, c);
+ }
+
+ size_t slen = __builtin_strlen(s);
+ if (__builtin_constant_p(slen) && (slen < bos)) {
+ return __builtin_strchr(s, c);
+ }
+
+ return __strchr_chk(s, c, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+char* strrchr(const char* _Nonnull s, int c) {
+ size_t bos = __bos(s);
+
+ // Compiler doesn't know destination size. Don't call __strrchr_chk
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __builtin_strrchr(s, c);
+ }
+
+ size_t slen = __builtin_strlen(s);
+ if (__builtin_constant_p(slen) && (slen < bos)) {
+ return __builtin_strrchr(s, c);
+ }
+
+ return __strrchr_chk(s, c, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
+#endif /* defined(__clang__) */
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/bits/fortify/unistd.h b/libc/include/bits/fortify/unistd.h
new file mode 100644
index 0000000..5df67b4
--- /dev/null
+++ b/libc/include/bits/fortify/unistd.h
@@ -0,0 +1,525 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef _UNISTD_H_
+#error "Never include this file directly; instead, include <unistd.h>"
+#endif
+
+char* __getcwd_chk(char*, size_t, size_t) __INTRODUCED_IN(24);
+
+ssize_t __pread_chk(int, void*, size_t, off_t, size_t) __INTRODUCED_IN(23);
+ssize_t __pread_real(int, void*, size_t, off_t) __RENAME(pread);
+
+ssize_t __pread64_chk(int, void*, size_t, off64_t, size_t) __INTRODUCED_IN(23);
+ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64) __INTRODUCED_IN(12);
+
+ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t) __INTRODUCED_IN(24);
+ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite);
+
+ssize_t __pwrite64_chk(int, const void*, size_t, off64_t, size_t) __INTRODUCED_IN(24);
+ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64)
+ __INTRODUCED_IN(12);
+
+ssize_t __read_chk(int, void*, size_t, size_t) __INTRODUCED_IN(21);
+ssize_t __write_chk(int, const void*, size_t, size_t) __INTRODUCED_IN(24);
+ssize_t __readlink_chk(const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
+ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
+
+#if defined(__BIONIC_FORTIFY)
+
+#if defined(__USE_FILE_OFFSET64)
+#define __PREAD_PREFIX(x) __pread64_ ## x
+#define __PWRITE_PREFIX(x) __pwrite64_ ## x
+#else
+#define __PREAD_PREFIX(x) __pread_ ## x
+#define __PWRITE_PREFIX(x) __pwrite_ ## x
+#endif
+
+#if defined(__clang__)
+#define __error_if_overflows_ssizet(what) \
+ __enable_if(what > SSIZE_MAX, #what " must be <= SSIZE_MAX") \
+ __errorattr(#what " must be <= SSIZE_MAX")
+
+#define __enable_if_no_overflow_ssizet(what) \
+ __enable_if((what) <= SSIZE_MAX, "enabled if " #what " <= SSIZE_MAX")
+
+#define __error_if_overflows_objectsize(what, objsize) \
+ __enable_if((objsize) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \
+ (what) > (objsize), \
+ "'" #what "' bytes overflows the given object") \
+ __errorattr("'" #what "' bytes overflows the given object")
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+char* getcwd(char* buf, size_t size) __overloadable
+ __error_if_overflows_objectsize(size, __bos(buf));
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+char* getcwd(char* const __pass_object_size buf, size_t size) __overloadable {
+ size_t bos = __bos(buf);
+
+ /*
+ * Clang responds bos==0 if buf==NULL
+ * (https://llvm.org/bugs/show_bug.cgi?id=23277). Given that NULL is a valid
+ * value, we need to handle that.
+ */
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE || buf == NULL) {
+ return __call_bypassing_fortify(getcwd)(buf, size);
+ }
+
+ return __getcwd_chk(buf, size, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pread(int fd, void* buf, size_t count, off_t offset) __overloadable
+ __error_if_overflows_ssizet(count);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pread(int fd, void* buf, size_t count, off_t offset) __overloadable
+ __enable_if_no_overflow_ssizet(count)
+ __error_if_overflows_objectsize(count, __bos0(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pread(int fd, void* const __pass_object_size0 buf, size_t count,
+ off_t offset) __overloadable {
+ size_t bos = __bos0(buf);
+
+ if (count == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __PREAD_PREFIX(real)(fd, buf, count, offset);
+ }
+
+ return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) __overloadable
+ __error_if_overflows_ssizet(count);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) __overloadable
+ __enable_if_no_overflow_ssizet(count)
+ __error_if_overflows_objectsize(count, __bos0(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pread64(int fd, void* const __pass_object_size0 buf, size_t count,
+ off64_t offset) __overloadable {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __pread64_real(fd, buf, count, offset);
+ }
+
+ return __pread64_chk(fd, buf, count, offset, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset)
+ __overloadable
+ __error_if_overflows_ssizet(count);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset)
+ __overloadable
+ __enable_if_no_overflow_ssizet(count)
+ __error_if_overflows_objectsize(count, __bos0(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite(int fd, const void* const __pass_object_size0 buf, size_t count,
+ off_t offset) __overloadable {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __PWRITE_PREFIX(real)(fd, buf, count, offset);
+ }
+
+ return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset)
+ __overloadable
+ __error_if_overflows_ssizet(count);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset)
+ __overloadable
+ __enable_if_no_overflow_ssizet(count)
+ __error_if_overflows_objectsize(count, __bos0(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite64(int fd, const void* const __pass_object_size0 buf,
+ size_t count, off64_t offset) __overloadable {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __pwrite64_real(fd, buf, count, offset);
+ }
+
+ return __pwrite64_chk(fd, buf, count, offset, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t read(int fd, void* buf, size_t count) __overloadable
+ __error_if_overflows_ssizet(count);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t read(int fd, void* buf, size_t count) __overloadable
+ __enable_if_no_overflow_ssizet(count)
+ __error_if_overflows_objectsize(count, __bos0(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t read(int fd, void* const __pass_object_size0 buf, size_t count)
+ __overloadable {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(read)(fd, buf, count);
+ }
+
+ return __read_chk(fd, buf, count, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t write(int fd, const void* buf, size_t count) __overloadable
+ __error_if_overflows_ssizet(count);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t write(int fd, const void* buf, size_t count) __overloadable
+ __enable_if_no_overflow_ssizet(count)
+ __error_if_overflows_objectsize(count, __bos0(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t write(int fd, const void* const __pass_object_size0 buf, size_t count)
+ __overloadable {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(write)(fd, buf, count);
+ }
+
+ return __write_chk(fd, buf, count, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t readlink(const char* path, char* buf, size_t size) __overloadable
+ __error_if_overflows_ssizet(size);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t readlink(const char* path, char* buf, size_t size) __overloadable
+ __enable_if_no_overflow_ssizet(size)
+ __error_if_overflows_objectsize(size, __bos(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t readlink(const char* path, char* const __pass_object_size buf,
+ size_t size) __overloadable {
+ size_t bos = __bos(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(readlink)(path, buf, size);
+ }
+
+ return __readlink_chk(path, buf, size, bos);
+}
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size)
+ __overloadable
+ __error_if_overflows_ssizet(size);
+
+__BIONIC_ERROR_FUNCTION_VISIBILITY
+ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size)
+ __overloadable
+ __enable_if_no_overflow_ssizet(size)
+ __error_if_overflows_objectsize(size, __bos(buf));
+
+__BIONIC_FORTIFY_INLINE
+ssize_t readlinkat(int dirfd, const char* path,
+ char* const __pass_object_size buf, size_t size)
+ __overloadable {
+ size_t bos = __bos(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __call_bypassing_fortify(readlinkat)(dirfd, path, buf, size);
+ }
+
+ return __readlinkat_chk(dirfd, path, buf, size, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#undef __enable_if_no_overflow_ssizet
+#undef __error_if_overflows_objectsize
+#undef __error_if_overflows_ssizet
+#else /* defined(__clang__) */
+
+char* __getcwd_real(char*, size_t) __RENAME(getcwd);
+ssize_t __read_real(int, void*, size_t) __RENAME(read);
+ssize_t __write_real(int, const void*, size_t) __RENAME(write);
+ssize_t __readlink_real(const char*, char*, size_t) __RENAME(readlink);
+ssize_t __readlinkat_real(int dirfd, const char*, char*, size_t) __RENAME(readlinkat);
+
+__errordecl(__getcwd_dest_size_error, "getcwd called with size bigger than destination");
+__errordecl(__pread_dest_size_error, "pread called with size bigger than destination");
+__errordecl(__pread_count_toobig_error, "pread called with count > SSIZE_MAX");
+__errordecl(__pread64_dest_size_error, "pread64 called with size bigger than destination");
+__errordecl(__pread64_count_toobig_error, "pread64 called with count > SSIZE_MAX");
+__errordecl(__pwrite_dest_size_error, "pwrite called with size bigger than destination");
+__errordecl(__pwrite_count_toobig_error, "pwrite called with count > SSIZE_MAX");
+__errordecl(__pwrite64_dest_size_error, "pwrite64 called with size bigger than destination");
+__errordecl(__pwrite64_count_toobig_error, "pwrite64 called with count > SSIZE_MAX");
+__errordecl(__read_dest_size_error, "read called with size bigger than destination");
+__errordecl(__read_count_toobig_error, "read called with count > SSIZE_MAX");
+__errordecl(__write_dest_size_error, "write called with size bigger than destination");
+__errordecl(__write_count_toobig_error, "write called with count > SSIZE_MAX");
+__errordecl(__readlink_dest_size_error, "readlink called with size bigger than destination");
+__errordecl(__readlink_size_toobig_error, "readlink called with size > SSIZE_MAX");
+__errordecl(__readlinkat_dest_size_error, "readlinkat called with size bigger than destination");
+__errordecl(__readlinkat_size_toobig_error, "readlinkat called with size > SSIZE_MAX");
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+char* getcwd(char* buf, size_t size) __overloadable {
+ size_t bos = __bos(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __getcwd_real(buf, size);
+ }
+
+ if (__builtin_constant_p(size) && (size > bos)) {
+ __getcwd_dest_size_error();
+ }
+
+ if (__builtin_constant_p(size) && (size <= bos)) {
+ return __getcwd_real(buf, size);
+ }
+
+ return __getcwd_chk(buf, size, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
+ size_t bos = __bos0(buf);
+
+ if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+ __PREAD_PREFIX(count_toobig_error)();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __PREAD_PREFIX(real)(fd, buf, count, offset);
+ }
+
+ if (__builtin_constant_p(count) && (count > bos)) {
+ __PREAD_PREFIX(dest_size_error)();
+ }
+
+ if (__builtin_constant_p(count) && (count <= bos)) {
+ return __PREAD_PREFIX(real)(fd, buf, count, offset);
+ }
+
+ return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) {
+ size_t bos = __bos0(buf);
+
+ if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+ __pread64_count_toobig_error();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __pread64_real(fd, buf, count, offset);
+ }
+
+ if (__builtin_constant_p(count) && (count > bos)) {
+ __pread64_dest_size_error();
+ }
+
+ if (__builtin_constant_p(count) && (count <= bos)) {
+ return __pread64_real(fd, buf, count, offset);
+ }
+
+ return __pread64_chk(fd, buf, count, offset, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {
+ size_t bos = __bos0(buf);
+
+ if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+ __PWRITE_PREFIX(count_toobig_error)();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __PWRITE_PREFIX(real)(fd, buf, count, offset);
+ }
+
+ if (__builtin_constant_p(count) && (count > bos)) {
+ __PWRITE_PREFIX(dest_size_error)();
+ }
+
+ if (__builtin_constant_p(count) && (count <= bos)) {
+ return __PWRITE_PREFIX(real)(fd, buf, count, offset);
+ }
+
+ return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) {
+ size_t bos = __bos0(buf);
+
+ if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+ __pwrite64_count_toobig_error();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __pwrite64_real(fd, buf, count, offset);
+ }
+
+ if (__builtin_constant_p(count) && (count > bos)) {
+ __pwrite64_dest_size_error();
+ }
+
+ if (__builtin_constant_p(count) && (count <= bos)) {
+ return __pwrite64_real(fd, buf, count, offset);
+ }
+
+ return __pwrite64_chk(fd, buf, count, offset, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_L__
+__BIONIC_FORTIFY_INLINE
+ssize_t read(int fd, void* buf, size_t count) {
+ size_t bos = __bos0(buf);
+
+ if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
+ __read_count_toobig_error();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __read_real(fd, buf, count);
+ }
+
+ if (__builtin_constant_p(count) && (count > bos)) {
+ __read_dest_size_error();
+ }
+
+ if (__builtin_constant_p(count) && (count <= bos)) {
+ return __read_real(fd, buf, count);
+ }
+
+ return __read_chk(fd, buf, count, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_N__
+__BIONIC_FORTIFY_INLINE
+ssize_t write(int fd, const void* buf, size_t count) {
+ size_t bos = __bos0(buf);
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __write_real(fd, buf, count);
+ }
+
+ if (__builtin_constant_p(count) && (count > bos)) {
+ __write_dest_size_error();
+ }
+
+ if (__builtin_constant_p(count) && (count <= bos)) {
+ return __write_real(fd, buf, count);
+ }
+
+ return __write_chk(fd, buf, count, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
+
+#if __ANDROID_API__ >= __ANDROID_API_M__
+__BIONIC_FORTIFY_INLINE
+ssize_t readlink(const char* path, char* buf, size_t size) {
+ size_t bos = __bos(buf);
+
+ if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
+ __readlink_size_toobig_error();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __readlink_real(path, buf, size);
+ }
+
+ if (__builtin_constant_p(size) && (size > bos)) {
+ __readlink_dest_size_error();
+ }
+
+ if (__builtin_constant_p(size) && (size <= bos)) {
+ return __readlink_real(path, buf, size);
+ }
+
+ return __readlink_chk(path, buf, size, bos);
+}
+
+__BIONIC_FORTIFY_INLINE
+ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size) {
+ size_t bos = __bos(buf);
+
+ if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
+ __readlinkat_size_toobig_error();
+ }
+
+ if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
+ return __readlinkat_real(dirfd, path, buf, size);
+ }
+
+ if (__builtin_constant_p(size) && (size > bos)) {
+ __readlinkat_dest_size_error();
+ }
+
+ if (__builtin_constant_p(size) && (size <= bos)) {
+ return __readlinkat_real(dirfd, path, buf, size);
+ }
+
+ return __readlinkat_chk(dirfd, path, buf, size, bos);
+}
+#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
+#endif /* defined(__clang__) */
+#undef __PREAD_PREFIX
+#undef __PWRITE_PREFIX
+#endif /* defined(__BIONIC_FORTIFY) */
diff --git a/libc/include/fcntl.h b/libc/include/fcntl.h
index f27efdf..cd52b45 100644
--- a/libc/include/fcntl.h
+++ b/libc/include/fcntl.h
@@ -91,120 +91,9 @@
int sync_file_range(int, off64_t, off64_t, unsigned int) __INTRODUCED_IN(26);
#endif
-int __open_2(const char*, int) __INTRODUCED_IN(17);
-int __openat_2(int, const char*, int) __INTRODUCED_IN(17);
-/*
- * These are the easiest way to call the real open even in clang FORTIFY.
- */
-int __open_real(const char*, int, ...) __RENAME(open);
-int __openat_real(int, const char*, int, ...) __RENAME(openat);
-
-
-#if defined(__BIONIC_FORTIFY)
-#define __open_too_many_args_error "too many arguments"
-#define __open_too_few_args_error "called with O_CREAT, but missing mode"
-#if defined(__clang__)
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int open(const char* pathname, int flags, mode_t modes, ...) __overloadable
- __errorattr(__open_too_many_args_error);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int open(const char* pathname, int flags) __overloadable
- __enable_if(flags & O_CREAT, __open_too_few_args_error)
- __errorattr(__open_too_few_args_error);
-
-/*
- * pass_object_size serves two purposes here, neither of which involve __bos: it
- * disqualifies this function from having its address taken (so &open works),
- * and it makes overload resolution prefer open(const char *, int) over
- * open(const char *, int, ...).
- */
-__BIONIC_FORTIFY_INLINE
-int open(const char* const __pass_object_size pathname,
- int flags) __overloadable {
- return __open_2(pathname, flags);
-}
-
-__BIONIC_FORTIFY_INLINE
-int open(const char* const __pass_object_size pathname, int flags, mode_t modes)
- __overloadable {
- return __open_real(pathname, flags, modes);
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int openat(int dirfd, const char* pathname, int flags) __overloadable
- __enable_if(flags & O_CREAT, __open_too_few_args_error)
- __errorattr(__open_too_few_args_error);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int openat(int dirfd, const char* pathname, int flags, mode_t modes, ...)
- __overloadable
- __errorattr(__open_too_many_args_error);
-
-__BIONIC_FORTIFY_INLINE
-int openat(int dirfd, const char* const __pass_object_size pathname,
- int flags) __overloadable {
- return __openat_2(dirfd, pathname, flags);
-}
-
-__BIONIC_FORTIFY_INLINE
-int openat(int dirfd, const char* const __pass_object_size pathname, int flags,
- mode_t modes) __overloadable {
- return __openat_real(dirfd, pathname, flags, modes);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#else /* defined(__clang__) */
-__errordecl(__creat_missing_mode, __open_too_few_args_error);
-__errordecl(__creat_too_many_args, __open_too_many_args_error);
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-int open(const char* pathname, int flags, ...) {
- if (__builtin_constant_p(flags)) {
- if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) {
- __creat_missing_mode(); /* Compile time error. */
- }
- }
-
- if (__builtin_va_arg_pack_len() > 1) {
- __creat_too_many_args(); /* Compile time error. */
- }
-
- if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
- return __open_2(pathname, flags);
- }
-
- return __open_real(pathname, flags, __builtin_va_arg_pack());
-}
-
-__BIONIC_FORTIFY_INLINE
-int openat(int dirfd, const char* pathname, int flags, ...) {
- if (__builtin_constant_p(flags)) {
- if ((flags & O_CREAT) && __builtin_va_arg_pack_len() == 0) {
- __creat_missing_mode(); /* Compile time error. */
- }
- }
-
- if (__builtin_va_arg_pack_len() > 1) {
- __creat_too_many_args(); /* Compile time error. */
- }
-
- if ((__builtin_va_arg_pack_len() == 0) && !__builtin_constant_p(flags)) {
- return __openat_2(dirfd, pathname, flags);
- }
-
- return __openat_real(dirfd, pathname, flags, __builtin_va_arg_pack());
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#endif /* defined(__clang__) */
-
-#undef __open_too_many_args_error
-#undef __open_too_few_args_error
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/fcntl.h>
+#endif
__END_DECLS
diff --git a/libc/include/poll.h b/libc/include/poll.h
index 3287a0c..0f5758d 100644
--- a/libc/include/poll.h
+++ b/libc/include/poll.h
@@ -42,87 +42,9 @@
int ppoll(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*)
__overloadable __RENAME_CLANG(ppoll) __INTRODUCED_IN(21);
-int __poll_chk(struct pollfd*, nfds_t, int, size_t) __INTRODUCED_IN(23);
-int __ppoll_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*, size_t)
- __INTRODUCED_IN(23);
-
-#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 {
- size_t bos_fds = __bos(fds);
-
- if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- 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 {
- size_t bos_fds = __bos(fds);
-
- if (bos_fds == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(ppoll)(fds, fd_count, timeout, mask);
- }
-
- return __ppoll_chk(fds, fd_count, timeout, mask, bos_fds);
-}
-#else /* defined(__clang__) */
-int __poll_real(struct pollfd*, nfds_t, int) __RENAME(poll);
-__errordecl(__poll_too_small_error, "poll: pollfd array smaller than fd count");
-
-int __ppoll_real(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*) __RENAME(ppoll)
- __INTRODUCED_IN(21);
-__errordecl(__ppoll_too_small_error, "ppoll: pollfd array smaller than fd count");
-
-__BIONIC_FORTIFY_INLINE
-int poll(struct pollfd* fds, nfds_t fd_count, int timeout) {
- if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- if (!__builtin_constant_p(fd_count)) {
- return __poll_chk(fds, fd_count, timeout, __bos(fds));
- } else if (__bos(fds) / sizeof(*fds) < fd_count) {
- __poll_too_small_error();
- }
- }
- return __poll_real(fds, fd_count, timeout);
-}
-
-__BIONIC_FORTIFY_INLINE
-int ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout,
- const sigset_t* mask) {
- if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- if (!__builtin_constant_p(fd_count)) {
- return __ppoll_chk(fds, fd_count, timeout, mask, __bos(fds));
- } else if (__bos(fds) / sizeof(*fds) < fd_count) {
- __ppoll_too_small_error();
- }
- }
- return __ppoll_real(fds, fd_count, timeout, mask);
-}
-
-#endif /* defined(__clang__) */
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/poll.h>
+#endif
__END_DECLS
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index ca56437..d2f2bd2 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -259,265 +259,9 @@
#define fwopen(cookie, fn) funopen(cookie, 0, fn, 0, 0)
#endif /* __USE_BSD */
-char* __fgets_chk(char*, int, FILE*, size_t) __INTRODUCED_IN(17);
-size_t __fread_chk(void* __restrict, size_t, size_t, FILE* __restrict, size_t)
- __INTRODUCED_IN(24);
-size_t __fwrite_chk(const void* __restrict, size_t, size_t, FILE* __restrict, size_t)
- __INTRODUCED_IN(24);
-
-#if defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY)
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE __printflike(3, 0)
-int vsnprintf(char *const __pass_object_size dest, size_t size,
- const char *_Nonnull format, __va_list ap) __overloadable {
- return __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, ap);
-}
-
-__BIONIC_FORTIFY_INLINE __printflike(2, 0)
-int vsprintf(char *const __pass_object_size dest, const char *_Nonnull format,
- __va_list ap) __overloadable {
- return __builtin___vsprintf_chk(dest, 0, __bos(dest), format, ap);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if defined(__clang__)
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-/*
- * Simple case: `format` can't have format specifiers, so we can just compare
- * its length to the length of `dest`
- */
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int snprintf(char *__restrict dest, size_t size, const char *__restrict format)
- __overloadable
- __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos(dest) < __builtin_strlen(format),
- "format string will always overflow destination buffer")
- __errorattr("format string will always overflow destination buffer");
-
-__BIONIC_FORTIFY_INLINE
-__printflike(3, 4)
-int snprintf(char *__restrict const __pass_object_size dest,
- size_t size, const char *__restrict format, ...) __overloadable {
- va_list va;
- va_start(va, format);
- int result = __builtin___vsnprintf_chk(dest, size, 0, __bos(dest), format, va);
- va_end(va);
- return result;
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-int sprintf(char *__restrict dest, const char *__restrict format) __overloadable
- __enable_if(__bos(dest) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- __bos(dest) < __builtin_strlen(format),
- "format string will always overflow destination buffer")
- __errorattr("format string will always overflow destination buffer");
-
-__BIONIC_FORTIFY_INLINE
-__printflike(2, 3)
-int sprintf(char *__restrict const __pass_object_size dest,
- const char *__restrict format, ...) __overloadable {
- va_list va;
- va_start(va, format);
- int result = __builtin___vsprintf_chk(dest, 0, __bos(dest), format, va);
- va_end(va);
- return result;
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-size_t fread(void *__restrict buf, size_t size, size_t count,
- FILE *__restrict stream) __overloadable
- __enable_if(__unsafe_check_mul_overflow(size, count), "size * count overflows")
- __errorattr("size * count overflows");
-
-__BIONIC_FORTIFY_INLINE
-size_t fread(void *__restrict buf, size_t size, size_t count,
- FILE *__restrict stream) __overloadable
- __enable_if(!__unsafe_check_mul_overflow(size, count), "no overflow")
- __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- size * count > __bos(buf), "size * count is too large")
- __errorattr("size * count is too large");
-
-__BIONIC_FORTIFY_INLINE
-size_t fread(void *__restrict const __pass_object_size0 buf, size_t size,
- size_t count, FILE *__restrict stream) __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(fread)(buf, size, count, stream);
- }
-
- return __fread_chk(buf, size, count, stream, bos);
-}
-
-size_t fwrite(const void * __restrict buf, size_t size,
- size_t count, FILE * __restrict stream) __overloadable
- __enable_if(__unsafe_check_mul_overflow(size, count),
- "size * count overflows")
- __errorattr("size * count overflows");
-
-size_t fwrite(const void * __restrict buf, size_t size,
- size_t count, FILE * __restrict stream) __overloadable
- __enable_if(!__unsafe_check_mul_overflow(size, count), "no overflow")
- __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
- size * count > __bos(buf), "size * count is too large")
- __errorattr("size * count is too large");
-
-__BIONIC_FORTIFY_INLINE
-size_t fwrite(const void * __restrict const __pass_object_size0 buf,
- size_t size, size_t count, FILE * __restrict stream)
- __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(fwrite)(buf, size, count, stream);
- }
-
- return __fwrite_chk(buf, size, count, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char *fgets(char* __restrict dest, int size, FILE* stream) __overloadable
- __enable_if(size < 0, "size is negative")
- __errorattr("size is negative");
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char *fgets(char* dest, int size, FILE* stream) __overloadable
- __enable_if(size >= 0 && size > __bos(dest),
- "size is larger than the destination buffer")
- __errorattr("size is larger than the destination buffer");
-
-__BIONIC_FORTIFY_INLINE
-char *fgets(char* __restrict const __pass_object_size dest,
- int size, FILE* stream) __overloadable {
- size_t bos = __bos(dest);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(fgets)(dest, size, stream);
- }
-
- return __fgets_chk(dest, size, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#else /* defined(__clang__) */
-
-size_t __fread_real(void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fread);
-__errordecl(__fread_too_big_error, "fread called with size * count bigger than buffer");
-__errordecl(__fread_overflow, "fread called with overflowing size * count");
-
-char* __fgets_real(char*, int, FILE*) __RENAME(fgets);
-__errordecl(__fgets_too_big_error, "fgets called with size bigger than buffer");
-__errordecl(__fgets_too_small_error, "fgets called with size less than zero");
-
-size_t __fwrite_real(const void * __restrict, size_t, size_t, FILE * __restrict) __RENAME(fwrite);
-__errordecl(__fwrite_too_big_error, "fwrite called with size * count bigger than buffer");
-__errordecl(__fwrite_overflow, "fwrite called with overflowing size * count");
-
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE __printflike(3, 4)
-int snprintf(char *__restrict dest, size_t size, const char* _Nonnull format, ...)
-{
- return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format,
- __builtin_va_arg_pack());
-}
-
-__BIONIC_FORTIFY_INLINE __printflike(2, 3)
-int sprintf(char *__restrict dest, const char* _Nonnull format, ...) {
- return __builtin___sprintf_chk(dest, 0, __bos(dest), format,
- __builtin_va_arg_pack());
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-size_t fread(void *__restrict buf, size_t size, size_t count, FILE * __restrict stream) {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __fread_real(buf, size, count, stream);
- }
-
- if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
- size_t total;
- if (__size_mul_overflow(size, count, &total)) {
- __fread_overflow();
- }
-
- if (total > bos) {
- __fread_too_big_error();
- }
-
- return __fread_real(buf, size, count, stream);
- }
-
- return __fread_chk(buf, size, count, stream, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __restrict stream) {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __fwrite_real(buf, size, count, stream);
- }
-
- if (__builtin_constant_p(size) && __builtin_constant_p(count)) {
- size_t total;
- if (__size_mul_overflow(size, count, &total)) {
- __fwrite_overflow();
- }
-
- if (total > bos) {
- __fwrite_too_big_error();
- }
-
- return __fwrite_real(buf, size, count, stream);
- }
-
- return __fwrite_chk(buf, size, count, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-char *fgets(char* dest, int size, FILE* stream) {
- size_t bos = __bos(dest);
-
- // Compiler can prove, at compile time, that the passed in size
- // is always negative. Force a compiler error.
- if (__builtin_constant_p(size) && (size < 0)) {
- __fgets_too_small_error();
- }
-
- // Compiler doesn't know destination size. Don't call __fgets_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __fgets_real(dest, size, stream);
- }
-
- // Compiler can prove, at compile time, that the passed in size
- // is always <= the actual object size. Don't call __fgets_chk
- if (__builtin_constant_p(size) && (size <= (int) bos)) {
- return __fgets_real(dest, size, stream);
- }
-
- // Compiler can prove, at compile time, that the passed in size
- // is always > the actual object size. Force a compiler error.
- if (__builtin_constant_p(size) && (size > (int) bos)) {
- __fgets_too_big_error();
- }
-
- return __fgets_chk(dest, size, stream, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#endif /* defined(__clang__) */
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/stdio.h>
+#endif
#if defined(__clang__)
#pragma clang diagnostic pop
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 24ddd99..55e0fa2 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -165,46 +165,9 @@
#define MB_CUR_MAX 1
#endif
-#if defined(__BIONIC_FORTIFY)
-#define __realpath_buf_too_small_str \
- "realpath output parameter must be NULL or a >= PATH_MAX bytes buffer"
-
-/* 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.
- */
-
-#else /* defined(__clang__) */
-
-char* __realpath_real(const char*, char*) __RENAME(realpath);
-__errordecl(__realpath_size_error, __realpath_buf_too_small_str);
-
-__BIONIC_FORTIFY_INLINE
-char* realpath(const char* path, char* resolved) {
- size_t bos = __bos(resolved);
-
- if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < __PATH_MAX) {
- __realpath_size_error();
- }
-
- return __realpath_real(path, resolved);
-}
-
-#endif /* defined(__clang__) */
-
-#undef __PATH_MAX
-#undef __realpath_buf_too_small_str
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/stdlib.h>
+#endif
#if __ANDROID_API__ >= __ANDROID_API_L__
float strtof(const char*, char**) __INTRODUCED_IN(21);
diff --git a/libc/include/string.h b/libc/include/string.h
index c15fe4a..81eaccf 100644
--- a/libc/include/string.h
+++ b/libc/include/string.h
@@ -149,455 +149,9 @@
#endif
#endif
-void* __memchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
-void* __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
-char* __stpncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
- __INTRODUCED_IN(21);
-char* __strncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
- __INTRODUCED_IN(21);
-size_t __strlcpy_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
-size_t __strlcat_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
-
-/* Only used with FORTIFY, but some headers that need it undef FORTIFY, so we
- * have the definition out here.
- */
-struct __bionic_zero_size_is_okay_t {};
-
-#if defined(__BIONIC_FORTIFY)
-// These can share their implementation between gcc and clang with minimal
-// trickery...
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-void* memcpy(void* _Nonnull __restrict const dst __pass_object_size0, const void* _Nonnull __restrict src, size_t copy_amount)
- __overloadable {
- return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
-}
-
-__BIONIC_FORTIFY_INLINE
-void* memmove(void* const _Nonnull dst __pass_object_size0, const void* _Nonnull src, size_t len)
- __overloadable {
- return __builtin___memmove_chk(dst, src, len, __bos0(dst));
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_L__
-__BIONIC_FORTIFY_INLINE
-char* stpcpy(char* _Nonnull __restrict const dst __pass_object_size, const char* _Nonnull __restrict src)
- __overloadable {
- return __builtin___stpcpy_chk(dst, src, __bos(dst));
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-char* strcpy(char* _Nonnull __restrict const dst __pass_object_size, const char* _Nonnull __restrict src)
- __overloadable {
- return __builtin___strcpy_chk(dst, src, __bos(dst));
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strcat(char* _Nonnull __restrict const dst __pass_object_size, const char* _Nonnull __restrict src)
- __overloadable {
- return __builtin___strcat_chk(dst, src, __bos(dst));
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strncat(char* const _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t n)
- __overloadable {
- return __builtin___strncat_chk(dst, src, n, __bos(dst));
-}
-
-__BIONIC_FORTIFY_INLINE
-void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n) __overloadable {
- return __builtin___memset_chk(s, c, n, __bos0(s));
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-
-#if defined(__clang__)
-
-#define __error_if_overflows_dst(name, dst, n, what) \
- __enable_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \
- __bos0(dst) < (n), "selected when the buffer is too small") \
- __errorattr(#name " called with " what " bigger than buffer")
-
-/*
- * N.B. _Nonnull isn't necessary on params, since these functions just emit
- * errors.
- */
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-void* memcpy(void* dst, const void* src, size_t copy_amount) __overloadable
- __error_if_overflows_dst(memcpy, dst, copy_amount, "size");
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-void* memmove(void *dst, const void* src, size_t len) __overloadable
- __error_if_overflows_dst(memmove, dst, len, "size");
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-void* memset(void* s, int c, size_t n) __overloadable
- __error_if_overflows_dst(memset, s, n, "size");
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char* stpcpy(char* dst, const char* src) __overloadable
- __error_if_overflows_dst(stpcpy, dst, __builtin_strlen(src), "string");
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char* strcpy(char* dst, const char* src) __overloadable
- __error_if_overflows_dst(strcpy, dst, __builtin_strlen(src), "string");
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_FORTIFY_INLINE
-void* memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
- __overloadable {
- size_t bos = __bos(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_memchr(s, c, n);
- }
-
- return __memchr_chk(s, c, n, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-void* memrchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
- __overloadable {
- size_t bos = __bos(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(memrchr)(s, c, n);
- }
-
- return __memrchr_chk(s, c, n, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_L__
-__BIONIC_FORTIFY_INLINE
-char* stpncpy(char* __restrict const _Nonnull dst __pass_object_size, const char* __restrict const _Nonnull src __pass_object_size, size_t n)
- __overloadable {
- size_t bos_dst = __bos(dst);
- size_t bos_src = __bos(src);
-
- /* Ignore dst size checks; they're handled in strncpy_chk */
- if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin___stpncpy_chk(dst, src, n, bos_dst);
- }
-
- return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strncpy(char* __restrict const _Nonnull dst __pass_object_size, const char* __restrict const _Nonnull src __pass_object_size, size_t n)
- __overloadable {
- size_t bos_dst = __bos(dst);
- size_t bos_src = __bos(src);
-
- /* Ignore dst size checks; they're handled in strncpy_chk */
- if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin___strncpy_chk(dst, src, n, bos_dst);
- }
-
- return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-size_t strlcpy(char* const _Nonnull __restrict dst __pass_object_size, const char *_Nonnull __restrict src, size_t size)
- __overloadable {
- size_t bos = __bos(dst);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(strlcpy)(dst, src, size);
- }
-
- return __strlcpy_chk(dst, src, size, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t strlcat(char* const _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t size)
- __overloadable {
- size_t bos = __bos(dst);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(strlcat)(dst, src, size);
- }
-
- return __strlcat_chk(dst, src, size, bos);
-}
-
-/*
- * If we can evaluate the size of s at compile-time, just call __builtin_strlen
- * on it directly. This makes it way easier for compilers to fold things like
- * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
- * because it's large.
- */
-__BIONIC_FORTIFY_INLINE
-size_t strlen(const char* const _Nonnull s __pass_object_size)
- __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
- "enabled if s is a known good string.") {
- return __builtin_strlen(s);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t strlen(const char* const _Nonnull s __pass_object_size0)
- __overloadable {
- size_t bos = __bos0(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_strlen(s);
- }
-
- // return __builtin_strlen(s);
- return __strlen_chk(s, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
-__BIONIC_FORTIFY_INLINE
-char* strchr(const char* const _Nonnull s __pass_object_size, int c)
- __overloadable {
- size_t bos = __bos(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_strchr(s, c);
- }
-
- return __strchr_chk(s, c, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strrchr(const char* const _Nonnull s __pass_object_size, int c)
- __overloadable {
- size_t bos = __bos(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_strrchr(s, c);
- }
-
- return __strrchr_chk(s, c, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-/* In *many* cases, memset(foo, sizeof(foo), 0) is a mistake where the user has
- * flipped the size + value arguments. However, there may be cases (e.g. with
- * macros) where it's okay for the size to fold to zero. We should warn on this,
- * but we should also provide a FORTIFY'ed escape hatch.
- */
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-void* memset(void* _Nonnull s, int c, size_t n, struct __bionic_zero_size_is_okay_t ok)
- __overloadable
- __error_if_overflows_dst(memset, s, n, "size");
-
-__BIONIC_FORTIFY_INLINE
-void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n, struct __bionic_zero_size_is_okay_t ok __attribute__((unused)))
- __overloadable {
- return __builtin___memset_chk(s, c, n, __bos0(s));
-}
-
-extern struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay;
-/* We verify that `c` is non-zero, because as pointless as memset(foo, 0, 0) is,
- * flipping size + count will do nothing.
- */
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-void* memset(void* _Nonnull s, int c, size_t n) __overloadable
- __enable_if(c && !n, "selected when we'll set zero bytes")
- __RENAME_CLANG(memset)
- __warnattr_real("will set 0 bytes; maybe the arguments got flipped? "
- "(Add __bionic_zero_size_is_okay as a fourth argument "
- "to silence this.)");
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#undef __error_zero_size
-#undef __error_if_overflows_dst
-#else // defined(__clang__)
-extern char* __strncpy_real(char* __restrict, const char*, size_t) __RENAME(strncpy);
-extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
-extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t)
- __RENAME(strlcpy);
-extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t)
- __RENAME(strlcat);
-
-__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
-__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_FORTIFY_INLINE
-void* memchr(const void *_Nonnull s __pass_object_size, int c, size_t n) {
- size_t bos = __bos(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_memchr(s, c, n);
- }
-
- if (__builtin_constant_p(n) && (n > bos)) {
- __memchr_buf_size_error();
- }
-
- if (__builtin_constant_p(n) && (n <= bos)) {
- return __builtin_memchr(s, c, n);
- }
-
- return __memchr_chk(s, c, n, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-void* memrchr(const void* s, int c, size_t n) {
- size_t bos = __bos(s);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __memrchr_real(s, c, n);
- }
-
- if (__builtin_constant_p(n) && (n > bos)) {
- __memrchr_buf_size_error();
- }
-
- if (__builtin_constant_p(n) && (n <= bos)) {
- return __memrchr_real(s, c, n);
- }
-
- return __memrchr_chk(s, c, n, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_L__
-__BIONIC_FORTIFY_INLINE
-char* stpncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
- size_t bos_dst = __bos(dst);
- size_t bos_src = __bos(src);
-
- if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin___stpncpy_chk(dst, src, n, bos_dst);
- }
-
- if (__builtin_constant_p(n) && (n <= bos_src)) {
- return __builtin___stpncpy_chk(dst, src, n, bos_dst);
- }
-
- size_t slen = __builtin_strlen(src);
- if (__builtin_constant_p(slen)) {
- return __builtin___stpncpy_chk(dst, src, n, bos_dst);
- }
-
- return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
- size_t bos_dst = __bos(dst);
- size_t bos_src = __bos(src);
-
- if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __strncpy_real(dst, src, n);
- }
-
- if (__builtin_constant_p(n) && (n <= bos_src)) {
- return __builtin___strncpy_chk(dst, src, n, bos_dst);
- }
-
- size_t slen = __builtin_strlen(src);
- if (__builtin_constant_p(slen)) {
- return __builtin___strncpy_chk(dst, src, n, bos_dst);
- }
-
- return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
-__BIONIC_FORTIFY_INLINE
-size_t strlcpy(char* _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t size) {
- size_t bos = __bos(dst);
-
- // Compiler doesn't know destination size. Don't call __strlcpy_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __strlcpy_real(dst, src, size);
- }
-
- // Compiler can prove, at compile time, that the passed in size
- // is always <= the actual object size. Don't call __strlcpy_chk
- if (__builtin_constant_p(size) && (size <= bos)) {
- return __strlcpy_real(dst, src, size);
- }
-
- return __strlcpy_chk(dst, src, size, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t strlcat(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t size) {
- size_t bos = __bos(dst);
-
- // Compiler doesn't know destination size. Don't call __strlcat_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __strlcat_real(dst, src, size);
- }
-
- // Compiler can prove, at compile time, that the passed in size
- // is always <= the actual object size. Don't call __strlcat_chk
- if (__builtin_constant_p(size) && (size <= bos)) {
- return __strlcat_real(dst, src, size);
- }
-
- return __strlcat_chk(dst, src, size, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-size_t strlen(const char* _Nonnull s) __overloadable {
- size_t bos = __bos(s);
-
- // Compiler doesn't know destination size. Don't call __strlen_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_strlen(s);
- }
-
- size_t slen = __builtin_strlen(s);
- if (__builtin_constant_p(slen)) {
- return slen;
- }
-
- return __strlen_chk(s, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
-__BIONIC_FORTIFY_INLINE
-char* strchr(const char* _Nonnull s, int c) {
- size_t bos = __bos(s);
-
- // Compiler doesn't know destination size. Don't call __strchr_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_strchr(s, c);
- }
-
- size_t slen = __builtin_strlen(s);
- if (__builtin_constant_p(slen) && (slen < bos)) {
- return __builtin_strchr(s, c);
- }
-
- return __strchr_chk(s, c, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-char* strrchr(const char* _Nonnull s, int c) {
- size_t bos = __bos(s);
-
- // Compiler doesn't know destination size. Don't call __strrchr_chk
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __builtin_strrchr(s, c);
- }
-
- size_t slen = __builtin_strlen(s);
- if (__builtin_constant_p(slen) && (slen < bos)) {
- return __builtin_strrchr(s, c);
- }
-
- return __strrchr_chk(s, c, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
-#endif /* defined(__clang__) */
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/string.h>
+#endif
/* Const-correct overloads. Placed after FORTIFY so we call those functions, if possible. */
#if defined(__cplusplus) && defined(__clang__)
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index dd5b345..3d556f2 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -309,6 +309,11 @@
#define __pass_object_size __pass_object_size_n(__bos_level)
#define __pass_object_size0 __pass_object_size_n(0)
+/* FIXME: This should be __BIONIC_FORTIFY, but we don't enable FORTIFY in -O0. */
+#if (defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0) || defined(__BIONIC_DECLARE_FORTIFY_HELPERS)
+# define __BIONIC_INCLUDE_FORTIFY_HEADERS 1
+#endif
+
/*
* Used to support clangisms with FORTIFY. Because these change how symbols are
* emitted, we need to ensure that bionic itself is built fortified. But lots
diff --git a/libc/include/sys/socket.h b/libc/include/sys/socket.h
index 2dc54aa..6875d7f 100644
--- a/libc/include/sys/socket.h
+++ b/libc/include/sys/socket.h
@@ -325,140 +325,9 @@
__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(26);
-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
-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 {
- 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 __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 {
- 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,
- struct sockaddr* src_addr, socklen_t* addr_len) {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
- }
-
- if (__builtin_constant_p(len) && (len <= bos)) {
- return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
- }
-
- if (__builtin_constant_p(len) && (len > bos)) {
- __recvfrom_error();
- }
-
- 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,
- int flags) __overloadable {
- 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 */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/socket.h>
+#endif
#undef __socketcall
diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h
index 47ff5c4..b8e3cb1 100644
--- a/libc/include/sys/stat.h
+++ b/libc/include/sys/stat.h
@@ -167,51 +167,9 @@
int mknod(const char*, mode_t, dev_t);
mode_t umask(mode_t) __overloadable __RENAME_CLANG(umask);
-mode_t __umask_chk(mode_t) __INTRODUCED_IN(18);
-
-#if defined(__BIONIC_FORTIFY)
-#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);
-
-__BIONIC_FORTIFY_INLINE
-mode_t umask(mode_t mode) __enable_if(1, "") __overloadable {
- return __umask_chk(mode);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
-
-#else /* defined(__clang__) */
-__errordecl(__umask_invalid_mode, __umask_invalid_mode_str);
-extern mode_t __umask_real(mode_t) __RENAME(umask);
-
-#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
-__BIONIC_FORTIFY_INLINE
-mode_t umask(mode_t mode) {
- if (__builtin_constant_p(mode)) {
- if ((mode & 0777) != mode) {
- __umask_invalid_mode();
- }
- return __umask_real(mode);
- }
- return __umask_chk(mode);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
-
-#endif /* defined(__clang__) */
-#undef __umask_invalid_mode_str
-
-#endif /* defined(__BIONIC_FORTIFY) */
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/stat.h>
+#endif
#if __ANDROID_API__ >= __ANDROID_API_L__
int mkfifo(const char*, mode_t) __INTRODUCED_IN(21);
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index e024527..bacc5a7 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -241,505 +241,13 @@
} while (_rc == -1 && errno == EINTR); \
_rc; })
-/* TODO(unified-headers): Factor out all the FORTIFY features. */
-char* __getcwd_chk(char*, size_t, size_t) __INTRODUCED_IN(24);
-
-ssize_t __pread_chk(int, void*, size_t, off_t, size_t) __INTRODUCED_IN(23);
-ssize_t __pread_real(int, void*, size_t, off_t) __RENAME(pread);
-
-ssize_t __pread64_chk(int, void*, size_t, off64_t, size_t) __INTRODUCED_IN(23);
-ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64) __INTRODUCED_IN(12);
-
-ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t) __INTRODUCED_IN(24);
-ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite);
-
-ssize_t __pwrite64_chk(int, const void*, size_t, off64_t, size_t) __INTRODUCED_IN(24);
-ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64)
- __INTRODUCED_IN(12);
-
-ssize_t __read_chk(int, void*, size_t, size_t) __INTRODUCED_IN(21);
-ssize_t __write_chk(int, const void*, size_t, size_t) __INTRODUCED_IN(24);
-ssize_t __readlink_chk(const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
-ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTRODUCED_IN(23);
-
int getdomainname(char*, size_t) __INTRODUCED_IN(26);
int setdomainname(const char*, size_t) __INTRODUCED_IN(26);
-#if defined(__BIONIC_FORTIFY)
-
-#if defined(__USE_FILE_OFFSET64)
-#define __PREAD_PREFIX(x) __pread64_ ## x
-#define __PWRITE_PREFIX(x) __pwrite64_ ## x
-#else
-#define __PREAD_PREFIX(x) __pread_ ## x
-#define __PWRITE_PREFIX(x) __pwrite_ ## x
+#if defined(__BIONIC_INCLUDE_FORTIFY_HEADERS)
+#include <bits/fortify/unistd.h>
#endif
-#if defined(__clang__)
-#define __error_if_overflows_ssizet(what) \
- __enable_if(what > SSIZE_MAX, #what " must be <= SSIZE_MAX") \
- __errorattr(#what " must be <= SSIZE_MAX")
-
-#define __enable_if_no_overflow_ssizet(what) \
- __enable_if((what) <= SSIZE_MAX, "enabled if " #what " <= SSIZE_MAX")
-
-#define __error_if_overflows_objectsize(what, objsize) \
- __enable_if((objsize) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \
- (what) > (objsize), \
- "'" #what "' bytes overflows the given object") \
- __errorattr("'" #what "' bytes overflows the given object")
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-char* getcwd(char* buf, size_t size) __overloadable
- __error_if_overflows_objectsize(size, __bos(buf));
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-char* getcwd(char* const __pass_object_size buf, size_t size) __overloadable {
- size_t bos = __bos(buf);
-
- /*
- * Clang responds bos==0 if buf==NULL
- * (https://llvm.org/bugs/show_bug.cgi?id=23277). Given that NULL is a valid
- * value, we need to handle that.
- */
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE || buf == NULL) {
- return __call_bypassing_fortify(getcwd)(buf, size);
- }
-
- return __getcwd_chk(buf, size, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pread(int fd, void* buf, size_t count, off_t offset) __overloadable
- __error_if_overflows_ssizet(count);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pread(int fd, void* buf, size_t count, off_t offset) __overloadable
- __enable_if_no_overflow_ssizet(count)
- __error_if_overflows_objectsize(count, __bos0(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pread(int fd, void* const __pass_object_size0 buf, size_t count,
- off_t offset) __overloadable {
- size_t bos = __bos0(buf);
-
- if (count == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __PREAD_PREFIX(real)(fd, buf, count, offset);
- }
-
- return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) __overloadable
- __error_if_overflows_ssizet(count);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) __overloadable
- __enable_if_no_overflow_ssizet(count)
- __error_if_overflows_objectsize(count, __bos0(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pread64(int fd, void* const __pass_object_size0 buf, size_t count,
- off64_t offset) __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __pread64_real(fd, buf, count, offset);
- }
-
- return __pread64_chk(fd, buf, count, offset, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset)
- __overloadable
- __error_if_overflows_ssizet(count);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset)
- __overloadable
- __enable_if_no_overflow_ssizet(count)
- __error_if_overflows_objectsize(count, __bos0(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pwrite(int fd, const void* const __pass_object_size0 buf, size_t count,
- off_t offset) __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __PWRITE_PREFIX(real)(fd, buf, count, offset);
- }
-
- return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset)
- __overloadable
- __error_if_overflows_ssizet(count);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset)
- __overloadable
- __enable_if_no_overflow_ssizet(count)
- __error_if_overflows_objectsize(count, __bos0(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pwrite64(int fd, const void* const __pass_object_size0 buf,
- size_t count, off64_t offset) __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __pwrite64_real(fd, buf, count, offset);
- }
-
- return __pwrite64_chk(fd, buf, count, offset, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_L__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t read(int fd, void* buf, size_t count) __overloadable
- __error_if_overflows_ssizet(count);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t read(int fd, void* buf, size_t count) __overloadable
- __enable_if_no_overflow_ssizet(count)
- __error_if_overflows_objectsize(count, __bos0(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t read(int fd, void* const __pass_object_size0 buf, size_t count)
- __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(read)(fd, buf, count);
- }
-
- return __read_chk(fd, buf, count, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t write(int fd, const void* buf, size_t count) __overloadable
- __error_if_overflows_ssizet(count);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t write(int fd, const void* buf, size_t count) __overloadable
- __enable_if_no_overflow_ssizet(count)
- __error_if_overflows_objectsize(count, __bos0(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t write(int fd, const void* const __pass_object_size0 buf, size_t count)
- __overloadable {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(write)(fd, buf, count);
- }
-
- return __write_chk(fd, buf, count, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t readlink(const char* path, char* buf, size_t size) __overloadable
- __error_if_overflows_ssizet(size);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t readlink(const char* path, char* buf, size_t size) __overloadable
- __enable_if_no_overflow_ssizet(size)
- __error_if_overflows_objectsize(size, __bos(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t readlink(const char* path, char* const __pass_object_size buf,
- size_t size) __overloadable {
- size_t bos = __bos(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(readlink)(path, buf, size);
- }
-
- return __readlink_chk(path, buf, size, bos);
-}
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size)
- __overloadable
- __error_if_overflows_ssizet(size);
-
-__BIONIC_ERROR_FUNCTION_VISIBILITY
-ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size)
- __overloadable
- __enable_if_no_overflow_ssizet(size)
- __error_if_overflows_objectsize(size, __bos(buf));
-
-__BIONIC_FORTIFY_INLINE
-ssize_t readlinkat(int dirfd, const char* path,
- char* const __pass_object_size buf, size_t size)
- __overloadable {
- size_t bos = __bos(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __call_bypassing_fortify(readlinkat)(dirfd, path, buf, size);
- }
-
- return __readlinkat_chk(dirfd, path, buf, size, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-
-#undef __enable_if_no_overflow_ssizet
-#undef __error_if_overflows_objectsize
-#undef __error_if_overflows_ssizet
-#else /* defined(__clang__) */
-
-char* __getcwd_real(char*, size_t) __RENAME(getcwd);
-ssize_t __read_real(int, void*, size_t) __RENAME(read);
-ssize_t __write_real(int, const void*, size_t) __RENAME(write);
-ssize_t __readlink_real(const char*, char*, size_t) __RENAME(readlink);
-ssize_t __readlinkat_real(int dirfd, const char*, char*, size_t) __RENAME(readlinkat);
-
-__errordecl(__getcwd_dest_size_error, "getcwd called with size bigger than destination");
-__errordecl(__pread_dest_size_error, "pread called with size bigger than destination");
-__errordecl(__pread_count_toobig_error, "pread called with count > SSIZE_MAX");
-__errordecl(__pread64_dest_size_error, "pread64 called with size bigger than destination");
-__errordecl(__pread64_count_toobig_error, "pread64 called with count > SSIZE_MAX");
-__errordecl(__pwrite_dest_size_error, "pwrite called with size bigger than destination");
-__errordecl(__pwrite_count_toobig_error, "pwrite called with count > SSIZE_MAX");
-__errordecl(__pwrite64_dest_size_error, "pwrite64 called with size bigger than destination");
-__errordecl(__pwrite64_count_toobig_error, "pwrite64 called with count > SSIZE_MAX");
-__errordecl(__read_dest_size_error, "read called with size bigger than destination");
-__errordecl(__read_count_toobig_error, "read called with count > SSIZE_MAX");
-__errordecl(__write_dest_size_error, "write called with size bigger than destination");
-__errordecl(__write_count_toobig_error, "write called with count > SSIZE_MAX");
-__errordecl(__readlink_dest_size_error, "readlink called with size bigger than destination");
-__errordecl(__readlink_size_toobig_error, "readlink called with size > SSIZE_MAX");
-__errordecl(__readlinkat_dest_size_error, "readlinkat called with size bigger than destination");
-__errordecl(__readlinkat_size_toobig_error, "readlinkat called with size > SSIZE_MAX");
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-char* getcwd(char* buf, size_t size) __overloadable {
- size_t bos = __bos(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __getcwd_real(buf, size);
- }
-
- if (__builtin_constant_p(size) && (size > bos)) {
- __getcwd_dest_size_error();
- }
-
- if (__builtin_constant_p(size) && (size <= bos)) {
- return __getcwd_real(buf, size);
- }
-
- return __getcwd_chk(buf, size, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_FORTIFY_INLINE
-ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
- size_t bos = __bos0(buf);
-
- if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
- __PREAD_PREFIX(count_toobig_error)();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __PREAD_PREFIX(real)(fd, buf, count, offset);
- }
-
- if (__builtin_constant_p(count) && (count > bos)) {
- __PREAD_PREFIX(dest_size_error)();
- }
-
- if (__builtin_constant_p(count) && (count <= bos)) {
- return __PREAD_PREFIX(real)(fd, buf, count, offset);
- }
-
- return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) {
- size_t bos = __bos0(buf);
-
- if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
- __pread64_count_toobig_error();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __pread64_real(fd, buf, count, offset);
- }
-
- if (__builtin_constant_p(count) && (count > bos)) {
- __pread64_dest_size_error();
- }
-
- if (__builtin_constant_p(count) && (count <= bos)) {
- return __pread64_real(fd, buf, count, offset);
- }
-
- return __pread64_chk(fd, buf, count, offset, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) {
- size_t bos = __bos0(buf);
-
- if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
- __PWRITE_PREFIX(count_toobig_error)();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __PWRITE_PREFIX(real)(fd, buf, count, offset);
- }
-
- if (__builtin_constant_p(count) && (count > bos)) {
- __PWRITE_PREFIX(dest_size_error)();
- }
-
- if (__builtin_constant_p(count) && (count <= bos)) {
- return __PWRITE_PREFIX(real)(fd, buf, count, offset);
- }
-
- return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) {
- size_t bos = __bos0(buf);
-
- if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
- __pwrite64_count_toobig_error();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __pwrite64_real(fd, buf, count, offset);
- }
-
- if (__builtin_constant_p(count) && (count > bos)) {
- __pwrite64_dest_size_error();
- }
-
- if (__builtin_constant_p(count) && (count <= bos)) {
- return __pwrite64_real(fd, buf, count, offset);
- }
-
- return __pwrite64_chk(fd, buf, count, offset, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_L__
-__BIONIC_FORTIFY_INLINE
-ssize_t read(int fd, void* buf, size_t count) {
- size_t bos = __bos0(buf);
-
- if (__builtin_constant_p(count) && (count > SSIZE_MAX)) {
- __read_count_toobig_error();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __read_real(fd, buf, count);
- }
-
- if (__builtin_constant_p(count) && (count > bos)) {
- __read_dest_size_error();
- }
-
- if (__builtin_constant_p(count) && (count <= bos)) {
- return __read_real(fd, buf, count);
- }
-
- return __read_chk(fd, buf, count, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_N__
-__BIONIC_FORTIFY_INLINE
-ssize_t write(int fd, const void* buf, size_t count) {
- size_t bos = __bos0(buf);
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __write_real(fd, buf, count);
- }
-
- if (__builtin_constant_p(count) && (count > bos)) {
- __write_dest_size_error();
- }
-
- if (__builtin_constant_p(count) && (count <= bos)) {
- return __write_real(fd, buf, count);
- }
-
- return __write_chk(fd, buf, count, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
-
-#if __ANDROID_API__ >= __ANDROID_API_M__
-__BIONIC_FORTIFY_INLINE
-ssize_t readlink(const char* path, char* buf, size_t size) {
- size_t bos = __bos(buf);
-
- if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
- __readlink_size_toobig_error();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __readlink_real(path, buf, size);
- }
-
- if (__builtin_constant_p(size) && (size > bos)) {
- __readlink_dest_size_error();
- }
-
- if (__builtin_constant_p(size) && (size <= bos)) {
- return __readlink_real(path, buf, size);
- }
-
- return __readlink_chk(path, buf, size, bos);
-}
-
-__BIONIC_FORTIFY_INLINE
-ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size) {
- size_t bos = __bos(buf);
-
- if (__builtin_constant_p(size) && (size > SSIZE_MAX)) {
- __readlinkat_size_toobig_error();
- }
-
- if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
- return __readlinkat_real(dirfd, path, buf, size);
- }
-
- if (__builtin_constant_p(size) && (size > bos)) {
- __readlinkat_dest_size_error();
- }
-
- if (__builtin_constant_p(size) && (size <= bos)) {
- return __readlinkat_real(dirfd, path, buf, size);
- }
-
- return __readlinkat_chk(dirfd, path, buf, size, bos);
-}
-#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
-#endif /* defined(__clang__) */
-#undef __PREAD_PREFIX
-#undef __PWRITE_PREFIX
-#endif /* defined(__BIONIC_FORTIFY) */
-
__END_DECLS
#endif /* _UNISTD_H_ */