Merge "libc: Split FORTIFY into its own headers"
am: 1db06faa38
Change-Id: I387fb3d28c9d3f827f0e0011718e72efb0949db7
This commit is contained in:
commit
f51724ab6b
21 changed files with 1975 additions and 1646 deletions
|
@ -787,7 +787,7 @@ cc_library_static {
|
|||
|
||||
// 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: {
|
||||
|
|
145
libc/include/bits/fortify/fcntl.h
Normal file
145
libc/include/bits/fortify/fcntl.h
Normal file
|
@ -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) */
|
113
libc/include/bits/fortify/poll.h
Normal file
113
libc/include/bits/fortify/poll.h
Normal file
|
@ -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) */
|
166
libc/include/bits/fortify/socket.h
Normal file
166
libc/include/bits/fortify/socket.h
Normal file
|
@ -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 */
|
77
libc/include/bits/fortify/stat.h
Normal file
77
libc/include/bits/fortify/stat.h
Normal file
|
@ -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) */
|
291
libc/include/bits/fortify/stdio.h
Normal file
291
libc/include/bits/fortify/stdio.h
Normal file
|
@ -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) */
|
72
libc/include/bits/fortify/stdlib.h
Normal file
72
libc/include/bits/fortify/stdlib.h
Normal file
|
@ -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) */
|
481
libc/include/bits/fortify/string.h
Normal file
481
libc/include/bits/fortify/string.h
Normal file
|
@ -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) */
|
525
libc/include/bits/fortify/unistd.h
Normal file
525
libc/include/bits/fortify/unistd.h
Normal file
|
@ -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) */
|
|
@ -91,120 +91,9 @@ ssize_t readahead(int, off64_t, size_t) __INTRODUCED_IN(16);
|
|||
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
|
||||
|
||||
|
|
|
@ -42,87 +42,9 @@ int poll(struct pollfd*, nfds_t, int) __overloadable __RENAME_CLANG(poll);
|
|||
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
|
||||
|
||||
|
|
|
@ -271,265 +271,9 @@ int fileno_unlocked(FILE*) __INTRODUCED_IN(24);
|
|||
#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
|
||||
|
|
|
@ -165,46 +165,9 @@ size_t __ctype_get_mb_cur_max(void) __INTRODUCED_IN(21);
|
|||
#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);
|
||||
|
|
|
@ -149,455 +149,9 @@ char* basename(const char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23
|
|||
#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__)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -325,140 +325,9 @@ __socketcall ssize_t sendto(int, const void*, size_t, int, const struct sockaddr
|
|||
__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
|
||||
|
||||
|
|
|
@ -167,51 +167,9 @@ int stat64(const char*, struct stat64*) __INTRODUCED_IN(21);
|
|||
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);
|
||||
|
|
|
@ -242,505 +242,13 @@ int tcsetpgrp(int __fd, pid_t __pid);
|
|||
} 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_ */
|
||||
|
|
|
@ -37,7 +37,8 @@ std::string getWorkingDir() {
|
|||
return buf;
|
||||
}
|
||||
|
||||
std::vector<std::string> collectHeaders(const std::string& directory) {
|
||||
std::vector<std::string> collectHeaders(const std::string& directory,
|
||||
const std::unordered_set<std::string>& ignored_directories) {
|
||||
std::vector<std::string> headers;
|
||||
|
||||
char* dir_argv[2] = { const_cast<char*>(directory.c_str()), nullptr };
|
||||
|
@ -48,16 +49,34 @@ std::vector<std::string> collectHeaders(const std::string& directory) {
|
|||
err(1, "failed to open directory '%s'", directory.c_str());
|
||||
}
|
||||
|
||||
FTSENT* skipping = nullptr;
|
||||
while (FTSENT* ent = fts_read(fts.get())) {
|
||||
if (ent->fts_info & (FTS_D | FTS_DP)) {
|
||||
if (ent->fts_info & FTS_DP) {
|
||||
if (ent == skipping) {
|
||||
skipping = nullptr;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!android::base::EndsWith(ent->fts_path, ".h")) {
|
||||
if (skipping != nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
headers.push_back(ent->fts_path);
|
||||
if (ent->fts_info & FTS_D) {
|
||||
if (ignored_directories.count(ent->fts_path) != 0) {
|
||||
// fts_read guarantees that `ent` is valid and sane to hold on to until
|
||||
// after it's returned with FTS_DP set.
|
||||
skipping = ent;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string path = ent->fts_path;
|
||||
if (!android::base::EndsWith(path, ".h")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
headers.push_back(std::move(path));
|
||||
}
|
||||
|
||||
return headers;
|
||||
|
|
|
@ -22,12 +22,14 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include <llvm/ADT/StringRef.h>
|
||||
|
||||
std::string getWorkingDir();
|
||||
std::vector<std::string> collectHeaders(const std::string& directory);
|
||||
std::vector<std::string> collectHeaders(const std::string& directory,
|
||||
const std::unordered_set<std::string>& ignored_directories);
|
||||
|
||||
static inline std::string dirname(const std::string& path) {
|
||||
std::unique_ptr<char, decltype(&free)> path_copy(strdup(path.c_str()), free);
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <android-base/file.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <android-base/parseint.h>
|
||||
#include <android-base/strings.h>
|
||||
|
||||
#include "Arch.h"
|
||||
#include "DeclarationDatabase.h"
|
||||
|
@ -79,11 +80,21 @@ static int getCpuCount() {
|
|||
#endif
|
||||
}
|
||||
|
||||
static CompilationRequirements collectRequirements(const Arch& arch, const std::string& header_dir,
|
||||
const std::string& dependency_dir) {
|
||||
std::vector<std::string> headers = collectHeaders(header_dir);
|
||||
std::vector<std::string> dependencies = { header_dir };
|
||||
if (!dependency_dir.empty()) {
|
||||
namespace {
|
||||
struct HeaderLocationInformation {
|
||||
std::string header_dir;
|
||||
std::string dependency_dir;
|
||||
// Absolute paths to ignore all children -- including subdirectories -- of.
|
||||
std::unordered_set<std::string> ignored_directories;
|
||||
};
|
||||
}
|
||||
|
||||
static CompilationRequirements collectRequirements(const Arch& arch,
|
||||
const HeaderLocationInformation& location) {
|
||||
std::vector<std::string> headers =
|
||||
collectHeaders(location.header_dir, location.ignored_directories);
|
||||
std::vector<std::string> dependencies = { location.header_dir };
|
||||
if (!location.dependency_dir.empty()) {
|
||||
auto collect_children = [&dependencies](const std::string& dir_path) {
|
||||
DIR* dir = opendir(dir_path.c_str());
|
||||
if (!dir) {
|
||||
|
@ -114,8 +125,8 @@ static CompilationRequirements collectRequirements(const Arch& arch, const std::
|
|||
closedir(dir);
|
||||
};
|
||||
|
||||
collect_children(dependency_dir + "/common");
|
||||
collect_children(dependency_dir + "/" + to_string(arch));
|
||||
collect_children(location.dependency_dir + "/common");
|
||||
collect_children(location.dependency_dir + "/" + to_string(arch));
|
||||
}
|
||||
|
||||
auto new_end = std::remove_if(headers.begin(), headers.end(), [&arch](llvm::StringRef header) {
|
||||
|
@ -159,13 +170,12 @@ static std::set<CompilationType> generateCompilationTypes(const std::set<Arch> s
|
|||
}
|
||||
|
||||
static std::unique_ptr<HeaderDatabase> compileHeaders(const std::set<CompilationType>& types,
|
||||
const std::string& header_dir,
|
||||
const std::string& dependency_dir) {
|
||||
const HeaderLocationInformation& location) {
|
||||
if (types.empty()) {
|
||||
errx(1, "compileHeaders received no CompilationTypes");
|
||||
}
|
||||
|
||||
auto vfs = createCommonVFS(header_dir, dependency_dir, add_include);
|
||||
auto vfs = createCommonVFS(location.header_dir, location.dependency_dir, add_include);
|
||||
|
||||
size_t thread_count = max_thread_count;
|
||||
std::vector<std::thread> threads;
|
||||
|
@ -176,7 +186,7 @@ static std::unique_ptr<HeaderDatabase> compileHeaders(const std::set<Compilation
|
|||
auto result = std::make_unique<HeaderDatabase>();
|
||||
for (const auto& type : types) {
|
||||
if (requirements.count(type.arch) == 0) {
|
||||
requirements[type.arch] = collectRequirements(type.arch, header_dir, dependency_dir);
|
||||
requirements[type.arch] = collectRequirements(type.arch, location);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -454,6 +464,7 @@ static void usage(bool help = false) {
|
|||
fprintf(stderr, " -f\t\tpreprocess header files even if validation fails\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Miscellaneous:\n");
|
||||
fprintf(stderr, " -F\t\tdo not ignore FORTIFY headers by default\n");
|
||||
fprintf(stderr, " -d\t\tdump function availability\n");
|
||||
fprintf(stderr, " -j THREADS\tmaximum number of threads to use\n");
|
||||
fprintf(stderr, " -v\t\tenable verbose logging\n");
|
||||
|
@ -477,9 +488,10 @@ int main(int argc, char** argv) {
|
|||
std::string preprocessor_output_path;
|
||||
bool force = false;
|
||||
bool dump = false;
|
||||
bool ignore_fortify_headers = true;
|
||||
|
||||
int c;
|
||||
while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhi")) != -1) {
|
||||
while ((c = getopt(argc, argv, "a:r:p:so:fdj:vhFi")) != -1) {
|
||||
default_args = false;
|
||||
switch (c) {
|
||||
case 'a': {
|
||||
|
@ -565,6 +577,10 @@ int main(int argc, char** argv) {
|
|||
add_include = true;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
ignore_fortify_headers = false;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
break;
|
||||
|
@ -575,8 +591,7 @@ int main(int argc, char** argv) {
|
|||
usage();
|
||||
}
|
||||
|
||||
std::string header_dir;
|
||||
std::string dependency_dir;
|
||||
HeaderLocationInformation location;
|
||||
|
||||
const char* top = getenv("ANDROID_BUILD_TOP");
|
||||
if (!top && (optind == argc || add_include)) {
|
||||
|
@ -587,21 +602,32 @@ int main(int argc, char** argv) {
|
|||
if (optind == argc) {
|
||||
// Neither HEADER_PATH nor DEPS_PATH were specified, so try to figure them out.
|
||||
std::string versioner_dir = to_string(top) + "/bionic/tools/versioner";
|
||||
header_dir = versioner_dir + "/current";
|
||||
dependency_dir = versioner_dir + "/dependencies";
|
||||
location.header_dir = versioner_dir + "/current";
|
||||
location.dependency_dir = versioner_dir + "/dependencies";
|
||||
if (platform_dir.empty()) {
|
||||
platform_dir = versioner_dir + "/platforms";
|
||||
}
|
||||
} else {
|
||||
if (!android::base::Realpath(argv[optind], &header_dir)) {
|
||||
if (!android::base::Realpath(argv[optind], &location.header_dir)) {
|
||||
err(1, "failed to get realpath for path '%s'", argv[optind]);
|
||||
}
|
||||
|
||||
if (argc - optind == 2) {
|
||||
dependency_dir = argv[optind + 1];
|
||||
location.dependency_dir = argv[optind + 1];
|
||||
}
|
||||
}
|
||||
|
||||
// Every file that lives in bits/fortify is logically a part of a header outside of bits/fortify.
|
||||
// This makes the files there impossible to build on their own.
|
||||
if (ignore_fortify_headers) {
|
||||
std::string fortify_path = location.header_dir;
|
||||
if (!android::base::EndsWith(location.header_dir, "/")) {
|
||||
fortify_path += '/';
|
||||
}
|
||||
fortify_path += "bits/fortify";
|
||||
location.ignored_directories.insert(std::move(fortify_path));
|
||||
}
|
||||
|
||||
if (selected_levels.empty()) {
|
||||
selected_levels = supported_levels;
|
||||
}
|
||||
|
@ -612,10 +638,10 @@ int main(int argc, char** argv) {
|
|||
|
||||
|
||||
struct stat st;
|
||||
if (stat(header_dir.c_str(), &st) != 0) {
|
||||
err(1, "failed to stat '%s'", header_dir.c_str());
|
||||
if (const char *dir = location.header_dir.c_str(); stat(dir, &st) != 0) {
|
||||
err(1, "failed to stat '%s'", dir);
|
||||
} else if (!S_ISDIR(st.st_mode)) {
|
||||
errx(1, "'%s' is not a directory", header_dir.c_str());
|
||||
errx(1, "'%s' is not a directory", dir);
|
||||
}
|
||||
|
||||
std::set<CompilationType> compilation_types;
|
||||
|
@ -631,7 +657,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
std::unique_ptr<HeaderDatabase> declaration_database =
|
||||
compileHeaders(compilation_types, header_dir, dependency_dir);
|
||||
compileHeaders(compilation_types, location);
|
||||
auto end = std::chrono::high_resolution_clock::now();
|
||||
|
||||
if (verbose) {
|
||||
|
@ -641,7 +667,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
bool failed = false;
|
||||
if (dump) {
|
||||
declaration_database->dump(header_dir + "/");
|
||||
declaration_database->dump(location.header_dir + "/");
|
||||
} else {
|
||||
if (!sanityCheck(declaration_database.get())) {
|
||||
printf("versioner: sanity check failed\n");
|
||||
|
@ -657,7 +683,7 @@ int main(int argc, char** argv) {
|
|||
}
|
||||
|
||||
if (!preprocessor_output_path.empty() && (force || !failed)) {
|
||||
failed = !preprocessHeaders(preprocessor_output_path, header_dir, declaration_database.get());
|
||||
failed = !preprocessHeaders(preprocessor_output_path, location.header_dir, declaration_database.get());
|
||||
}
|
||||
return failed;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue