diff options
30 files changed, 288 insertions, 202 deletions
diff --git a/docs/status.md b/docs/status.md index 2919471e8..bc8ab6a4f 100644 --- a/docs/status.md +++ b/docs/status.md @@ -397,22 +397,25 @@ automatic bounds checking for common libc functions. If a buffer overrun is detected, the program is safely aborted as in this [example](https://source.android.com/devices/tech/debug/native-crash#fortify). -Note that in recent releases Android's FORTIFY has been extended to -cover other issues. It can now detect, for example, passing `O_CREAT` -to open(2) without specifying a mode. It also performs some checking -regardless of whether the caller was built with FORTIFY enabled. In P, -for example, calling a `pthread_mutex_` function on a destroyed mutex, -calling a `<dirent.h>` function on a null pointer, using `%n` with the -printf(3) family, or using the scanf(3) `m` modifier incorrectly will -all result in FORTIFY failures even for code not built with FORTIFY. +Note that Android's FORTIFY has been extended to cover other issues. It can +detect, for example, passing `O_CREAT` to open(2) without specifying a mode. It +also performs some checking regardless of whether the caller was built with +FORTIFY enabled. From API level 28, for example, calling a `pthread_mutex_` +function on a destroyed mutex, calling a `<dirent.h>` function on a null +pointer, using `%n` with the printf(3) family, or using the scanf(3) `m` +modifier incorrectly will all result in FORTIFY failures even for code not built +with FORTIFY. More background information is available in our [FORTIFY in Android](https://android-developers.googleblog.com/2017/04/fortify-in-android.html) -blog post. - -The Android platform is built with `-D_FORTIFY_SOURCE=2`, but NDK users -need to manually enable FORTIFY by setting that themselves in whatever -build system they're using. The exact subset of FORTIFY available to +blog post, and there's more detail about the implementation in +[The Anatomy of Clang FORTIFY](clang_fortify_anatomy.md). + +The Android platform is built with `-D_FORTIFY_SOURCE=2`. Users of ndk-build +or the NDK's CMake toolchain file also get this by default with NDK r21 or +newer. Users of other build systems +need to manually enable FORTIFY by setting `_FORTIFY_SOURCE` themselves in +whatever build system they're using. The exact subset of FORTIFY available to NDK users will depend on their target ABI level, because when a FORTIFY check can't be guaranteed at compile-time, a call to a run-time `_chk` function is added. diff --git a/libc/Android.bp b/libc/Android.bp index 84fa498d3..2efca6855 100644 --- a/libc/Android.bp +++ b/libc/Android.bp @@ -55,7 +55,9 @@ libc_common_flags = [ cc_defaults { name: "libc_defaults", defaults: ["linux_bionic_supported"], - cflags: libc_common_flags, + cflags: libc_common_flags + [ + "-DUSE_SCUDO", + ], asflags: libc_common_flags, conlyflags: ["-std=gnu99"], cppflags: [], @@ -98,8 +100,8 @@ cc_defaults { malloc_pattern_fill_contents: { cflags: ["-DSCUDO_PATTERN_FILL_CONTENTS"], }, - malloc_not_svelte: { - cflags: ["-DUSE_SCUDO"], + malloc_low_memory: { + cflags: ["-UUSE_SCUDO"], }, }, @@ -112,32 +114,31 @@ cc_defaults { tidy_disabled_srcs: ["upstream-*/**/*.c"], } -libc_scudo_product_variables = { - malloc_not_svelte: { - cflags: ["-DUSE_SCUDO"], - whole_static_libs: ["libscudo"], - exclude_static_libs: [ - "libjemalloc5", - "libc_jemalloc_wrapper", - ], - }, -} - // Defaults for native allocator libs/includes to make it // easier to change. -// To disable scudo for the non-svelte config remove the line: -// product_variables: libc_scudo_product_variables, -// in the cc_defaults below. // ======================================================== cc_defaults { name: "libc_native_allocator_defaults", whole_static_libs: [ - "libjemalloc5", - "libc_jemalloc_wrapper", + "libscudo", + ], + cflags: [ + "-DUSE_SCUDO", ], header_libs: ["gwp_asan_headers"], - product_variables: libc_scudo_product_variables, + product_variables: { + malloc_low_memory: { + cflags: ["-UUSE_SCUDO"], + whole_static_libs: [ + "libjemalloc5", + "libc_jemalloc_wrapper", + ], + exclude_static_libs: [ + "libscudo", + ], + }, + }, } // Functions not implemented by jemalloc directly, or that need to @@ -2990,3 +2991,8 @@ filegroup { name: "versioner-dependencies", srcs: ["versioner-dependencies/**/*"], } + +filegroup { + name: "linux_capability_header", + srcs: ["kernel/uapi/linux/capability.h"], +} diff --git a/libc/bionic/gwp_asan_wrappers.cpp b/libc/bionic/gwp_asan_wrappers.cpp index 11f7cedd2..2124f515d 100644 --- a/libc/bionic/gwp_asan_wrappers.cpp +++ b/libc/bionic/gwp_asan_wrappers.cpp @@ -57,7 +57,7 @@ static gwp_asan::GuardedPoolAllocator GuardedAlloc; static const MallocDispatch* prev_dispatch; -using Action = android_mallopt_gwp_asan_options_t::Action; +using Mode = android_mallopt_gwp_asan_options_t::Mode; using Options = gwp_asan::options::Options; // basename() is a mess, see the manpage. Let's be explicit what handling we @@ -261,8 +261,8 @@ void SetDefaultGwpAsanOptions(Options* options, unsigned* process_sample_rate, options->Recoverable = true; GwpAsanRecoverable = true; - if (mallopt_options.desire == Action::TURN_ON_WITH_SAMPLING || - mallopt_options.desire == Action::TURN_ON_FOR_APP_SAMPLED_NON_CRASHING) { + if (mallopt_options.mode == Mode::SYSTEM_PROCESS_OR_SYSTEM_APP || + mallopt_options.mode == Mode::APP_MANIFEST_DEFAULT) { *process_sample_rate = kDefaultProcessSampling; } else { *process_sample_rate = 1; @@ -285,7 +285,7 @@ bool GetGwpAsanOptionImpl(char* value_out, // be used. Tests still continue to use the environment variable though. if (*basename != '\0') { const char* default_sysprop = system_sysprop; - if (mallopt_options.desire == Action::TURN_ON_FOR_APP) { + if (mallopt_options.mode == Mode::APP_MANIFEST_ALWAYS) { default_sysprop = app_sysprop; } async_safe_format_buffer(&program_specific_sysprop[0], kSyspropMaxLen, "%s%s", @@ -425,7 +425,7 @@ bool MaybeInitGwpAsan(libc_globals* globals, Options options; unsigned process_sample_rate = kDefaultProcessSampling; if (!GetGwpAsanOptions(&options, &process_sample_rate, mallopt_options) && - mallopt_options.desire == Action::DONT_TURN_ON_UNLESS_OVERRIDDEN) { + mallopt_options.mode == Mode::APP_MANIFEST_NEVER) { return false; } @@ -492,7 +492,7 @@ bool MaybeInitGwpAsanFromLibc(libc_globals* globals) { android_mallopt_gwp_asan_options_t mallopt_options; mallopt_options.program_name = progname; - mallopt_options.desire = Action::TURN_ON_WITH_SAMPLING; + mallopt_options.mode = Mode::SYSTEM_PROCESS_OR_SYSTEM_APP; return MaybeInitGwpAsan(globals, mallopt_options); } diff --git a/libc/bionic/heap_tagging.cpp b/libc/bionic/heap_tagging.cpp index 4d1981c30..c8a025f57 100644 --- a/libc/bionic/heap_tagging.cpp +++ b/libc/bionic/heap_tagging.cpp @@ -38,6 +38,11 @@ extern "C" void scudo_malloc_disable_memory_tagging(); extern "C" void scudo_malloc_set_track_allocation_stacks(int); +extern "C" const char* __scudo_get_stack_depot_addr(); +extern "C" const char* __scudo_get_ring_buffer_addr(); +extern "C" size_t __scudo_get_ring_buffer_size(); +extern "C" size_t __scudo_get_stack_depot_size(); + // Protected by `g_heap_tagging_lock`. static HeapTaggingLevel heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE; @@ -158,6 +163,10 @@ bool SetHeapTaggingLevel(HeapTaggingLevel tag_level) { set_tcf_on_all_threads(PR_MTE_TCF_SYNC); #if defined(USE_SCUDO) && !__has_feature(hwaddress_sanitizer) scudo_malloc_set_track_allocation_stacks(1); + __libc_shared_globals()->scudo_ring_buffer = __scudo_get_ring_buffer_addr(); + __libc_shared_globals()->scudo_ring_buffer_size = __scudo_get_ring_buffer_size(); + __libc_shared_globals()->scudo_stack_depot = __scudo_get_stack_depot_addr(); + __libc_shared_globals()->scudo_stack_depot_size = __scudo_get_stack_depot_size(); #endif } break; diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp index d86df3093..3da0a92d3 100644 --- a/libc/bionic/libc_init_static.cpp +++ b/libc/bionic/libc_init_static.cpp @@ -297,6 +297,30 @@ static HeapTaggingLevel __get_tagging_level(const memtag_dynamic_entries_t* memt return level; } +static int64_t __get_memtag_upgrade_secs() { + char* env = getenv("BIONIC_MEMTAG_UPGRADE_SECS"); + if (!env) return 0; + int64_t timed_upgrade = 0; + static const char kAppProcessName[] = "app_process64"; + const char* progname = __libc_shared_globals()->init_progname; + progname = progname ? __gnu_basename(progname) : nullptr; + // disable timed upgrade for zygote, as the thread spawned will violate the requirement + // that it be single-threaded. + if (!progname || strncmp(progname, kAppProcessName, sizeof(kAppProcessName)) != 0) { + char* endptr; + timed_upgrade = strtoll(env, &endptr, 10); + if (*endptr != '\0' || timed_upgrade < 0) { + async_safe_format_log(ANDROID_LOG_ERROR, "libc", + "Invalid value for BIONIC_MEMTAG_UPGRADE_SECS: %s", env); + timed_upgrade = 0; + } + } + // Make sure that this does not get passed to potential processes inheriting + // this environment. + unsetenv("BIONIC_MEMTAG_UPGRADE_SECS"); + return timed_upgrade; +} + // Figure out the desired memory tagging mode (sync/async, heap/globals/stack) for this executable. // This function is called from the linker before the main executable is relocated. __attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte( @@ -313,31 +337,7 @@ __attribute__((no_sanitize("hwaddress", "memtag"))) void __libc_init_mte( } memtag_stack = true; } - char* env = getenv("BIONIC_MEMTAG_UPGRADE_SECS"); - static const char kAppProcessName[] = "app_process64"; - const char* progname = __libc_shared_globals()->init_progname; - progname = progname ? __gnu_basename(progname) : nullptr; - if (progname && - strncmp(progname, kAppProcessName, sizeof(kAppProcessName)) == 0) { - // disable timed upgrade for zygote, as the thread spawned will violate the requirement - // that it be single-threaded. - env = nullptr; - } - int64_t timed_upgrade = 0; - if (env) { - char* endptr; - timed_upgrade = strtoll(env, &endptr, 10); - if (*endptr != '\0' || timed_upgrade < 0) { - async_safe_format_log(ANDROID_LOG_ERROR, "libc", - "Invalid value for BIONIC_MEMTAG_UPGRADE_SECS: %s", - env); - timed_upgrade = 0; - } - // Make sure that this does not get passed to potential processes inheriting - // this environment. - unsetenv("BIONIC_MEMTAG_UPGRADE_SECS"); - } - if (timed_upgrade) { + if (int64_t timed_upgrade = __get_memtag_upgrade_secs()) { if (level == M_HEAP_TAGGING_LEVEL_ASYNC) { async_safe_format_log(ANDROID_LOG_INFO, "libc", "Attempting timed MTE upgrade from async to sync."); diff --git a/libc/bionic/sys_statvfs.cpp b/libc/bionic/sys_statvfs.cpp index 3a05c3fa6..b3a0aca0c 100644 --- a/libc/bionic/sys_statvfs.cpp +++ b/libc/bionic/sys_statvfs.cpp @@ -17,7 +17,7 @@ #include <sys/statfs.h> #include <sys/statvfs.h> -static inline void __bionic_statfs_to_statvfs(const struct statfs* src, struct statvfs* dst) { +static __inline void __bionic_statfs_to_statvfs(const struct statfs* src, struct statvfs* dst) { dst->f_bsize = src->f_bsize; dst->f_frsize = src->f_frsize; dst->f_blocks = src->f_blocks; diff --git a/libc/dns/resolv/res_cache.c b/libc/dns/resolv/res_cache.c index d6416e5c5..38de84b5f 100644 --- a/libc/dns/resolv/res_cache.c +++ b/libc/dns/resolv/res_cache.c @@ -1166,23 +1166,19 @@ entry_free( Entry* e ) } } -static inline void -entry_mru_remove( Entry* e ) -{ - e->mru_prev->mru_next = e->mru_next; - e->mru_next->mru_prev = e->mru_prev; +static __inline__ void entry_mru_remove(Entry* e) { + e->mru_prev->mru_next = e->mru_next; + e->mru_next->mru_prev = e->mru_prev; } -static inline void -entry_mru_add( Entry* e, Entry* list ) -{ - Entry* first = list->mru_next; +static __inline__ void entry_mru_add(Entry* e, Entry* list) { + Entry* first = list->mru_next; - e->mru_next = first; - e->mru_prev = list; + e->mru_next = first; + e->mru_prev = list; - list->mru_next = e; - first->mru_prev = e; + list->mru_next = e; + first->mru_prev = e; } /* compute the hash of a given entry, this is a hash of most diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h index 113897c97..1bde3a598 100644 --- a/libc/include/android/api-level.h +++ b/libc/include/android/api-level.h @@ -168,7 +168,10 @@ __BEGIN_DECLS */ #define __ANDROID_API_U__ 34 -/** Names the "V" API level (35), for comparison against `__ANDROID_API__`. */ +/** + * Names the Android 15 (aka "V" or "VanillaIceCream") API level (35), + * for comparison against `__ANDROID_API__`. + */ #define __ANDROID_API_V__ 35 /* This file is included in <features.h>, and might be used from .S files. */ @@ -191,7 +194,7 @@ int android_get_application_target_sdk_version() __INTRODUCED_IN(24); #if __ANDROID_API__ < 29 /* android_get_device_api_level is a static inline before API level 29. */ -#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static inline +#define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline #include <bits/get_device_api_level_inlines.h> #undef __BIONIC_GET_DEVICE_API_LEVEL_INLINE diff --git a/libc/include/android/dlext.h b/libc/include/android/dlext.h index a5061c741..b42e5b22f 100644 --- a/libc/include/android/dlext.h +++ b/libc/include/android/dlext.h @@ -14,8 +14,7 @@ * limitations under the License. */ -#ifndef __ANDROID_DLEXT_H__ -#define __ANDROID_DLEXT_H__ +#pragma once #include <stdbool.h> #include <stddef.h> @@ -101,7 +100,7 @@ enum { ANDROID_DLEXT_FORCE_LOAD = 0x40, // Historically we had two other options for ART. - // They were last available in Android P. + // They were last available in API level 28. // Reuse these bits last! // ANDROID_DLEXT_FORCE_FIXED_VADDR = 0x80 // ANDROID_DLEXT_LOAD_AT_FIXED_ADDRESS = 0x100 @@ -115,7 +114,7 @@ enum { ANDROID_DLEXT_USE_NAMESPACE = 0x200, /** - * Instructs dlopen to apply `ANDROID_DLEXT_RESERVED_ADDRESS`, + * Instructs dlopen() to apply `ANDROID_DLEXT_RESERVED_ADDRESS`, * `ANDROID_DLEXT_RESERVED_ADDRESS_HINT`, `ANDROID_DLEXT_WRITE_RELRO` and * `ANDROID_DLEXT_USE_RELRO` to any libraries loaded as dependencies of the * main library as well. @@ -151,7 +150,7 @@ enum { struct android_namespace_t; -/** Used to pass Android-specific arguments to `android_dlopen_ext`. */ +/** Used to pass Android-specific arguments to android_dlopen_ext(). */ typedef struct { /** A bitmask of `ANDROID_DLEXT_` enum values. */ uint64_t flags; @@ -183,5 +182,3 @@ void* _Nullable android_dlopen_ext(const char* _Nullable __filename, int __flags __END_DECLS /** @} */ - -#endif diff --git a/libc/include/android/legacy_stdlib_inlines.h b/libc/include/android/legacy_stdlib_inlines.h index 0ca1022e8..f0985fe61 100644 --- a/libc/include/android/legacy_stdlib_inlines.h +++ b/libc/include/android/legacy_stdlib_inlines.h @@ -38,15 +38,15 @@ __BEGIN_DECLS -static inline double strtod_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) { +static __inline double strtod_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) { return strtod(__s, __end_ptr); } -static inline float strtof_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) { +static __inline float strtof_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, locale_t _Nonnull __l) { return strtof(__s, __end_ptr); } -static inline long strtol_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) { +static __inline long strtol_l(const char* _Nonnull __s, char* _Nullable * _Nullable __end_ptr, int __base, locale_t _Nonnull __l) { return strtol(__s, __end_ptr, __base); } diff --git a/libc/include/android/legacy_termios_inlines.h b/libc/include/android/legacy_termios_inlines.h index e557525ab..a816b4048 100644 --- a/libc/include/android/legacy_termios_inlines.h +++ b/libc/include/android/legacy_termios_inlines.h @@ -39,14 +39,14 @@ #include <sys/ioctl.h> #include <sys/types.h> -#define __BIONIC_TERMIOS_INLINE static inline +#define __BIONIC_TERMIOS_INLINE static __inline #include <bits/termios_inlines.h> #endif #if __ANDROID_API__ < 35 -#define __BIONIC_TERMIOS_WINSIZE_INLINE static inline +#define __BIONIC_TERMIOS_WINSIZE_INLINE static __inline #include <bits/termios_winsize_inlines.h> #endif diff --git a/libc/include/android/legacy_threads_inlines.h b/libc/include/android/legacy_threads_inlines.h index 06e743813..c614cd01a 100644 --- a/libc/include/android/legacy_threads_inlines.h +++ b/libc/include/android/legacy_threads_inlines.h @@ -32,7 +32,7 @@ #if __ANDROID_API__ < 30 -#define __BIONIC_THREADS_INLINE static inline +#define __BIONIC_THREADS_INLINE static __inline #include <bits/threads_inlines.h> #endif diff --git a/libc/include/android/legacy_unistd_inlines.h b/libc/include/android/legacy_unistd_inlines.h index ac9f3b354..4a5206b88 100644 --- a/libc/include/android/legacy_unistd_inlines.h +++ b/libc/include/android/legacy_unistd_inlines.h @@ -32,7 +32,7 @@ #if __ANDROID_API__ < 28 -#define __BIONIC_SWAB_INLINE static inline +#define __BIONIC_SWAB_INLINE static __inline #include <bits/swab.h> #endif diff --git a/libc/include/bits/stdatomic.h b/libc/include/bits/stdatomic.h index 8df86e2ad..c74eafdec 100644 --- a/libc/include/bits/stdatomic.h +++ b/libc/include/bits/stdatomic.h @@ -138,11 +138,11 @@ typedef enum { * 7.17.4 Fences. */ -static inline void atomic_thread_fence(memory_order __order __attribute__((__unused__))) { +static __inline void atomic_thread_fence(memory_order __order __attribute__((__unused__))) { __c11_atomic_thread_fence(__order); } -static inline void atomic_signal_fence(memory_order __order __attribute__((__unused__))) { +static __inline void atomic_signal_fence(memory_order __order __attribute__((__unused__))) { __c11_atomic_signal_fence(__order); } @@ -269,18 +269,18 @@ typedef struct { #define ATOMIC_FLAG_INIT { ATOMIC_VAR_INIT(false) } -static inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag * _Nonnull __object, memory_order __order) { +static __inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag * _Nonnull __object, memory_order __order) { return (atomic_exchange_explicit(&__object->__flag, 1, __order)); } -static inline void atomic_flag_clear_explicit(volatile atomic_flag * _Nonnull __object, memory_order __order) { +static __inline void atomic_flag_clear_explicit(volatile atomic_flag * _Nonnull __object, memory_order __order) { atomic_store_explicit(&__object->__flag, 0, __order); } -static inline bool atomic_flag_test_and_set(volatile atomic_flag * _Nonnull __object) { +static __inline bool atomic_flag_test_and_set(volatile atomic_flag * _Nonnull __object) { return (atomic_flag_test_and_set_explicit(__object, memory_order_seq_cst)); } -static inline void atomic_flag_clear(volatile atomic_flag * _Nonnull __object) { +static __inline void atomic_flag_clear(volatile atomic_flag * _Nonnull __object) { atomic_flag_clear_explicit(__object, memory_order_seq_cst); } diff --git a/libc/include/bits/swab.h b/libc/include/bits/swab.h index ebb7c7406..9591c2ede 100644 --- a/libc/include/bits/swab.h +++ b/libc/include/bits/swab.h @@ -33,7 +33,7 @@ #include <sys/types.h> #if !defined(__BIONIC_SWAB_INLINE) -#define __BIONIC_SWAB_INLINE static inline +#define __BIONIC_SWAB_INLINE static __inline #endif __BEGIN_DECLS diff --git a/libc/include/bits/termios_inlines.h b/libc/include/bits/termios_inlines.h index 702f43346..a884b595f 100644 --- a/libc/include/bits/termios_inlines.h +++ b/libc/include/bits/termios_inlines.h @@ -37,7 +37,7 @@ #include <linux/termios.h> #if !defined(__BIONIC_TERMIOS_INLINE) -#define __BIONIC_TERMIOS_INLINE static inline +#define __BIONIC_TERMIOS_INLINE static __inline #endif __BEGIN_DECLS @@ -45,7 +45,7 @@ __BEGIN_DECLS // Supporting separate input and output speeds would require an ABI // change for `struct termios`. -static inline speed_t cfgetspeed(const struct termios* _Nonnull s) { +static __inline speed_t cfgetspeed(const struct termios* _Nonnull s) { return __BIONIC_CAST(static_cast, speed_t, s->c_cflag & CBAUD); } diff --git a/libc/include/bits/termios_winsize_inlines.h b/libc/include/bits/termios_winsize_inlines.h index 0d188e75e..ae246e401 100644 --- a/libc/include/bits/termios_winsize_inlines.h +++ b/libc/include/bits/termios_winsize_inlines.h @@ -36,7 +36,7 @@ #include <linux/termios.h> #if !defined(__BIONIC_TERMIOS_WINSIZE_INLINE) -#define __BIONIC_TERMIOS_WINSIZE_INLINE static inline +#define __BIONIC_TERMIOS_WINSIZE_INLINE static __inline #endif __BEGIN_DECLS diff --git a/libc/include/bits/threads_inlines.h b/libc/include/bits/threads_inlines.h index 074e1ca98..5878e0acc 100644 --- a/libc/include/bits/threads_inlines.h +++ b/libc/include/bits/threads_inlines.h @@ -38,7 +38,7 @@ __BEGIN_DECLS -static inline int __bionic_thrd_error(int __pthread_code) { +static __inline int __bionic_thrd_error(int __pthread_code) { switch (__pthread_code) { case 0: return 0; case ENOMEM: return thrd_nomem; diff --git a/libc/include/ctype.h b/libc/include/ctype.h index 5cad412d6..c15ee5618 100644 --- a/libc/include/ctype.h +++ b/libc/include/ctype.h @@ -42,7 +42,7 @@ * also provide actual symbols for any caller that needs them. */ #if !defined(__BIONIC_CTYPE_INLINE) -#define __BIONIC_CTYPE_INLINE static inline +#define __BIONIC_CTYPE_INLINE static __inline #endif /** Internal implementation detail. Do not use. */ diff --git a/libc/include/link.h b/libc/include/link.h index 33fea49fc..ee1fc42ea 100644 --- a/libc/include/link.h +++ b/libc/include/link.h @@ -25,8 +25,13 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ -#ifndef _LINK_H_ -#define _LINK_H_ + +#pragma once + +/** + * @file link.h + * @brief Extra dynamic linker functionality (see also <dlfcn.h>). + */ #include <stdint.h> #include <sys/cdefs.h> @@ -37,32 +42,80 @@ __BEGIN_DECLS #if defined(__LP64__) +/** Convenience macro to get the appropriate 32-bit or 64-bit <elf.h> type for the caller's bitness. */ #define ElfW(type) Elf64_ ## type #else +/** Convenience macro to get the appropriate 32-bit or 64-bit <elf.h> type for the caller's bitness. */ #define ElfW(type) Elf32_ ## type #endif +/** + * Information passed by dl_iterate_phdr() to the callback. + */ struct dl_phdr_info { + /** The address of the shared object. */ ElfW(Addr) dlpi_addr; + /** The name of the shared object. */ const char* _Nullable dlpi_name; + /** Pointer to the shared object's program headers. */ const ElfW(Phdr)* _Nullable dlpi_phdr; + /** Number of program headers pointed to by `dlpi_phdr`. */ ElfW(Half) dlpi_phnum; - // These fields were added in Android R. + /** + * The total number of library load events at the time dl_iterate_phdr() was + * called. + * + * This field is only available since API level 30; you can use the size + * passed to the callback to determine whether you have the full struct, + * or just the fields up to and including `dlpi_phnum`. + */ unsigned long long dlpi_adds; + /** + * The total number of library unload events at the time dl_iterate_phdr() was + * called. + * + * This field is only available since API level 30; you can use the size + * passed to the callback to determine whether you have the full struct, + * or just the fields up to and including `dlpi_phnum`. + */ unsigned long long dlpi_subs; + /** + * The module ID for TLS relocations in this shared object. + * + * This field is only available since API level 30; you can use the size + * passed to the callback to determine whether you have the full struct, + * or just the fields up to and including `dlpi_phnum`. + */ size_t dlpi_tls_modid; + /** + * The caller's TLS data for this shared object. + * + * This field is only available since API level 30; you can use the size + * passed to the callback to determine whether you have the full struct, + * or just the fields up to and including `dlpi_phnum`. + */ void* _Nullable dlpi_tls_data; }; -int dl_iterate_phdr(int (* _Nonnull __callback)(struct dl_phdr_info* _Nonnull, size_t, void* _Nullable), void* _Nullable __data); +/** + * [dl_iterate_phdr(3)](http://man7.org/linux/man-pages/man3/dl_iterate_phdr.3.html) + * calls the given callback once for every loaded shared object. The size + * argument to the callback lets you determine whether you have a smaller + * `dl_phdr_info` from before API level 30, or the newer full one. + * The data argument to the callback is whatever you pass as the data argument + * to dl_iterate_phdr(). + * + * Returns the value returned by the final call to the callback. + */ +int dl_iterate_phdr(int (* _Nonnull __callback)(struct dl_phdr_info* _Nonnull __info, size_t __size, void* _Nullable __data), void* _Nullable __data); #ifdef __arm__ typedef uintptr_t _Unwind_Ptr; _Unwind_Ptr dl_unwind_find_exidx(_Unwind_Ptr, int* _Nonnull); #endif -/* Used by the dynamic linker to communicate with the debugger. */ +/** Used by the dynamic linker to communicate with the debugger. */ struct link_map { ElfW(Addr) l_addr; char* _Nullable l_name; @@ -71,7 +124,7 @@ struct link_map { struct link_map* _Nullable l_prev; }; -/* Used by the dynamic linker to communicate with the debugger. */ +/** Used by the dynamic linker to communicate with the debugger. */ struct r_debug { int32_t r_version; struct link_map* _Nullable r_map; @@ -85,5 +138,3 @@ struct r_debug { }; __END_DECLS - -#endif diff --git a/libc/include/strings.h b/libc/include/strings.h index 6ec3bdf58..2f4f7641a 100644 --- a/libc/include/strings.h +++ b/libc/include/strings.h @@ -50,7 +50,7 @@ #include <bits/strcasecmp.h> #if !defined(__BIONIC_STRINGS_INLINE) -#define __BIONIC_STRINGS_INLINE static inline +#define __BIONIC_STRINGS_INLINE static __inline #endif #undef ffs @@ -61,13 +61,13 @@ __BEGIN_DECLS /** Deprecated. Use memmove() instead. */ #define bcopy(b1, b2, len) __bionic_bcopy((b1), (b2), (len)) -static inline __always_inline void __bionic_bcopy(const void* _Nonnull b1, void* _Nonnull b2, size_t len) { +static __inline__ __always_inline void __bionic_bcopy(const void* _Nonnull b1, void* _Nonnull b2, size_t len) { __builtin_memmove(b2, b1, len); } /** Deprecated. Use memset() instead. */ #define bzero(b, len) __bionic_bzero((b), (len)) -static inline __always_inline void __bionic_bzero(void* _Nonnull b, size_t len) { +static __inline__ __always_inline void __bionic_bzero(void* _Nonnull b, size_t len) { __builtin_memset(b, 0, len); } diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h index 3218d1554..7625d3886 100644 --- a/libc/include/sys/cdefs.h +++ b/libc/include/sys/cdefs.h @@ -260,7 +260,7 @@ * them available externally. FORTIFY'ed functions try to be as close to possible as 'invisible'; * having stack protectors detracts from that (b/182948263). */ -# define __BIONIC_FORTIFY_INLINE static inline __attribute__((__no_stack_protector__)) \ +# define __BIONIC_FORTIFY_INLINE static __inline__ __attribute__((__no_stack_protector__)) \ __always_inline __VERSIONER_FORTIFY_INLINE /* * We should use __BIONIC_FORTIFY_VARIADIC instead of __BIONIC_FORTIFY_INLINE @@ -268,7 +268,7 @@ * The __always_inline attribute is useless, misleading, and could trigger * clang compiler bug to incorrectly inline variadic functions. */ -# define __BIONIC_FORTIFY_VARIADIC static inline +# define __BIONIC_FORTIFY_VARIADIC static __inline__ /* Error functions don't have bodies, so they can just be static. */ # define __BIONIC_ERROR_FUNCTION_VISIBILITY static __attribute__((__unused__)) #else diff --git a/libc/include/sys/system_properties.h b/libc/include/sys/system_properties.h index dc869da62..ae94db56c 100644 --- a/libc/include/sys/system_properties.h +++ b/libc/include/sys/system_properties.h @@ -26,8 +26,12 @@ * SUCH DAMAGE. */ -#ifndef _INCLUDE_SYS_SYSTEM_PROPERTIES_H -#define _INCLUDE_SYS_SYSTEM_PROPERTIES_H +#pragma once + +/** + * @file system_properties.h + * @brief System properties. + */ #include <sys/cdefs.h> #include <stdbool.h> @@ -36,39 +40,53 @@ __BEGIN_DECLS +/** An opaque structure representing a system property. */ typedef struct prop_info prop_info; +/** + * The limit on the length of a property value. + * (See PROP_NAME_MAX for property names.) + */ #define PROP_VALUE_MAX 92 -/* +/** * Sets system property `name` to `value`, creating the system property if it doesn't already exist. + * + * Returns 0 on success, or -1 on failure. */ int __system_property_set(const char* _Nonnull __name, const char* _Nonnull __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. + * 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. + * Property lookup is expensive, so it can be useful to cache the result of this + * function rather than using __system_property_get(). */ const prop_info* _Nullable __system_property_find(const char* _Nonnull __name); -/* - * Calls `callback` with a consistent trio of name, value, and serial number for property `pi`. +/** + * Calls `callback` with a consistent trio of name, value, and serial number + * for property `pi`. + * + * Available since API level 26. */ void __system_property_read_callback(const prop_info* _Nonnull __pi, void (* _Nonnull __callback)(void* _Nullable __cookie, const char* _Nonnull __name, const char* _Nonnull __value, uint32_t __serial), void* _Nullable __cookie) __INTRODUCED_IN(26); -/* +/** * Passes a `prop_info` for each system property to the provided - * callback. Use __system_property_read_callback() to read the value. + * callback. Use __system_property_read_callback() to read the value of + * any of the properties. * * This method is for inspecting and debugging the property system, and not generally useful. + * + * Returns 0 on success, or -1 on failure. */ int __system_property_foreach(void (* _Nonnull __callback)(const prop_info* _Nonnull __pi, void* _Nullable __cookie), void* _Nullable __cookie); -/* +/** * Waits for the specific system property identified by `pi` to be updated * past `old_serial`. Waits no longer than `relative_timeout`, or forever * if `relative_timeout` is null. @@ -79,20 +97,24 @@ int __system_property_foreach(void (* _Nonnull __callback)(const prop_info* _Non * * Returns true and updates `*new_serial_ptr` on success, or false if the call * timed out. + * + * Available since API level 26. */ struct timespec; bool __system_property_wait(const prop_info* _Nullable __pi, uint32_t __old_serial, uint32_t* _Nonnull __new_serial_ptr, const struct timespec* _Nullable __relative_timeout) __INTRODUCED_IN(26); -/* Deprecated. In Android O and above, there's no limit on property name length. */ +/** + * Deprecated: there's no limit on the length of a property name since + * API level 26, though the limit on property values (PROP_VALUE_MAX) remains. + */ #define PROP_NAME_MAX 32 -/* Deprecated. Use __system_property_read_callback instead. */ + +/** Deprecated. Use __system_property_read_callback() instead. */ int __system_property_read(const prop_info* _Nonnull __pi, char* _Nullable __name, char* _Nonnull __value); -/* Deprecated. Use __system_property_read_callback instead. */ +/** Deprecated. Use __system_property_read_callback() instead. */ int __system_property_get(const char* _Nonnull __name, char* _Nonnull __value); -/* Deprecated. Use __system_property_foreach instead. */ +/** Deprecated. Use __system_property_foreach() instead. */ const prop_info* _Nullable __system_property_find_nth(unsigned __n); __END_DECLS - -#endif diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py index 0fd6e46f9..08b786ac5 100755 --- a/libc/kernel/tools/cpp.py +++ b/libc/kernel/tools/cpp.py @@ -2345,11 +2345,11 @@ struct something_s { def test_function_keep_attribute_structs(self): text = """\ -static inline struct some_struct1 * function(struct some_struct2 * e) { +static __inline__ struct some_struct1 * function(struct some_struct2 * e) { } """ expected = """\ -static inline struct some_struct1 * function(struct some_struct2 * e) { +static __inline__ struct some_struct1 * function(struct some_struct2 * e) { } """ self.assertEqual(self.parse(text, set(["function"])), expected) diff --git a/libc/platform/bionic/malloc.h b/libc/platform/bionic/malloc.h index ffc6d4a43..da85cf526 100644 --- a/libc/platform/bionic/malloc.h +++ b/libc/platform/bionic/malloc.h @@ -130,36 +130,55 @@ typedef struct { // Worth noting, the "libc.debug.gwp_asan.*.app_default" sysprops *do not* // apply to system apps. They use the "libc.debug.gwp_asan.*.system_default" // sysprops. - enum Action { - // Enable GWP-ASan. This is used by apps that have `gwpAsanMode=always` in - // the manifest. - TURN_ON_FOR_APP, - // Enable GWP-ASan, but only a small percentage of the time. This is used by - // system processes and system apps, and we use a lottery to determine which - // processes have GWP-ASan enabled. This allows us to mitigate system-wide - // memory overhead concerns, as each GWP-ASan enabled process uses ~70KiB of - // extra memory. - TURN_ON_WITH_SAMPLING, - // Don't enable GWP-ASan, unless overwritten by a system property or - // environment variable. This is used by apps that have `gwpAsanMode=never` - // in the manifest. Prior to Android 14, this also was used by non-system - // apps that didn't specify a `gwpAsanMode` in their manifest. - DONT_TURN_ON_UNLESS_OVERRIDDEN, - // Enable GWP-ASan, but only a small percentage of the time, and enable it - // in the non-crashing ("recoverable") mode. In Android 14, this is used by - // apps that don't specify `gwpAsanMode` (or use `gwpAsanMode=default`) in - // their manifest. GWP-ASan will detect heap memory safety bugs in this - // mode, and bug reports will be created by debuggerd, however the process - // will recover and continue to function as if the memory safety bug wasn't - // detected. + // + // In recoverable mode, GWP-ASan will detect heap memory safety bugs, and bug + // reports will be created by debuggerd, however the process will recover and + // continue to function as if the memory safety bug wasn't detected. This + // prevents any user-visible impact as apps and processes don't crash, and + // probably saves us some CPU time in restarting the process. + // + // Process sampling enables GWP-ASan, but only a small percentage of the time + // (~1%). This helps mitigate any recurring high-frequency problems in certain + // processes, as it's highly likely the next restart of said process won't + // have GWP-ASan. In addition, for system processes and system apps, this + // allows us to mitigate system-wide memory overhead concerns, as each + // GWP-ASan enabled process uses ~70KiB of extra memory. + enum Mode { + // Used by default for apps, or by those that have an explicit + // `gwpAsanMode=default` in the manifest. + // + // Result: + // - Android 13 and before: GWP-ASan is not enabled. + // - Android 14 and after: Enables GWP-ASan with process sampling in + // recoverable mode. + APP_MANIFEST_DEFAULT = 3, + // This is used by apps that have `gwpAsanMode=always` in the manifest. + // + // Result: + // - Android 14 and before: Enables GWP-ASan in non-recoverable mode, + // without process sampling. + // - Android 15 and after: Enables GWP-ASan in recoverable mode, without + // process sampling. + APP_MANIFEST_ALWAYS = 0, + // This is used by apps that have `gwpAsanMode=never` in the manifest. + // + // Result: + // - GWP-ASan is not enabled, unless it's force-enabled by a system + // property or environment variable. + APP_MANIFEST_NEVER = 2, + // Used by system processes and system apps. // - // In Android 15, this is the same as TURN_ON_WITH_SAMPLING, as GWP-ASan is - // only ever used in non-crashing mode (even for platform executables and - // system apps). - TURN_ON_FOR_APP_SAMPLED_NON_CRASHING, + // Result: + // - Android 14 and before: Enables GWP-ASan with process sampling in + // non-recoverable mode. + // - Android 15 and after: Enables GWP-ASan with process sampling in + // recoverable mode. + SYSTEM_PROCESS_OR_SYSTEM_APP = 1, + // Next enum value = 4. Numbered non-sequentially above to preserve ABI + // stability, but now ordered more logically. }; - Action desire = DONT_TURN_ON_UNLESS_OVERRIDDEN; + Mode mode = APP_MANIFEST_NEVER; } android_mallopt_gwp_asan_options_t; #pragma clang diagnostic pop // Manipulates bionic-specific handling of memory allocation APIs such as diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp index 089ecebf9..e27fd9175 100644 --- a/linker/linker_main.cpp +++ b/linker/linker_main.cpp @@ -422,20 +422,11 @@ static ElfW(Addr) linker_main(KernelArgumentBlock& args, const char* exe_to_load ElfW(Ehdr)* elf_hdr = reinterpret_cast<ElfW(Ehdr)*>(si->base); - // We haven't supported non-PIE since Lollipop for security reasons. + // For security reasons we dropped non-PIE support in API level 21, + // and the NDK no longer supports earlier API levels. if (elf_hdr->e_type != ET_DYN) { - // We don't use async_safe_fatal here because we don't want a tombstone: - // even after several years we still find ourselves on app compatibility - // investigations because some app's trying to launch an executable that - // hasn't worked in at least three years, and we've "helpfully" dropped a - // tombstone for them. The tombstone never provided any detail relevant to - // fixing the problem anyway, and the utility of drawing extra attention - // to the problem is non-existent at this late date. - async_safe_format_fd(STDERR_FILENO, - "\"%s\": error: Android 5.0 and later only support " - "position-independent executables (-fPIE).\n", - g_argv[0]); - _exit(EXIT_FAILURE); + __linker_error("error: %s: Android only supports position-independent " + "executables (-fPIE)\n", exe_info.path.c_str()); } // Use LD_LIBRARY_PATH and LD_PRELOAD (but only if we aren't setuid/setgid). diff --git a/linker/linker_phdr.cpp b/linker/linker_phdr.cpp index fa712a10a..b9229caef 100644 --- a/linker/linker_phdr.cpp +++ b/linker/linker_phdr.cpp @@ -298,7 +298,6 @@ bool ElfReader::VerifyElfHeader() { } if (header_.e_shentsize != sizeof(ElfW(Shdr))) { - // Fail if app is targeting Android O or above if (get_application_target_sdk_version() >= 26) { DL_ERR_AND_LOG("\"%s\" has unsupported e_shentsize: 0x%x (expected 0x%zx)", name_.c_str(), header_.e_shentsize, sizeof(ElfW(Shdr))); @@ -312,12 +311,10 @@ bool ElfReader::VerifyElfHeader() { } if (header_.e_shstrndx == 0) { - // Fail if app is targeting Android O or above if (get_application_target_sdk_version() >= 26) { DL_ERR_AND_LOG("\"%s\" has invalid e_shstrndx", name_.c_str()); return false; } - DL_WARN_documented_change(26, "invalid-elf-header_section-headers-enforced-for-api-level-26", "\"%s\" has invalid e_shstrndx", name_.c_str()); diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp index bd17b82fa..a5916d318 100644 --- a/tests/malloc_test.cpp +++ b/tests/malloc_test.cpp @@ -1412,15 +1412,15 @@ TEST(android_mallopt, set_allocation_limit_multiple_threads) { } #if defined(__BIONIC__) -using Action = android_mallopt_gwp_asan_options_t::Action; +using Mode = android_mallopt_gwp_asan_options_t::Mode; TEST(android_mallopt, DISABLED_multiple_enable_gwp_asan) { android_mallopt_gwp_asan_options_t options; options.program_name = ""; // Don't infer GWP-ASan options from sysprops. - options.desire = Action::DONT_TURN_ON_UNLESS_OVERRIDDEN; + options.mode = Mode::APP_MANIFEST_NEVER; // GWP-ASan should already be enabled. Trying to enable or disable it should // always pass. ASSERT_TRUE(android_mallopt(M_INITIALIZE_GWP_ASAN, &options, sizeof(options))); - options.desire = Action::TURN_ON_WITH_SAMPLING; + options.mode = Mode::APP_MANIFEST_DEFAULT; ASSERT_TRUE(android_mallopt(M_INITIALIZE_GWP_ASAN, &options, sizeof(options))); } #endif // defined(__BIONIC__) diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp index 6ae8bfd3f..0de0a01ba 100644 --- a/tests/setjmp_test.cpp +++ b/tests/setjmp_test.cpp @@ -174,31 +174,23 @@ TEST(setjmp, sigsetjmp_1_signal_mask) { } } -#if defined(__aarch64__) +#if defined(__arm__) +#define SET_FREG(n, v) asm volatile("vmov.f64 d"#n ", #"#v : : : "d"#n) +#define GET_FREG(n) ({ double _r; asm volatile("fcpyd %P0, d"#n : "=w"(_r) : :); _r;}) +#define CLEAR_FREG(n) asm volatile("vmov.i64 d"#n ", #0x0" : : : "d"#n) +#elif defined(__aarch64__) #define SET_FREG(n, v) asm volatile("fmov d"#n ", "#v : : : "d"#n) +#define GET_FREG(n) ({ double _r; asm volatile("fmov %0, d"#n : "=r"(_r) : :); _r; }) #define CLEAR_FREG(n) asm volatile("fmov d"#n ", xzr" : : : "d"#n) +#endif + +#if defined(__arm__) || defined(__aarch64__) #define SET_FREGS \ SET_FREG(8, 8.0); SET_FREG(9, 9.0); SET_FREG(10, 10.0); SET_FREG(11, 11.0); \ SET_FREG(12, 12.0); SET_FREG(13, 13.0); SET_FREG(14, 14.0); SET_FREG(15, 15.0); #define CLEAR_FREGS \ CLEAR_FREG(8); CLEAR_FREG(9); CLEAR_FREG(10); CLEAR_FREG(11); \ CLEAR_FREG(12); CLEAR_FREG(13); CLEAR_FREG(14); CLEAR_FREG(15); -#define GET_FREG(n) ({ double _r; asm volatile("fmov %0, d"#n : "=r"(_r) : :); _r; }) -#define CHECK_FREGS \ - EXPECT_EQ(8.0, GET_FREG(8)); EXPECT_EQ(9.0, GET_FREG(9)); \ - EXPECT_EQ(10.0, GET_FREG(10)); EXPECT_EQ(11.0, GET_FREG(11)); \ - EXPECT_EQ(12.0, GET_FREG(12)); EXPECT_EQ(13.0, GET_FREG(13)); \ - EXPECT_EQ(14.0, GET_FREG(14)); EXPECT_EQ(15.0, GET_FREG(15)); -#elif defined(__arm__) -#define SET_FREG(n, v) \ - ({ const double _v{v}; asm volatile("fcpyd d"#n ", %P0" : : "w"(_v) : "d"#n); }) -#define SET_FREGS \ - SET_FREG(8, 8); SET_FREG(9, 9); SET_FREG(10, 10); SET_FREG(11, 11); \ - SET_FREG(12, 12); SET_FREG(13, 13); SET_FREG(14, 14); SET_FREG(15, 15); -#define CLEAR_FREGS \ - SET_FREG(8, 0); SET_FREG(9, 0); SET_FREG(10, 0); SET_FREG(11, 0); \ - SET_FREG(12, 0); SET_FREG(13, 0); SET_FREG(14, 0); SET_FREG(15, 0); -#define GET_FREG(n) ({ double _r; asm volatile("fcpyd %P0, d"#n : "=w"(_r) : :); _r;}) #define CHECK_FREGS \ EXPECT_EQ(8.0, GET_FREG(8)); EXPECT_EQ(9.0, GET_FREG(9)); \ EXPECT_EQ(10.0, GET_FREG(10)); EXPECT_EQ(11.0, GET_FREG(11)); \ diff --git a/tests/stack_protector_test.cpp b/tests/stack_protector_test.cpp index c4be78c72..aea791c81 100644 --- a/tests/stack_protector_test.cpp +++ b/tests/stack_protector_test.cpp @@ -136,7 +136,7 @@ TEST_F(stack_protector_DeathTest, modify_stack_protector) { if (stack_mte_enabled()) { GTEST_SKIP() << "Stack MTE is enabled, stack protector is not available"; } else if (hwasan_enabled()) { - ASSERT_EXIT(modify_stack_protector_test(), testing::KilledBySignal(SIGABRT), "tag-mismatch"); + GTEST_SKIP() << "HWASan is enabled, stack protector is not testable"; } else { ASSERT_EXIT(modify_stack_protector_test(), testing::KilledBySignal(SIGABRT), "stack corruption detected"); |