summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2017-02-24 19:54:43 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-02-24 19:54:43 +0000
commit2807fa99bd2e2268897e10d39a261edda89652a3 (patch)
tree5f533e696c7aaaf5c2613a1f1794fd0edfd85640
parentb63cf0b45a786e48ef41a0ee0ff9bd9095069078 (diff)
parent4d230e6e5a0557c065e548f1730ad65bb5155699 (diff)
downloadndk-2807fa99bd2e2268897e10d39a261edda89652a3.tar.gz
Merge "Update bionic headers to 9dbfd8ad7." am: d89dea2f0d
am: 4d230e6e5a Change-Id: Ie87a0913958a79804fe361ecd640beb8d6c8b5d1
-rw-r--r--NOTICE44
-rw-r--r--headers/android/legacy_termios_inlines.h12
-rw-r--r--headers/fcntl.h81
-rw-r--r--headers/malloc.h7
-rw-r--r--headers/poll.h77
-rw-r--r--headers/stdio.h233
-rw-r--r--headers/stdlib.h35
-rw-r--r--headers/string.h405
-rw-r--r--headers/sys/_system_properties.h31
-rw-r--r--headers/sys/cdefs.h90
-rw-r--r--headers/sys/socket.h128
-rw-r--r--headers/sys/stat.h33
-rw-r--r--headers/sys/system_properties.h89
-rw-r--r--headers/termios.h9
-rw-r--r--headers/unistd.h371
15 files changed, 1235 insertions, 410 deletions
diff --git a/NOTICE b/NOTICE
index 1b996e94e..6882d0c68 100644
--- a/NOTICE
+++ b/NOTICE
@@ -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