diff options
author | Dan Albert <danalbert@google.com> | 2017-02-24 19:54:43 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-02-24 19:54:43 +0000 |
commit | 2807fa99bd2e2268897e10d39a261edda89652a3 (patch) | |
tree | 5f533e696c7aaaf5c2613a1f1794fd0edfd85640 | |
parent | b63cf0b45a786e48ef41a0ee0ff9bd9095069078 (diff) | |
parent | 4d230e6e5a0557c065e548f1730ad65bb5155699 (diff) | |
download | ndk-2807fa99bd2e2268897e10d39a261edda89652a3.tar.gz |
Merge "Update bionic headers to 9dbfd8ad7." am: d89dea2f0d
am: 4d230e6e5a
Change-Id: Ie87a0913958a79804fe361ecd640beb8d6c8b5d1
-rw-r--r-- | NOTICE | 44 | ||||
-rw-r--r-- | headers/android/legacy_termios_inlines.h | 12 | ||||
-rw-r--r-- | headers/fcntl.h | 81 | ||||
-rw-r--r-- | headers/malloc.h | 7 | ||||
-rw-r--r-- | headers/poll.h | 77 | ||||
-rw-r--r-- | headers/stdio.h | 233 | ||||
-rw-r--r-- | headers/stdlib.h | 35 | ||||
-rw-r--r-- | headers/string.h | 405 | ||||
-rw-r--r-- | headers/sys/_system_properties.h | 31 | ||||
-rw-r--r-- | headers/sys/cdefs.h | 90 | ||||
-rw-r--r-- | headers/sys/socket.h | 128 | ||||
-rw-r--r-- | headers/sys/stat.h | 33 | ||||
-rw-r--r-- | headers/sys/system_properties.h | 89 | ||||
-rw-r--r-- | headers/termios.h | 9 | ||||
-rw-r--r-- | headers/unistd.h | 371 |
15 files changed, 1235 insertions, 410 deletions
@@ -382,6 +382,34 @@ limitations under the License. ------------------------------------------------------------------- +Copyright (C) 2007 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. + +------------------------------------------------------------------- + Copyright (C) 2008 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); @@ -933,22 +961,6 @@ SUCH DAMAGE. ------------------------------------------------------------------- Copyright (C) 2017 The Android Open Source Project - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. - -------------------------------------------------------------------- - -Copyright (C) 2017 The Android Open Source Project All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/headers/android/legacy_termios_inlines.h b/headers/android/legacy_termios_inlines.h index 4424bdb0b..02e942920 100644 --- a/headers/android/legacy_termios_inlines.h +++ b/headers/android/legacy_termios_inlines.h @@ -91,6 +91,18 @@ static __inline void cfmakeraw(struct termios *s) { s->c_cflag |= CS8; } +static __inline int cfsetspeed(struct termios* s, speed_t speed) { + // TODO: check 'speed' is valid. + s->c_cflag = (s->c_cflag & ~CBAUD) | (speed & CBAUD); + return 0; +} + +static __inline int tcdrain(int fd) { + // A non-zero argument to TCSBRK means "don't send a break". + // The drain is a side-effect of the ioctl! + return ioctl(fd, TCSBRK, __BIONIC_CAST(static_cast, unsigned long, 1)); +} + __END_DECLS #endif diff --git a/headers/fcntl.h b/headers/fcntl.h index 9efed0503..86e9a082e 100644 --- a/headers/fcntl.h +++ b/headers/fcntl.h @@ -71,13 +71,14 @@ int creat(const char*, mode_t); int creat64(const char*, mode_t) __INTRODUCED_IN(21); #endif /* __ANDROID_API__ >= 21 */ -int openat(int, const char*, int, ...); +int openat(int, const char*, int, ...) __overloadable + __RENAME_CLANG(openat); #if __ANDROID_API__ >= 21 int openat64(int, const char*, int, ...) __INTRODUCED_IN(21); #endif /* __ANDROID_API__ >= 21 */ -int open(const char*, int, ...); +int open(const char*, int, ...) __overloadable __RENAME_CLANG(open); #if __ANDROID_API__ >= 21 int open64(const char*, int, ...) __INTRODUCED_IN(21); @@ -128,22 +129,77 @@ int sync_file_range(int, off64_t, off64_t, unsigned int) __INTRODUCED_IN_FUTURE; #if __ANDROID_API__ >= 17 int __open_2(const char*, int) __INTRODUCED_IN(17); -#endif /* __ANDROID_API__ >= 17 */ - -int __open_real(const char*, int, ...) __RENAME(open); - -#if __ANDROID_API__ >= 17 int __openat_2(int, const char*, int) __INTRODUCED_IN(17); #endif /* __ANDROID_API__ >= 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); -__errordecl(__creat_missing_mode, "called with O_CREAT, but missing mode"); -__errordecl(__creat_too_many_args, "too many arguments"); + #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__ */ -#if !defined(__clang__) +#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)) { @@ -181,9 +237,12 @@ int openat(int dirfd, const char* pathname, int flags, ...) { return __openat_real(dirfd, pathname, flags, __builtin_va_arg_pack()); } +#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ -#endif /* !defined(__clang__) */ +#endif /* defined(__clang__) */ +#undef __open_too_many_args_error +#undef __open_too_few_args_error #endif /* defined(__BIONIC_FORTIFY) */ __END_DECLS diff --git a/headers/malloc.h b/headers/malloc.h index 12c7011fd..4cef300eb 100644 --- a/headers/malloc.h +++ b/headers/malloc.h @@ -24,7 +24,12 @@ __BEGIN_DECLS #if defined(__clang__) -#define __BIONIC_ALLOC_SIZE(...) /* clang doesn't support attribute alloc_size. */ +/* clang should support alloc_size in the nearish future. */ +#if __has_attribute(alloc_size) +#error "We should enable alloc_size for clang." +#else +#define __BIONIC_ALLOC_SIZE(...) +#endif #else #define __BIONIC_ALLOC_SIZE(...) __attribute__((__alloc_size__(__VA_ARGS__))) #endif diff --git a/headers/poll.h b/headers/poll.h index 88698469e..a8895c313 100644 --- a/headers/poll.h +++ b/headers/poll.h @@ -38,43 +38,73 @@ __BEGIN_DECLS typedef unsigned int nfds_t; -int poll(struct pollfd*, nfds_t, int); +int poll(struct pollfd*, nfds_t, int) __overloadable __RENAME_CLANG(poll); #if __ANDROID_API__ >= 21 -int ppoll(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*) __INTRODUCED_IN(21); +int ppoll(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*) + __overloadable __RENAME_CLANG(ppoll) __INTRODUCED_IN(21); #endif /* __ANDROID_API__ >= 21 */ #if __ANDROID_API__ >= 23 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); #endif /* __ANDROID_API__ >= 23 */ -int __poll_real(struct pollfd*, nfds_t, int) __RENAME(poll); -__errordecl(__poll_too_small_error, "poll: pollfd array smaller than fd count"); +#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"); -#if __ANDROID_API__ >= 23 -int __ppoll_chk(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*, size_t) - __INTRODUCED_IN(23); -#endif /* __ANDROID_API__ >= 23 */ +__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"); -#if __ANDROID_API__ >= 21 int __ppoll_real(struct pollfd*, nfds_t, const struct timespec*, const sigset_t*) __RENAME(ppoll) __INTRODUCED_IN(21); -#endif /* __ANDROID_API__ >= 21 */ - __errordecl(__ppoll_too_small_error, "ppoll: pollfd array smaller than fd count"); -#if defined(__BIONIC_FORTIFY) - -#if __ANDROID_API__ >= __ANDROID_API_M__ __BIONIC_FORTIFY_INLINE int poll(struct pollfd* fds, nfds_t fd_count, int timeout) { -#if defined(__clang__) - return __poll_chk(fds, fd_count, timeout, __bos(fds)); -#else if (__bos(fds) != __BIONIC_FORTIFY_UNKNOWN_SIZE) { if (!__builtin_constant_p(fd_count)) { return __poll_chk(fds, fd_count, timeout, __bos(fds)); @@ -83,14 +113,11 @@ int poll(struct pollfd* fds, nfds_t fd_count, int timeout) { } } return __poll_real(fds, fd_count, timeout); -#endif } __BIONIC_FORTIFY_INLINE -int ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout, const sigset_t* mask) { -#if defined(__clang__) - return __ppoll_chk(fds, fd_count, timeout, mask, __bos(fds)); -#else +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)); @@ -99,11 +126,11 @@ int ppoll(struct pollfd* fds, nfds_t fd_count, const struct timespec* timeout, c } } return __ppoll_real(fds, fd_count, timeout, mask); -#endif } -#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */ -#endif +#endif /* defined(__clang__) */ +#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */ +#endif /* defined(__BIONIC_FORTIFY) */ __END_DECLS diff --git a/headers/stdio.h b/headers/stdio.h index 70b89a996..c9976aa03 100644 --- a/headers/stdio.h +++ b/headers/stdio.h @@ -121,13 +121,16 @@ int feof(FILE *); int ferror(FILE *); int fflush(FILE *); int fgetc(FILE *); -char *fgets(char * __restrict, int, FILE * __restrict); +char *fgets(char * __restrict, int, FILE * __restrict) __overloadable + __RENAME_CLANG(fgets); int fprintf(FILE * __restrict , const char * __restrict _Nonnull, ...) __printflike(2, 3); int fputc(int, FILE *); int fputs(const char * __restrict, FILE * __restrict); -size_t fread(void * __restrict, size_t, size_t, FILE * __restrict); +size_t fread(void * __restrict, size_t, size_t, FILE * __restrict) + __overloadable __RENAME_CLANG(fread); int fscanf(FILE * __restrict, const char * __restrict _Nonnull, ...) __scanflike(2, 3); -size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict); +size_t fwrite(const void * __restrict, size_t, size_t, FILE * __restrict) + __overloadable __RENAME_CLANG(fwrite); int getc(FILE *); int getchar(void); @@ -163,12 +166,17 @@ int vdprintf(int, const char* __restrict _Nonnull, __va_list) __printflike(2, 0) (defined(__cplusplus) && __cplusplus <= 201103L) char* gets(char*) __attribute__((deprecated("gets is unsafe, use fgets instead"))); #endif -int sprintf(char* __restrict, const char* __restrict _Nonnull, ...) __printflike(2, 3); -int vsprintf(char* __restrict, const char* __restrict _Nonnull, __va_list) __printflike(2, 0); -char* tmpnam(char*) __attribute__((deprecated("tmpnam is unsafe, use mkstemp or tmpfile instead"))); +int sprintf(char* __restrict, const char* __restrict _Nonnull, ...) + __printflike(2, 3) __warnattr_strict("sprintf is often misused; please use snprintf") + __overloadable __RENAME_CLANG(sprintf); +int vsprintf(char* __restrict, const char* __restrict _Nonnull, __va_list) + __overloadable __printflike(2, 0) __RENAME_CLANG(vsprintf) + __warnattr_strict("vsprintf is often misused; please use vsnprintf"); +char* tmpnam(char*) + __warnattr("tempnam is unsafe, use mkstemp or tmpfile instead"); #define P_tmpdir "/tmp/" /* deprecated */ char* tempnam(const char*, const char*) - __attribute__((deprecated("tempnam is unsafe, use mkstemp or tmpfile instead"))); + __warnattr("tempnam is unsafe, use mkstemp or tmpfile instead"); int rename(const char*, const char*); int renameat(int, const char*, int, const char*); @@ -238,10 +246,12 @@ FILE* tmpfile64(void) __INTRODUCED_IN(24); #endif /* __ANDROID_API__ >= 24 */ -int snprintf(char* __restrict, size_t, const char* __restrict _Nonnull, ...) __printflike(3, 4); +int snprintf(char* __restrict, size_t, const char* __restrict _Nonnull, ...) + __printflike(3, 4) __overloadable __RENAME_CLANG(snprintf); int vfscanf(FILE* __restrict, const char* __restrict _Nonnull, __va_list) __scanflike(2, 0); int vscanf(const char* _Nonnull , __va_list) __scanflike(1, 0); -int vsnprintf(char* __restrict, size_t, const char* __restrict _Nonnull, __va_list) __printflike(3, 0); +int vsnprintf(char* __restrict, size_t, const char* __restrict _Nonnull, __va_list) + __printflike(3, 0) __overloadable __RENAME_CLANG(vsnprintf); int vsscanf(const char* __restrict _Nonnull, const char* __restrict _Nonnull, __va_list) __scanflike(2, 0); #define L_ctermid 1024 /* size for ctermid() */ @@ -298,74 +308,189 @@ int fileno_unlocked(FILE*) __INTRODUCED_IN(24); char* __fgets_chk(char*, int, FILE*, size_t) __INTRODUCED_IN(17); #endif /* __ANDROID_API__ >= 17 */ -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"); - #if __ANDROID_API__ >= 24 size_t __fread_chk(void* __restrict, size_t, size_t, FILE* __restrict, size_t) - __INTRODUCED_IN(24); -#endif /* __ANDROID_API__ >= 24 */ - -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"); - - -#if __ANDROID_API__ >= 24 + __INTRODUCED_IN(24); size_t __fwrite_chk(const void* __restrict, size_t, size_t, FILE* __restrict, size_t) - __INTRODUCED_IN(24); + __INTRODUCED_IN(24); #endif /* __ANDROID_API__ >= 24 */ -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 defined(__BIONIC_FORTIFY) && !defined(__BIONIC_NO_STDIO_FORTIFY) #if __ANDROID_API__ >= __ANDROID_API_J_MR1__ -__BIONIC_FORTIFY_INLINE -__printflike(3, 0) int vsnprintf(char* dest, size_t size, const char* _Nonnull format, __va_list ap) { +__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* dest, const char* _Nonnull format, __va_list 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 !defined(snprintf) - #define __wrap_snprintf(dest, size, ...) __builtin___snprintf_chk(dest, size, 0, __bos(dest), __VA_ARGS__) - #define snprintf(...) __wrap_snprintf(__VA_ARGS__) - #endif -#else +#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* dest, size_t size, const char* _Nonnull format, ...) { - return __builtin___snprintf_chk(dest, size, 0, __bos(dest), format, __builtin_va_arg_pack()); +__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; } -#endif -#if defined(__clang__) - #if !defined(sprintf) - #define __wrap_sprintf(dest, ...) __builtin___sprintf_chk(dest, 0, __bos(dest), __VA_ARGS__) - #define sprintf(...) __wrap_sprintf(__VA_ARGS__) - #endif -#else +__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* dest, const char* _Nonnull format, ...) { - return __builtin___sprintf_chk(dest, 0, __bos(dest), format, __builtin_va_arg_pack()); +__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 #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 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 !defined(__clang__) if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { return __fread_real(buf, size, count, stream); } @@ -382,7 +507,6 @@ size_t fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict return __fread_real(buf, size, count, stream); } -#endif return __fread_chk(buf, size, count, stream, bos); } @@ -391,7 +515,6 @@ __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 !defined(__clang__) if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { return __fwrite_real(buf, size, count, stream); } @@ -408,14 +531,12 @@ size_t fwrite(const void * __restrict buf, size_t size, size_t count, FILE * __r return __fwrite_real(buf, size, count, stream); } -#endif return __fwrite_chk(buf, size, count, stream, bos); } #endif /* __ANDROID_API__ >= __ANDROID_API_N__ */ -#if !defined(__clang__) - +#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ __BIONIC_FORTIFY_INLINE char *fgets(char* dest, int size, FILE* stream) { size_t bos = __bos(dest); @@ -445,9 +566,9 @@ char *fgets(char* dest, int size, FILE* stream) { return __fgets_chk(dest, size, stream, bos); } +#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ -#endif /* !defined(__clang__) */ - +#endif /* defined(__clang__) */ #endif /* defined(__BIONIC_FORTIFY) */ #if defined(__clang__) diff --git a/headers/stdlib.h b/headers/stdlib.h index 8f444093d..d16bb2c18 100644 --- a/headers/stdlib.h +++ b/headers/stdlib.h @@ -115,8 +115,9 @@ int atoi(const char*) __attribute_pure__; long atol(const char*) __attribute_pure__; long long atoll(const char*) __attribute_pure__; -char* realpath(const char* path, char* resolved); -int system(const char* string); +char * realpath(const char *path, char *resolved) __overloadable + __RENAME_CLANG(realpath); +int system(const char *string); void* bsearch(const void* key, const void* base0, size_t nmemb, size_t size, int (*compar)(const void*, const void*)); @@ -220,24 +221,44 @@ size_t __ctype_get_mb_cur_max(void) __INTRODUCED_IN(21); #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 output parameter must be NULL or a >= PATH_MAX bytes buffer"); +__errordecl(__realpath_size_error, __realpath_buf_too_small_str); -#if !defined(__clang__) __BIONIC_FORTIFY_INLINE char* realpath(const char* path, char* resolved) { size_t bos = __bos(resolved); - /* PATH_MAX is unavailable without polluting the namespace, but it's always 4096 on Linux */ - if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < 4096) { + if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE && bos < __PATH_MAX) { __realpath_size_error(); } return __realpath_real(path, resolved); } -#endif +#endif /* defined(__clang__) */ + +#undef __PATH_MAX +#undef __realpath_buf_too_small_str #endif /* defined(__BIONIC_FORTIFY) */ #if __ANDROID_API__ >= __ANDROID_API_L__ diff --git a/headers/string.h b/headers/string.h index 0b957d2b9..08f67227f 100644 --- a/headers/string.h +++ b/headers/string.h @@ -47,10 +47,13 @@ __BEGIN_DECLS #endif void* memccpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, int, size_t); -void* memchr(const void* _Nonnull, int, size_t) __attribute_pure__; -void* memrchr(const void* _Nonnull, int, size_t) __attribute_pure__; +void* memchr(const void* _Nonnull, int, size_t) __attribute_pure__ __overloadable + __RENAME_CLANG(memchr); +void* memrchr(const void* _Nonnull, int, size_t) __attribute_pure__ __overloadable + __RENAME_CLANG(memrchr); int memcmp(const void* _Nonnull, const void* _Nonnull, size_t) __attribute_pure__; -void* memcpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, size_t); +void* memcpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, size_t) + __overloadable __RENAME_CLANG(memcpy); #if defined(__USE_GNU) #if __ANDROID_API__ >= 23 @@ -58,11 +61,13 @@ void* mempcpy(void* _Nonnull __restrict, const void* _Nonnull __restrict, size_t #endif /* __ANDROID_API__ >= 23 */ #endif -void* memmove(void* _Nonnull, const void* _Nonnull, size_t); -void* memset(void* _Nonnull, int, size_t); +void* memmove(void* _Nonnull, const void* _Nonnull, size_t) __overloadable + __RENAME_CLANG(memmove); +void* memset(void* _Nonnull, int, size_t) __overloadable __RENAME_CLANG(memset); void* memmem(const void* _Nonnull, size_t, const void* _Nonnull, size_t) __attribute_pure__; -char* strchr(const char* _Nonnull, int) __attribute_pure__; +char* strchr(const char* _Nonnull, int) __attribute_pure__ __overloadable + __RENAME_CLANG(strchr); #if __ANDROID_API__ >= 18 char* __strchr_chk(const char* _Nonnull, int, size_t) __INTRODUCED_IN(18); @@ -81,28 +86,33 @@ char* strchrnul(const char* _Nonnull, int) __attribute_pure__ __INTRODUCED_IN(24 #endif #endif -char* strrchr(const char* _Nonnull, int) __attribute_pure__; +char* strrchr(const char* _Nonnull, int) __attribute_pure__ __overloadable + __RENAME_CLANG(strrchr); #if __ANDROID_API__ >= 18 char* __strrchr_chk(const char* _Nonnull, int, size_t) __INTRODUCED_IN(18); #endif /* __ANDROID_API__ >= 18 */ -size_t strlen(const char* _Nonnull) __attribute_pure__; +size_t strlen(const char* _Nonnull) __attribute_pure__ __overloadable + __RENAME_CLANG(strlen); #if __ANDROID_API__ >= 17 size_t __strlen_chk(const char* _Nonnull, size_t) __INTRODUCED_IN(17); #endif /* __ANDROID_API__ >= 17 */ + int strcmp(const char* _Nonnull, const char* _Nonnull) __attribute_pure__; #if __ANDROID_API__ >= 21 -char* stpcpy(char* _Nonnull __restrict, const char* _Nonnull__restrict) __INTRODUCED_IN(21); +char* stpcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict) + __overloadable __RENAME_CLANG(stpcpy) __INTRODUCED_IN(21); #endif /* __ANDROID_API__ >= 21 */ -char* strcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict); -char* strcat(char* _Nonnull __restrict, const char* _Nonnull __restrict); - +char* strcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict) + __overloadable __RENAME_CLANG(strcpy); +char* strcat(char* _Nonnull __restrict, const char* _Nonnull __restrict) + __overloadable __RENAME_CLANG(strcat); char* strdup(const char* _Nonnull); char* strstr(const char* _Nonnull, const char* _Nonnull) __attribute_pure__; @@ -116,29 +126,30 @@ char* strerror(int); char* strerror_l(int, locale_t) __INTRODUCED_IN(23); #endif /* __ANDROID_API__ >= 23 */ -#if defined(__USE_GNU) - -#if __ANDROID_API__ >= 23 +#if defined(__USE_GNU) && __ANDROID_API__ >= 23 char* strerror_r(int, char*, size_t) __RENAME(__gnu_strerror_r) __INTRODUCED_IN(23); -#endif /* __ANDROID_API__ >= 23 */ - #else /* POSIX */ int strerror_r(int, char*, size_t); #endif size_t strnlen(const char* _Nonnull, size_t) __attribute_pure__; -char* strncat(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t); +char* strncat(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t) + __overloadable __RENAME_CLANG(strncat); char* strndup(const char* _Nonnull, size_t); int strncmp(const char* _Nonnull, const char* _Nonnull, size_t) __attribute_pure__; #if __ANDROID_API__ >= 21 -char* stpncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t) __INTRODUCED_IN(21); +char* stpncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t) + __overloadable __RENAME_CLANG(stpncpy) __INTRODUCED_IN(21); #endif /* __ANDROID_API__ >= 21 */ -char* strncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t); +char* strncpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t) + __overloadable __RENAME_CLANG(strncpy); -size_t strlcat(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t); -size_t strlcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t); +size_t strlcat(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t) + __overloadable __RENAME_CLANG(strlcat); +size_t strlcpy(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t) + __overloadable __RENAME_CLANG(strlcpy); size_t strcspn(const char* _Nonnull, const char* _Nonnull) __attribute_pure__; char* strpbrk(const char* _Nonnull, const char* _Nonnull) __attribute_pure__; @@ -177,18 +188,9 @@ char* basename(const char* _Nonnull) __RENAME(__gnu_basename) __INTRODUCED_IN(23 #if __ANDROID_API__ >= 23 void* __memchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23); -#endif /* __ANDROID_API__ >= 23 */ - -__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer"); - - -#if __ANDROID_API__ >= 23 void* __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23); #endif /* __ANDROID_API__ >= 23 */ -__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer"); -void* __memrchr_real(const void* _Nonnull, int, size_t) __RENAME(memrchr); - #if __ANDROID_API__ >= 21 char* __stpncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t) @@ -197,91 +199,323 @@ char* __strncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, __INTRODUCED_IN(21); #endif /* __ANDROID_API__ >= 21 */ -size_t __strlcpy_real(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t) __RENAME(strlcpy); #if __ANDROID_API__ >= 17 size_t __strlcpy_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17); -#endif /* __ANDROID_API__ >= 17 */ - -size_t __strlcat_real(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t) __RENAME(strlcat); - -#if __ANDROID_API__ >= 17 size_t __strlcat_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17); #endif /* __ANDROID_API__ >= 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* s, int c, size_t n) { +void* memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n) + __overloadable { size_t bos = __bos(s); -#if !defined(__clang__) 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); - } -#endif - return __memchr_chk(s, c, n, bos); } __BIONIC_FORTIFY_INLINE -void* memrchr(const void* s, int c, size_t n) { +void* memrchr(const void* const _Nonnull s __pass_object_size, int c, size_t n) + __overloadable { size_t bos = __bos(s); -#if !defined(__clang__) if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { - return __memrchr_real(s, c, n); + return __call_bypassing_fortify(memrchr)(s, c, n); } - if (__builtin_constant_p(n) && (n > bos)) { - __memrchr_buf_size_error(); + 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); } - if (__builtin_constant_p(n) && (n <= bos)) { - return __memrchr_real(s, c, n); + 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); } -#endif - return __memrchr_chk(s, c, n, bos); + return __strncpy_chk2(dst, src, n, bos_dst, bos_src); } -#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */ +#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */ #if __ANDROID_API__ >= __ANDROID_API_J_MR1__ __BIONIC_FORTIFY_INLINE -void* memcpy(void* _Nonnull __restrict dst, const void* _Nonnull __restrict src, size_t copy_amount) { - return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst)); +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 -void* memmove(void* _Nonnull dst, const void* _Nonnull src, size_t len) { - return __builtin___memmove_chk(dst, src, len, __bos0(dst)); +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_L__ +#if __ANDROID_API__ >= __ANDROID_API_J_MR2__ __BIONIC_FORTIFY_INLINE -char* stpcpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src) { - return __builtin___stpcpy_chk(dst, src, __bos(dst)); +char* strchr(const char* const _Nonnull s __pass_object_size0, int c) + __overloadable { + size_t bos = __bos0(s); + + if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { + return __builtin_strchr(s, c); + } + + // return __builtin_strchr(s, c); + return __strchr_chk(s, c, bos); } -#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */ + +__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 -char* strcpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src) { - return __builtin___strcpy_chk(dst, src, __bos(dst)); +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(strcpy); +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) { @@ -310,7 +544,7 @@ char* strncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src size_t bos_src = __bos(src); if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { - return __builtin___strncpy_chk(dst, src, n, bos_dst); + return __strncpy_real(dst, src, n); } if (__builtin_constant_p(n) && (n <= bos_src)) { @@ -328,25 +562,10 @@ char* strncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src #if __ANDROID_API__ >= __ANDROID_API_J_MR1__ __BIONIC_FORTIFY_INLINE -char* strcat(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src) { - return __builtin___strcat_chk(dst, src, __bos(dst)); -} - -__BIONIC_FORTIFY_INLINE -char *strncat(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) { - return __builtin___strncat_chk(dst, src, n, __bos(dst)); -} - -__BIONIC_FORTIFY_INLINE -void* memset(void* _Nonnull s, int c, size_t n) { - return __builtin___memset_chk(s, c, n, __bos0(s)); -} - -__BIONIC_FORTIFY_INLINE -size_t strlcpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t size) { +size_t strlcpy(char* _Nonnull __restrict dst __pass_object_size, + const char* _Nonnull __restrict src, size_t size) { size_t bos = __bos(dst); -#if !defined(__clang__) // Compiler doesn't know destination size. Don't call __strlcpy_chk if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { return __strlcpy_real(dst, src, size); @@ -357,17 +576,14 @@ size_t strlcpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict sr if (__builtin_constant_p(size) && (size <= bos)) { return __strlcpy_real(dst, src, size); } -#endif /* !defined(__clang__) */ 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); -#if !defined(__clang__) // Compiler doesn't know destination size. Don't call __strlcat_chk if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { return __strlcat_real(dst, src, size); @@ -378,16 +594,14 @@ size_t strlcat(char* _Nonnull __restrict dst, const char* _Nonnull __restrict sr if (__builtin_constant_p(size) && (size <= bos)) { return __strlcat_real(dst, src, size); } -#endif /* !defined(__clang__) */ return __strlcat_chk(dst, src, size, bos); } __BIONIC_FORTIFY_INLINE -size_t strlen(const char* _Nonnull s) { +size_t strlen(const char* _Nonnull s) __overloadable { size_t bos = __bos(s); -#if !defined(__clang__) // Compiler doesn't know destination size. Don't call __strlen_chk if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { return __builtin_strlen(s); @@ -397,7 +611,6 @@ size_t strlen(const char* _Nonnull s) { if (__builtin_constant_p(slen)) { return slen; } -#endif /* !defined(__clang__) */ return __strlen_chk(s, bos); } @@ -408,7 +621,6 @@ __BIONIC_FORTIFY_INLINE char* strchr(const char* _Nonnull s, int c) { size_t bos = __bos(s); -#if !defined(__clang__) // Compiler doesn't know destination size. Don't call __strchr_chk if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { return __builtin_strchr(s, c); @@ -418,7 +630,6 @@ char* strchr(const char* _Nonnull s, int c) { if (__builtin_constant_p(slen) && (slen < bos)) { return __builtin_strchr(s, c); } -#endif /* !defined(__clang__) */ return __strchr_chk(s, c, bos); } @@ -427,7 +638,6 @@ __BIONIC_FORTIFY_INLINE char* strrchr(const char* _Nonnull s, int c) { size_t bos = __bos(s); -#if !defined(__clang__) // Compiler doesn't know destination size. Don't call __strrchr_chk if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { return __builtin_strrchr(s, c); @@ -437,12 +647,11 @@ char* strrchr(const char* _Nonnull s, int c) { if (__builtin_constant_p(slen) && (slen < bos)) { return __builtin_strrchr(s, c); } -#endif /* !defined(__clang__) */ return __strrchr_chk(s, c, bos); } #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */ - +#endif /* defined(__clang__) */ #endif /* defined(__BIONIC_FORTIFY) */ #if defined(__clang__) diff --git a/headers/sys/_system_properties.h b/headers/sys/_system_properties.h index ffa6d2e73..186d39034 100644 --- a/headers/sys/_system_properties.h +++ b/headers/sys/_system_properties.h @@ -30,6 +30,8 @@ #define _INCLUDE_SYS__SYSTEM_PROPERTIES_H #include <sys/cdefs.h> +#include <stdbool.h> +#include <stdint.h> #ifndef _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ #error you should #include <sys/system_properties.h> instead @@ -91,7 +93,7 @@ int __system_property_area_init(); ** ** Returns the serial number on success, -1 on error. */ -unsigned int __system_property_area_serial(); +uint32_t __system_property_area_serial(); /* Add a new system property. Can only be done by a single ** process that has write access to the property area, and @@ -118,12 +120,26 @@ int __system_property_update(prop_info *pi, const char *value, unsigned int len) ** ** Returns the serial number on success, -1 on error. */ -unsigned int __system_property_serial(const prop_info *pi); +uint32_t __system_property_serial(const prop_info* pi); -/* Wait for any system property to be updated. Caller must pass -** in 0 the first time, and the previous return value on each -** successive call. */ -unsigned int __system_property_wait_any(unsigned int serial); +/* + * Waits for the specific system property identified by `pi` to be updated + * past `old_serial`. Waits no longer than `relative_timeout`, or forever + * if `relaive_timeout` is null. + * + * If `pi` is null, waits for the global serial number instead. + * + * If you don't know the current serial, use 0. + * + * Returns true and updates `*new_serial_ptr` on success, or false if the call + * timed out. + */ +struct timespec; +bool __system_property_wait(const prop_info* pi, + uint32_t old_serial, + uint32_t* new_serial_ptr, + const struct timespec* relative_timeout) + __INTRODUCED_IN_FUTURE; /* Initialize the system properties area in read only mode. * Should be done by all processes that need to read system @@ -133,6 +149,9 @@ unsigned int __system_property_wait_any(unsigned int serial); */ int __system_properties_init(); +/* Deprecated: use __system_property_wait instead. */ +uint32_t __system_property_wait_any(uint32_t old_serial); + __END_DECLS #endif diff --git a/headers/sys/cdefs.h b/headers/sys/cdefs.h index 63e782efd..dab252d6f 100644 --- a/headers/sys/cdefs.h +++ b/headers/sys/cdefs.h @@ -181,12 +181,29 @@ #define __wur __attribute__((__warn_unused_result__)) #ifdef __clang__ -#define __errorattr(msg) __attribute__((unavailable(msg))) +# define __errorattr(msg) __attribute__((unavailable(msg))) +# define __warnattr(msg) __attribute__((deprecated(msg))) +# define __warnattr_real(msg) __attribute__((deprecated(msg))) +# define __enable_if(cond, msg) __attribute__((enable_if(cond, msg))) #else -#define __errorattr(msg) __attribute__((__error__(msg))) +# define __errorattr(msg) __attribute__((__error__(msg))) +# define __warnattr(msg) __attribute__((__warning__(msg))) +# define __warnattr_real __warnattr +/* enable_if doesn't exist on other compilers; give an error if it's used. */ + +/* errordecls really don't work as well in clang as they do in GCC. */ +# define __errordecl(name, msg) extern void name(void) __errorattr(msg) #endif -#define __errordecl(name, msg) extern void name(void) __errorattr(msg) +#if defined(ANDROID_STRICT) +/* + * For things that are sketchy, but not necessarily an error. FIXME: Enable + * this. + */ +# define __warnattr_strict(msg) /* __warnattr(msg) */ +#else +# define __warnattr_strict(msg) +#endif /* * Some BSD source needs these macros. @@ -242,21 +259,60 @@ * See * http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html for details. */ + +#define __BIONIC_FORTIFY_UNKNOWN_SIZE ((size_t) -1) + #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 # define __BIONIC_FORTIFY 1 # if _FORTIFY_SOURCE == 2 -# define __bos(s) __builtin_object_size((s), 1) +# define __bos_level 1 # else -# define __bos(s) __builtin_object_size((s), 0) +# define __bos_level 0 # endif -# define __bos0(s) __builtin_object_size((s), 0) +# define __bosn(s, n) __builtin_object_size((s), (n)) +# define __bos(s) __bosn((s), __bos_level) +# define __bos0(s) __bosn((s), 0) # if defined(__clang__) -# define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline)) +# define __pass_object_size_n(n) __attribute__((pass_object_size(n))) +/* + * FORTIFY'ed functions all have either enable_if or pass_object_size, which + * makes taking their address impossible. Saying (&read)(foo, bar, baz); will + * therefore call the unFORTIFYed version of read. + */ +# define __call_bypassing_fortify(fn) (&fn) +/* + * Because clang-FORTIFY uses overloads, we can't mark functions as `extern + * inline` without making them available externally. + */ +# define __BIONIC_FORTIFY_INLINE static __inline__ __always_inline +/* Error functions don't have bodies, so they can just be static. */ +# define __BIONIC_ERROR_FUNCTION_VISIBILITY static # else +/* + * Where they can, GCC and clang-style FORTIFY share implementations. + * So, make these nops in GCC. + */ +# define __pass_object_size_n(n) +# define __call_bypassing_fortify(fn) (fn) +/* __BIONIC_FORTIFY_NONSTATIC_INLINE is pointless in GCC's FORTIFY */ # define __BIONIC_FORTIFY_INLINE extern __inline__ __always_inline __attribute__((gnu_inline)) __attribute__((__artificial__)) # endif +# define __pass_object_size __pass_object_size_n(__bos_level) +# define __pass_object_size0 __pass_object_size_n(0) +#endif + +/* Used to support clangisms with FORTIFY. This isn't in the FORTIFY section + * because these change how symbols are emitted. The linker must be kept happy. + */ +#ifdef __clang__ +# define __overloadable __attribute__((overloadable)) +// Don't use __RENAME directly because on gcc, this could result in a number of +// unnecessary renames. +# define __RENAME_CLANG(x) __RENAME(x) +#else +# define __overloadable +# define __RENAME_CLANG(x) #endif -#define __BIONIC_FORTIFY_UNKNOWN_SIZE __BIONIC_CAST(static_cast, size_t, -1) /* Used to tag non-static symbols that are private and never exposed by the shared library. */ #define __LIBC_HIDDEN__ __attribute__((visibility("hidden"))) @@ -291,17 +347,15 @@ int __size_mul_overflow(__SIZE_TYPE__ a, __SIZE_TYPE__ b, __SIZE_TYPE__ *result) } #endif +#if defined(__clang__) /* - * TODO(danalbert): Remove this once we've moved entirely off prebuilts/ndk. - * - * The NDK used to have a __NDK_FPABI__ that was defined to empty for most cases - * but `__attribute__((pcs("aapcs")))` for the now defunct armeabi-v7a-hard ABI. - * - * During the transition from prebuilts/ndk to ndk_headers, we'll have some - * headers that still use __NDK_FPABI__ while the libc headers have stopped - * defining it. In the interim, just provide an empty definition to keep the - * build working. + * Used when we need to check for overflow when multiplying x and y. This + * should only be used where __size_mul_overflow can not work, because it makes + * assumptions that __size_mul_overflow doesn't (x and y are positive, ...), + * *and* doesn't make use of compiler intrinsics, so it's probably slower than + * __size_mul_overflow. */ -#define __NDK_FPABI__ +#define __unsafe_check_mul_overflow(x, y) ((__SIZE_TYPE__)-1 / (x) < (y)) +#endif #endif /* !_SYS_CDEFS_H_ */ diff --git a/headers/sys/socket.h b/headers/sys/socket.h index 87246260a..21a30c560 100644 --- a/headers/sys/socket.h +++ b/headers/sys/socket.h @@ -329,29 +329,101 @@ __socketcall int shutdown(int, int); __socketcall int socket(int, int, int); __socketcall int socketpair(int, int, int, int*); -ssize_t recv(int, void*, size_t, int); -ssize_t send(int, const void*, size_t, int); +ssize_t recv(int, void*, size_t, int) __overloadable __RENAME_CLANG(recv); +ssize_t send(int, const void*, size_t, int) __overloadable __RENAME_CLANG(send); -__socketcall ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t); -__socketcall ssize_t recvfrom(int, void*, size_t, int, struct sockaddr*, socklen_t*); +__socketcall ssize_t sendto(int, const void*, size_t, int, const struct sockaddr*, socklen_t) + __overloadable __RENAME_CLANG(sendto); +__socketcall ssize_t recvfrom(int, void*, size_t, int, struct sockaddr*, + socklen_t*) __overloadable __RENAME_CLANG(recvfrom); + + +#if __ANDROID_API__ >= __ANDROID_API_FUTURE__ +extern ssize_t __sendto_chk(int, const void*, size_t, size_t, int, const struct sockaddr*, + socklen_t) __INTRODUCED_IN_FUTURE; +#endif /* __ANDROID_API__ >= __ANDROID_API_FUTURE__ */ -__errordecl(__recvfrom_error, "recvfrom called with size bigger than buffer"); #if __ANDROID_API__ >= 21 -ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*, socklen_t*) - __INTRODUCED_IN(21); +ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*, + socklen_t*) __INTRODUCED_IN(21); #endif /* __ANDROID_API__ >= 21 */ -ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom); #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) { +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 !defined(__clang__) if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len); } @@ -363,17 +435,49 @@ ssize_t recvfrom(int fd, void* buf, size_t len, int flags, struct sockaddr* src_ if (__builtin_constant_p(len) && (len > bos)) { __recvfrom_error(); } -#endif 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* buf, size_t len, int flags) { +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 */ #undef __socketcall diff --git a/headers/sys/stat.h b/headers/sys/stat.h index 753ad7f99..b2dde3c68 100644 --- a/headers/sys/stat.h +++ b/headers/sys/stat.h @@ -177,33 +177,56 @@ int stat64(const char*, struct stat64*) __INTRODUCED_IN(21); int mknod(const char*, mode_t, dev_t); -mode_t umask(mode_t); +mode_t umask(mode_t) __overloadable __RENAME_CLANG(umask); #if __ANDROID_API__ >= 18 mode_t __umask_chk(mode_t) __INTRODUCED_IN(18); #endif /* __ANDROID_API__ >= 18 */ -mode_t __umask_real(mode_t) __RENAME(umask); -__errordecl(__umask_invalid_mode, "umask called with invalid mode"); #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 !defined(__clang__) if (__builtin_constant_p(mode)) { if ((mode & 0777) != mode) { __umask_invalid_mode(); } return __umask_real(mode); } -#endif return __umask_chk(mode); } #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */ +#endif /* defined(__clang__) */ +#undef __umask_invalid_mode_str + #endif /* defined(__BIONIC_FORTIFY) */ #if __ANDROID_API__ >= __ANDROID_API_L__ diff --git a/headers/sys/system_properties.h b/headers/sys/system_properties.h index b3fbc48ff..f7d1bacc8 100644 --- a/headers/sys/system_properties.h +++ b/headers/sys/system_properties.h @@ -31,82 +31,48 @@ #include <sys/cdefs.h> #include <stddef.h> +#include <stdint.h> __BEGIN_DECLS typedef struct prop_info prop_info; -#define PROP_NAME_MAX 32 #define PROP_VALUE_MAX 92 -/* Look up a system property by name, copying its value and a -** \0 terminator to the provided pointer. The total bytes -** copied will be no greater than PROP_VALUE_MAX. Returns -** the string length of the value. A property that is not -** defined is identical to a property with a length 0 value. -*/ -int __system_property_get(const char *name, char *value); - -/* Set a system property by name. -**/ +/* + * Sets system property `key` to `value`, creating the system property if it doesn't already exist. + */ #if __ANDROID_API__ >= 12 int __system_property_set(const char* key, const char* value) __INTRODUCED_IN(12); #endif /* __ANDROID_API__ >= 12 */ -/* Return a pointer to the system property named name, if it -** exists, or NULL if there is no such property. Use -** __system_property_read() to obtain the string value from -** the returned prop_info pointer. -** -** It is safe to cache the prop_info pointer to avoid future -** lookups. These returned pointers will remain valid for -** the lifetime of the system. -*/ -const prop_info *__system_property_find(const char *name); - -/* Read the value of a system property. Returns the length -** of the value. Copies the value and \0 terminator into -** the provided value pointer. Total length (including -** terminator) will be no greater that PROP_VALUE_MAX for -** __system_property_read. -** -** If name is nonzero, up to PROP_NAME_MAX bytes will be -** copied into the provided name pointer. The name will -** be \0 terminated. -*/ -int __system_property_read(const prop_info *pi, char *name, char *value); +/* + * Returns a `prop_info` corresponding system property `name`, or nullptr if it doesn't exist. + * Use __system_property_read_callback to query the current value. + * + * Property lookup is expensive, so it can be useful to cache the result of this function. + */ +const prop_info* __system_property_find(const char* name); + +/* + * Calls `callback` with a consistent trio of name, value, and serial number for property `pi`. + */ #if __ANDROID_API__ >= __ANDROID_API_FUTURE__ void __system_property_read_callback(const prop_info *pi, - void (*)(void* cookie, const char *name, const char *value), - void* cookie) __INTRODUCED_IN_FUTURE; + void (*callback)(void* cookie, const char *name, const char *value, uint32_t serial), + void* cookie) __INTRODUCED_IN_FUTURE; #endif /* __ANDROID_API__ >= __ANDROID_API_FUTURE__ */ -/* Return a prop_info for the nth system property, or NULL if -** there is no nth property. Use __system_property_read() to -** read the value of this property. -** -** Please do not call this method. It only exists to provide -** backwards compatibility to NDK apps. Its implementation -** is inefficient and order of results may change from call -** to call. -*/ -const prop_info *__system_property_find_nth(unsigned n) - __REMOVED_IN(26); - -/* Pass a prop_info for each system property to the provided -** callback. Use __system_property_read() to read the value -** of this property. -** -** This method is for inspecting and debugging the property -** system. Please use __system_property_find() instead. -** -** Order of results may change from call to call. This is -** not a bug. -*/ +/* + * Passes a `prop_info` for each system property to the provided + * callback. Use __system_property_read_callback() to read the value. + * + * This method is for inspecting and debugging the property system, and not generally useful. + */ #if __ANDROID_API__ >= 19 int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie), void* cookie) @@ -114,6 +80,15 @@ int __system_property_foreach(void (*propfn)(const prop_info* pi, void* cookie), #endif /* __ANDROID_API__ >= 19 */ +/* Deprecated. In Android O and above, there's no limit on property name length. */ +#define PROP_NAME_MAX 32 +/* Deprecated. Use __system_property_read_callback instead. */ +int __system_property_read(const prop_info *pi, char *name, char *value); +/* Deprecated. Use __system_property_read_callback instead. */ +int __system_property_get(const char *name, char *value); +/* Deprecated. Use __system_property_foreach instead. Aborts in Android O and above. */ +const prop_info *__system_property_find_nth(unsigned n) __REMOVED_IN(26); + __END_DECLS #endif diff --git a/headers/termios.h b/headers/termios.h index ab27d9d83..66ae71cd5 100644 --- a/headers/termios.h +++ b/headers/termios.h @@ -40,8 +40,10 @@ __BEGIN_DECLS speed_t cfgetispeed(const struct termios*) __INTRODUCED_IN(21); speed_t cfgetospeed(const struct termios*) __INTRODUCED_IN(21); void cfmakeraw(struct termios*) __INTRODUCED_IN(21); +int cfsetspeed(struct termios*, speed_t) __INTRODUCED_IN(21); int cfsetispeed(struct termios*, speed_t) __INTRODUCED_IN(21); int cfsetospeed(struct termios*, speed_t) __INTRODUCED_IN(21); +int tcdrain(int) __INTRODUCED_IN(21); int tcflow(int, int) __INTRODUCED_IN(21); int tcflush(int, int) __INTRODUCED_IN(21); int tcgetattr(int, struct termios*) __INTRODUCED_IN(21); @@ -50,13 +52,6 @@ int tcsendbreak(int, int) __INTRODUCED_IN(21); int tcsetattr(int, int, const struct termios*) __INTRODUCED_IN(21); #endif - -#if __ANDROID_API__ >= 21 -int cfsetspeed(struct termios*, speed_t) __INTRODUCED_IN(21); -int tcdrain(int) __INTRODUCED_IN(21); -#endif /* __ANDROID_API__ >= 21 */ - - __END_DECLS #include <android/legacy_termios_inlines.h> diff --git a/headers/unistd.h b/headers/unistd.h index a1e23fcdc..15359a1ae 100644 --- a/headers/unistd.h +++ b/headers/unistd.h @@ -159,25 +159,29 @@ int symlink(const char* __oldpath, const char* __newpath); int symlinkat(const char* __oldpath, int __newdirfd, const char* __newpath) __INTRODUCED_IN(21); #endif /* __ANDROID_API__ >= 21 */ -ssize_t readlink(const char* __path, char* __buf, size_t __bufsiz); +ssize_t readlink(const char* __path, char* __buf, size_t __bufsiz) + __overloadable __RENAME_CLANG(readlink); #if __ANDROID_API__ >= 21 ssize_t readlinkat(int __dirfd, const char* __path, char* __buf, - size_t __bufsiz) __INTRODUCED_IN(21); + size_t __bufsiz) + __INTRODUCED_IN(21) __overloadable __RENAME_CLANG(readlinkat); #endif /* __ANDROID_API__ >= 21 */ int chown(const char* __path, uid_t __owner, gid_t __group); int fchown(int __fd, uid_t __owner, gid_t __group); int fchownat(int __dirfd, const char* __path, uid_t __owner, gid_t __group, int __flags); int lchown(const char* __path, uid_t __owner, gid_t __group); -char* getcwd(char* __buf, size_t __size); +char* getcwd(char* __buf, size_t __size) __overloadable __RENAME_CLANG(getcwd); void sync(void); int close(int __fd); -ssize_t read(int __fd, void* __buf, size_t __count); -ssize_t write(int __fd, const void* __buf, size_t __count); +ssize_t read(int __fd, void* __buf, size_t __count) __overloadable + __RENAME_CLANG(read); +ssize_t write(int __fd, const void* __buf, size_t __count) __overloadable + __RENAME_CLANG(write); int dup(int __oldfd); int dup2(int __oldfd, int __newfd); @@ -199,15 +203,17 @@ off64_t lseek64(int __fd, off64_t __offset, int __whence); #if defined(__USE_FILE_OFFSET64) && __ANDROID_API__ >= __ANDROID_API_L__ int truncate(const char* __path, off_t __length) __RENAME(truncate64) __INTRODUCED_IN(21); -ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset) __RENAME(pread64) - __INTRODUCED_IN(12); +ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset) + __overloadable __RENAME(pread64) __INTRODUCED_IN(12); ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset) - __RENAME(pwrite64) __INTRODUCED_IN(12); + __overloadable __RENAME(pwrite64) __INTRODUCED_IN(12); int ftruncate(int __fd, off_t __length) __RENAME(ftruncate64) __INTRODUCED_IN(12); #else int truncate(const char* __path, off_t __length); -ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset); -ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset); +ssize_t pread(int __fd, void* __buf, size_t __count, off_t __offset) + __overloadable __RENAME_CLANG(pread); +ssize_t pwrite(int __fd, const void* __buf, size_t __count, off_t __offset) + __overloadable __RENAME_CLANG(pwrite); int ftruncate(int __fd, off_t __length); #endif @@ -218,9 +224,10 @@ int truncate64(const char* __path, off64_t __length) __INTRODUCED_IN(21); #if __ANDROID_API__ >= 12 -ssize_t pread64(int __fd, void* __buf, size_t __count, off64_t __offset) __INTRODUCED_IN(12); +ssize_t pread64(int __fd, void* __buf, size_t __count, off64_t __offset) + __INTRODUCED_IN(12) __overloadable __RENAME_CLANG(pread64); ssize_t pwrite64(int __fd, const void* __buf, size_t __count, off64_t __offset) - __INTRODUCED_IN(12); + __INTRODUCED_IN(12) __overloadable __RENAME_CLANG(pwrite64); int ftruncate64(int __fd, off64_t __length) __INTRODUCED_IN(12); #endif /* __ANDROID_API__ >= 12 */ @@ -280,16 +287,12 @@ int tcsetpgrp(int __fd, pid_t __pid); char* __getcwd_chk(char*, size_t, size_t) __INTRODUCED_IN(24); #endif /* __ANDROID_API__ >= 24 */ -__errordecl(__getcwd_dest_size_error, "getcwd called with size bigger than destination"); -char* __getcwd_real(char*, size_t) __RENAME(getcwd); #if __ANDROID_API__ >= 23 ssize_t __pread_chk(int, void*, size_t, off_t, size_t) __INTRODUCED_IN(23); #endif /* __ANDROID_API__ >= 23 */ -__errordecl(__pread_dest_size_error, "pread called with size bigger than destination"); -__errordecl(__pread_count_toobig_error, "pread called with count > SSIZE_MAX"); ssize_t __pread_real(int, void*, size_t, off_t) __RENAME(pread); @@ -297,8 +300,6 @@ 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); #endif /* __ANDROID_API__ >= 23 */ -__errordecl(__pread64_dest_size_error, "pread64 called with size bigger than destination"); -__errordecl(__pread64_count_toobig_error, "pread64 called with count > SSIZE_MAX"); #if __ANDROID_API__ >= 12 ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64) __INTRODUCED_IN(12); @@ -310,8 +311,6 @@ ssize_t __pread64_real(int, void*, size_t, off64_t) __RENAME(pread64) __INTRODUC ssize_t __pwrite_chk(int, const void*, size_t, off_t, size_t) __INTRODUCED_IN(24); #endif /* __ANDROID_API__ >= 24 */ -__errordecl(__pwrite_dest_size_error, "pwrite called with size bigger than destination"); -__errordecl(__pwrite_count_toobig_error, "pwrite called with count > SSIZE_MAX"); ssize_t __pwrite_real(int, const void*, size_t, off_t) __RENAME(pwrite); @@ -319,11 +318,10 @@ 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); #endif /* __ANDROID_API__ >= 24 */ -__errordecl(__pwrite64_dest_size_error, "pwrite64 called with size bigger than destination"); -__errordecl(__pwrite64_count_toobig_error, "pwrite64 called with count > SSIZE_MAX"); #if __ANDROID_API__ >= 12 -ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64) __INTRODUCED_IN(12); +ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64) + __INTRODUCED_IN(12); #endif /* __ANDROID_API__ >= 12 */ @@ -332,40 +330,17 @@ ssize_t __pwrite64_real(int, const void*, size_t, off64_t) __RENAME(pwrite64) __ ssize_t __read_chk(int, void*, size_t, size_t) __INTRODUCED_IN(21); #endif /* __ANDROID_API__ >= 21 */ -__errordecl(__read_dest_size_error, "read called with size bigger than destination"); -__errordecl(__read_count_toobig_error, "read called with count > SSIZE_MAX"); -ssize_t __read_real(int, void*, size_t) __RENAME(read); - #if __ANDROID_API__ >= 24 ssize_t __write_chk(int, const void*, size_t, size_t) __INTRODUCED_IN(24); #endif /* __ANDROID_API__ >= 24 */ -__errordecl(__write_dest_size_error, "write called with size bigger than destination"); -__errordecl(__write_count_toobig_error, "write called with count > SSIZE_MAX"); -ssize_t __write_real(int, const void*, size_t) __RENAME(write); - #if __ANDROID_API__ >= 23 ssize_t __readlink_chk(const char*, char*, size_t, size_t) __INTRODUCED_IN(23); -#endif /* __ANDROID_API__ >= 23 */ - -__errordecl(__readlink_dest_size_error, "readlink called with size bigger than destination"); -__errordecl(__readlink_size_toobig_error, "readlink called with size > SSIZE_MAX"); -ssize_t __readlink_real(const char*, char*, size_t) __RENAME(readlink); - - -#if __ANDROID_API__ >= 23 ssize_t __readlinkat_chk(int dirfd, const char*, char*, size_t, size_t) __INTRODUCED_IN(23); #endif /* __ANDROID_API__ >= 23 */ -__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__ >= 21 -ssize_t __readlinkat_real(int dirfd, const char*, char*, size_t) __RENAME(readlinkat) __INTRODUCED_IN(21); -#endif /* __ANDROID_API__ >= 21 */ - #if __ANDROID_API__ >= __ANDROID_API_FUTURE__ @@ -376,22 +351,269 @@ int setdomainname(const char*, size_t) __INTRODUCED_IN_FUTURE; #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* buf, size_t size) { +char* getcwd(char* const __pass_object_size buf, size_t size) __overloadable { size_t bos = __bos(buf); -#if defined(__clang__) /* - * Work around LLVM's incorrect __builtin_object_size implementation here - * to avoid needing the workaround in the __getcwd_chk ABI forever. - * - * https://llvm.org/bugs/show_bug.cgi?id=23277 + * 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 (buf == NULL) { - bos = __BIONIC_FORTIFY_UNKNOWN_SIZE; + if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE || buf == NULL) { + return __call_bypassing_fortify(getcwd)(buf, size); } -#else + + 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); } @@ -403,24 +625,16 @@ char* getcwd(char* buf, size_t size) { if (__builtin_constant_p(size) && (size <= bos)) { return __getcwd_real(buf, size); } -#endif return __getcwd_chk(buf, size, bos); } #endif /* __ANDROID_API__ >= __ANDROID_API_N__ */ -#if defined(__USE_FILE_OFFSET64) -#define __PREAD_PREFIX(x) __pread64_ ## x -#else -#define __PREAD_PREFIX(x) __pread_ ## x -#endif - #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 !defined(__clang__) if (__builtin_constant_p(count) && (count > SSIZE_MAX)) { __PREAD_PREFIX(count_toobig_error)(); } @@ -436,7 +650,6 @@ ssize_t pread(int fd, void* buf, size_t count, off_t offset) { if (__builtin_constant_p(count) && (count <= bos)) { return __PREAD_PREFIX(real)(fd, buf, count, offset); } -#endif return __PREAD_PREFIX(chk)(fd, buf, count, offset, bos); } @@ -445,7 +658,6 @@ __BIONIC_FORTIFY_INLINE ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) { size_t bos = __bos0(buf); -#if !defined(__clang__) if (__builtin_constant_p(count) && (count > SSIZE_MAX)) { __pread64_count_toobig_error(); } @@ -461,24 +673,16 @@ ssize_t pread64(int fd, void* buf, size_t count, off64_t offset) { if (__builtin_constant_p(count) && (count <= bos)) { return __pread64_real(fd, buf, count, offset); } -#endif return __pread64_chk(fd, buf, count, offset, bos); } #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */ -#if defined(__USE_FILE_OFFSET64) -#define __PWRITE_PREFIX(x) __pwrite64_ ## x -#else -#define __PWRITE_PREFIX(x) __pwrite_ ## x -#endif - #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 !defined(__clang__) if (__builtin_constant_p(count) && (count > SSIZE_MAX)) { __PWRITE_PREFIX(count_toobig_error)(); } @@ -494,7 +698,6 @@ ssize_t pwrite(int fd, const void* buf, size_t count, off_t offset) { if (__builtin_constant_p(count) && (count <= bos)) { return __PWRITE_PREFIX(real)(fd, buf, count, offset); } -#endif return __PWRITE_PREFIX(chk)(fd, buf, count, offset, bos); } @@ -503,7 +706,6 @@ __BIONIC_FORTIFY_INLINE ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) { size_t bos = __bos0(buf); -#if !defined(__clang__) if (__builtin_constant_p(count) && (count > SSIZE_MAX)) { __pwrite64_count_toobig_error(); } @@ -519,7 +721,6 @@ ssize_t pwrite64(int fd, const void* buf, size_t count, off64_t offset) { if (__builtin_constant_p(count) && (count <= bos)) { return __pwrite64_real(fd, buf, count, offset); } -#endif return __pwrite64_chk(fd, buf, count, offset, bos); } @@ -530,7 +731,6 @@ __BIONIC_FORTIFY_INLINE ssize_t read(int fd, void* buf, size_t count) { size_t bos = __bos0(buf); -#if !defined(__clang__) if (__builtin_constant_p(count) && (count > SSIZE_MAX)) { __read_count_toobig_error(); } @@ -546,7 +746,6 @@ ssize_t read(int fd, void* buf, size_t count) { if (__builtin_constant_p(count) && (count <= bos)) { return __read_real(fd, buf, count); } -#endif return __read_chk(fd, buf, count, bos); } @@ -557,13 +756,6 @@ __BIONIC_FORTIFY_INLINE ssize_t write(int fd, const void* buf, size_t count) { size_t bos = __bos0(buf); -#if !defined(__clang__) -#if 0 /* work around a false positive due to a missed optimization */ - if (__builtin_constant_p(count) && (count > SSIZE_MAX)) { - __write_count_toobig_error(); - } -#endif - if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { return __write_real(fd, buf, count); } @@ -575,7 +767,6 @@ ssize_t write(int fd, const void* buf, size_t count) { if (__builtin_constant_p(count) && (count <= bos)) { return __write_real(fd, buf, count); } -#endif return __write_chk(fd, buf, count, bos); } @@ -586,7 +777,6 @@ __BIONIC_FORTIFY_INLINE ssize_t readlink(const char* path, char* buf, size_t size) { size_t bos = __bos(buf); -#if !defined(__clang__) if (__builtin_constant_p(size) && (size > SSIZE_MAX)) { __readlink_size_toobig_error(); } @@ -602,7 +792,6 @@ ssize_t readlink(const char* path, char* buf, size_t size) { if (__builtin_constant_p(size) && (size <= bos)) { return __readlink_real(path, buf, size); } -#endif return __readlink_chk(path, buf, size, bos); } @@ -611,7 +800,6 @@ __BIONIC_FORTIFY_INLINE ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size) { size_t bos = __bos(buf); -#if !defined(__clang__) if (__builtin_constant_p(size) && (size > SSIZE_MAX)) { __readlinkat_size_toobig_error(); } @@ -627,12 +815,13 @@ ssize_t readlinkat(int dirfd, const char* path, char* buf, size_t size) { if (__builtin_constant_p(size) && (size <= bos)) { return __readlinkat_real(dirfd, path, buf, size); } -#endif 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 |