Merge "libc: Split FORTIFY into its own headers"

am: 1db06faa38

Change-Id: I387fb3d28c9d3f827f0e0011718e72efb0949db7
This commit is contained in:
George Burgess IV 2017-08-01 02:07:58 +00:00 committed by android-build-merger
commit f51724ab6b
21 changed files with 1975 additions and 1646 deletions

View file

@ -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: {

View 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) */

View 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) */

View 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 */

View 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) */

View 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) */

View 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) */

View 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) */

View 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) */

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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__)

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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_ */

View file

@ -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;

View file

@ -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);

View file

@ -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;
}