diff options
author | Scott Lobdell <slobdell@google.com> | 2021-02-05 18:00:54 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2021-02-05 18:00:54 +0000 |
commit | c800319ca06bb624b67d33741336fa42e9dd2667 (patch) | |
tree | cae72caa0322a7ecec0fecf813ae0d7c14ffd980 /libc | |
parent | ea1e0a27d3fb999f3015dfd7b42d9ba699284f10 (diff) | |
parent | 3cfe8f2ca3589184c6329a6fa4fadf7a5ebaa0d4 (diff) |
Merge "Merge SP1A.210122.003 Change-Id: I38a0c2cf0aed3762aafe4b1fa8a69dd03106fa39" into s-keystone-qcom-dev
Diffstat (limited to 'libc')
39 files changed, 645 insertions, 256 deletions
diff --git a/libc/Android.bp b/libc/Android.bp index 6bb197446..5340c6f8a 100644 --- a/libc/Android.bp +++ b/libc/Android.bp @@ -93,9 +93,6 @@ cc_defaults { ldflags: ["-Wl,-z,muldefs"], product_variables: { - experimental_mte: { - cflags: ["-DANDROID_EXPERIMENTAL_MTE"], - }, malloc_zero_contents: { cflags: ["-DSCUDO_ZERO_CONTENTS"], }, @@ -269,6 +266,7 @@ cc_library_static { "-Wno-unused-parameter", "-include netbsd-compat.h", "-Wframe-larger-than=66000", + "-include private/bsd_sys_param.h", ], local_include_dirs: [ @@ -579,6 +577,7 @@ cc_library_static { ], local_include_dirs: [ + "private", "upstream-openbsd/android/include/", "upstream-openbsd/lib/libc/include/", "upstream-openbsd/lib/libc/gdtoa/", @@ -1653,6 +1652,7 @@ cc_library { "gwp_asan", "libc_init_dynamic", "libc_common_shared", + "libunwind-exported", ], }, @@ -1694,8 +1694,6 @@ cc_library { srcs: [":libc_sources_shared_arm"], // special for arm cflags: ["-DCRT_LEGACY_WORKAROUND"], - - whole_static_libs: [ "libunwind_llvm" ], }, // Arm 32 bit does not produce complete exidx unwind information @@ -1714,10 +1712,6 @@ cc_library { strip: { keep_symbols: true, }, - - shared: { - whole_static_libs: [ "libgcc_stripped" ], - }, }, x86: { // TODO: This is to work around b/24465209. Remove after root cause is fixed. @@ -1731,10 +1725,6 @@ cc_library { strip: { keep_symbols: true, }, - - shared: { - whole_static_libs: [ "libgcc_stripped" ], - }, }, x86_64: { version_script: ":libc.x86_64.map", @@ -1744,10 +1734,6 @@ cc_library { strip: { keep_symbols: true, }, - - shared: { - whole_static_libs: [ "libgcc_stripped" ], - }, }, }, @@ -2122,6 +2108,8 @@ cc_object { local_include_dirs: ["include"], srcs: ["arch-common/bionic/crtbegin.c"], defaults: ["crt_defaults"], + // When using libc.a, we're using the latest library regardless of target API level. + min_sdk_version: "current", } cc_object { @@ -2132,6 +2120,8 @@ cc_object { "crtbrand", ], defaults: ["crt_defaults"], + // When using libc.a, we're using the latest library regardless of target API level. + min_sdk_version: "current", } cc_object { @@ -2169,6 +2159,28 @@ cc_object { defaults: ["crt_defaults"], } +cc_library_static { + name: "note_memtag_heap_async", + arch: { + arm64: { + srcs: ["arch-arm64/bionic/note_memtag_heap_async.S"], + } + }, + + defaults: ["crt_defaults"], +} + +cc_library_static { + name: "note_memtag_heap_sync", + arch: { + arm64: { + srcs: ["arch-arm64/bionic/note_memtag_heap_sync.S"], + } + }, + + defaults: ["crt_defaults"], +} + // ======================================================== // NDK headers. // ======================================================== @@ -2249,7 +2261,6 @@ ndk_headers { ndk_library { name: "libc", - native_bridge_supported: true, symbol_file: "libc.map.txt", first_version: "9", } diff --git a/libc/NOTICE b/libc/NOTICE index f7d73d8f8..7041e5c3c 100644 --- a/libc/NOTICE +++ b/libc/NOTICE @@ -1083,6 +1083,34 @@ SUCH DAMAGE. ------------------------------------------------------------------- +Copyright (C) 2021 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) 1980, 1983, 1988, 1993 The Regents of the University of California. All rights reserved. diff --git a/libc/arch-arm/bionic/kuser_helper_on.S b/libc/arch-arm/bionic/kuser_helper_on.S index cff2073b7..2a1d86dde 100644 --- a/libc/arch-arm/bionic/kuser_helper_on.S +++ b/libc/arch-arm/bionic/kuser_helper_on.S @@ -26,13 +26,15 @@ * SUCH DAMAGE. */ +#include <private/bionic_asm_note.h> + .section .note.android.kuser_helper_on,"a",%note .balign 4 .type kuser_helper_on, %object kuser_helper_on: .long 2f-1f // int32_t namesz .long 3f-2f // int32_t descsz - .long 3 // int32_t type + .long NT_TYPE_KUSER // int32_t type 1:.ascii "Android\0" // char name[] 2:.long 1 // int32_t on 3: diff --git a/libc/arch-arm64/bionic/note_memtag_heap_async.S b/libc/arch-arm64/bionic/note_memtag_heap_async.S new file mode 100644 index 000000000..208115c13 --- /dev/null +++ b/libc/arch-arm64/bionic/note_memtag_heap_async.S @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021 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. + */ + +#include <private/bionic_asm.h> +#include <private/bionic_asm_note.h> + +__bionic_asm_custom_note_gnu_section() + + .section ".note.android.memtag", "a", %note + .p2align 2 + .long 1f - 0f // int32_t namesz + .long 3f - 2f // int32_t descsz + .long NT_TYPE_MEMTAG // int32_t type +0: + .asciz "Android" // char name[] +1: + .p2align 2 +2: + .long (NT_MEMTAG_LEVEL_ASYNC | NT_MEMTAG_HEAP) // value +3: + .p2align 2 diff --git a/libc/arch-arm64/bionic/note_memtag_heap_sync.S b/libc/arch-arm64/bionic/note_memtag_heap_sync.S new file mode 100644 index 000000000..d71ad020e --- /dev/null +++ b/libc/arch-arm64/bionic/note_memtag_heap_sync.S @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2021 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. + */ + +#include <private/bionic_asm.h> +#include <private/bionic_asm_note.h> + +__bionic_asm_custom_note_gnu_section() + + .section ".note.android.memtag", "a", %note + .p2align 2 + .long 1f - 0f // int32_t namesz + .long 3f - 2f // int32_t descsz + .long NT_TYPE_MEMTAG // int32_t type +0: + .asciz "Android" // char name[] +1: + .p2align 2 +2: + .long (NT_MEMTAG_LEVEL_SYNC | NT_MEMTAG_HEAP) // value +3: + .p2align 2 diff --git a/libc/arch-arm64/dynamic_function_dispatch.cpp b/libc/arch-arm64/dynamic_function_dispatch.cpp index 0fd331f79..83e5ca4da 100644 --- a/libc/arch-arm64/dynamic_function_dispatch.cpp +++ b/libc/arch-arm64/dynamic_function_dispatch.cpp @@ -26,25 +26,15 @@ * SUCH DAMAGE. */ -#include <platform/bionic/mte_kernel.h> #include <private/bionic_ifuncs.h> #include <stddef.h> #include <sys/auxv.h> extern "C" { -static bool supports_mte(unsigned long hwcap2) { -#ifdef ANDROID_EXPERIMENTAL_MTE - return hwcap2 & HWCAP2_MTE; -#else - (void)hwcap2; - return false; -#endif -} - typedef void* memchr_func(const void*, int, size_t); DEFINE_IFUNC_FOR(memchr) { - if (supports_mte(arg->_hwcap2)) { + if (arg->_hwcap2 & HWCAP2_MTE) { RETURN_FUNC(memchr_func, __memchr_aarch64_mte); } else { RETURN_FUNC(memchr_func, __memchr_aarch64); @@ -53,7 +43,7 @@ DEFINE_IFUNC_FOR(memchr) { typedef int stpcpy_func(char*, const char*); DEFINE_IFUNC_FOR(stpcpy) { - if (supports_mte(arg->_hwcap2)) { + if (arg->_hwcap2 & HWCAP2_MTE) { RETURN_FUNC(stpcpy_func, __stpcpy_aarch64_mte); } else { RETURN_FUNC(stpcpy_func, __stpcpy_aarch64); @@ -62,7 +52,7 @@ DEFINE_IFUNC_FOR(stpcpy) { typedef char* strchr_func(const char*, int); DEFINE_IFUNC_FOR(strchr) { - if (supports_mte(arg->_hwcap2)) { + if (arg->_hwcap2 & HWCAP2_MTE) { RETURN_FUNC(strchr_func, __strchr_aarch64_mte); } else { RETURN_FUNC(strchr_func, __strchr_aarch64); @@ -71,7 +61,7 @@ DEFINE_IFUNC_FOR(strchr) { typedef char* strchrnul_func(const char*, int); DEFINE_IFUNC_FOR(strchrnul) { - if (supports_mte(arg->_hwcap2)) { + if (arg->_hwcap2 & HWCAP2_MTE) { RETURN_FUNC(strchrnul_func, __strchrnul_aarch64_mte); } else { RETURN_FUNC(strchrnul_func, __strchrnul_aarch64); @@ -80,7 +70,7 @@ DEFINE_IFUNC_FOR(strchrnul) { typedef int strcmp_func(const char*, const char*); DEFINE_IFUNC_FOR(strcmp) { - if (supports_mte(arg->_hwcap2)) { + if (arg->_hwcap2 & HWCAP2_MTE) { RETURN_FUNC(strcmp_func, __strcmp_aarch64_mte); } else { RETURN_FUNC(strcmp_func, __strcmp_aarch64); @@ -89,7 +79,7 @@ DEFINE_IFUNC_FOR(strcmp) { typedef int strcpy_func(char*, const char*); DEFINE_IFUNC_FOR(strcpy) { - if (supports_mte(arg->_hwcap2)) { + if (arg->_hwcap2 & HWCAP2_MTE) { RETURN_FUNC(strcpy_func, __strcpy_aarch64_mte); } else { RETURN_FUNC(strcpy_func, __strcpy_aarch64); @@ -98,7 +88,7 @@ DEFINE_IFUNC_FOR(strcpy) { typedef size_t strlen_func(const char*); DEFINE_IFUNC_FOR(strlen) { - if (supports_mte(arg->_hwcap2)) { + if (arg->_hwcap2 & HWCAP2_MTE) { RETURN_FUNC(strlen_func, __strlen_aarch64_mte); } else { RETURN_FUNC(strlen_func, __strlen_aarch64); @@ -107,7 +97,7 @@ DEFINE_IFUNC_FOR(strlen) { typedef int strncmp_func(const char*, const char*, int); DEFINE_IFUNC_FOR(strncmp) { - if (supports_mte(arg->_hwcap2)) { + if (arg->_hwcap2 & HWCAP2_MTE) { RETURN_FUNC(strncmp_func, __strncmp_aarch64_mte); } else { RETURN_FUNC(strncmp_func, __strncmp_aarch64); @@ -116,7 +106,7 @@ DEFINE_IFUNC_FOR(strncmp) { typedef char* strrchr_func(const char*, int); DEFINE_IFUNC_FOR(strrchr) { - if (supports_mte(arg->_hwcap2)) { + if (arg->_hwcap2 & HWCAP2_MTE) { RETURN_FUNC(strrchr_func, __strrchr_aarch64_mte); } else { RETURN_FUNC(strrchr_func, __strrchr_aarch64); diff --git a/libc/arch-common/bionic/crtbrand.S b/libc/arch-common/bionic/crtbrand.S index 3d80d7353..307ef2e34 100644 --- a/libc/arch-common/bionic/crtbrand.S +++ b/libc/arch-common/bionic/crtbrand.S @@ -32,13 +32,15 @@ __bionic_asm_custom_note_gnu_section() #endif +#include <private/bionic_asm_note.h> + .section .note.android.ident,"a",%note .balign 4 .type abitag, %object abitag: .long 2f-1f // int32_t namesz .long 3f-2f // int32_t descsz - .long 1 // int32_t type + .long NT_TYPE_IDENT // int32_t type #ifdef __ANDROID__ 1:.ascii "Android\0" // char name[] 2:.long PLATFORM_SDK_VERSION // int32_t android_api diff --git a/libc/bionic/bionic_appcompat.cpp b/libc/bionic/bionic_appcompat.cpp index 5b31c299d..dcca0dad5 100644 --- a/libc/bionic/bionic_appcompat.cpp +++ b/libc/bionic/bionic_appcompat.cpp @@ -88,4 +88,4 @@ int get_package_name(char* buffer, const int bufferlen) { close(file); return 0; -}
\ No newline at end of file +} diff --git a/libc/bionic/bionic_appcompat.h b/libc/bionic/bionic_appcompat.h index 1976e0b70..fd3703588 100644 --- a/libc/bionic/bionic_appcompat.h +++ b/libc/bionic/bionic_appcompat.h @@ -41,4 +41,4 @@ static inline const char* const soft_mac_getlink_allowlist[] = { int get_package_name(char* buffer, const int bufferlen); bool should_apply_soft_mac_bind_restrictions(); -bool should_apply_soft_mac_getlink_restrictions();
\ No newline at end of file +bool should_apply_soft_mac_getlink_restrictions(); diff --git a/libc/bionic/fts.c b/libc/bionic/fts.c index 8888ab18a..77b411762 100644 --- a/libc/bionic/fts.c +++ b/libc/bionic/fts.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fts.c,v 1.48 2014/11/20 04:14:15 guenther Exp $ */ +/* $OpenBSD: fts.c,v 1.60 2021/01/08 16:06:30 tb Exp $ */ /*- * Copyright (c) 1990, 1993, 1994 @@ -29,10 +29,9 @@ * SUCH DAMAGE. */ -#include <sys/param.h> +#include <sys/param.h> /* ALIGN */ #include <sys/stat.h> -#include <assert.h> #include <dirent.h> #include <errno.h> #include <fcntl.h> @@ -42,7 +41,9 @@ #include <string.h> #include <unistd.h> -static FTSENT *fts_alloc(FTS *, char *, size_t); +#define MAXIMUM(a, b) (((a) > (b)) ? (a) : (b)) + +static FTSENT *fts_alloc(FTS *, const char *, size_t); static FTSENT *fts_build(FTS *, int); static void fts_lfree(FTSENT *); static void fts_load(FTS *, FTSENT *); @@ -51,11 +52,12 @@ static void fts_padjust(FTS *, FTSENT *); static int fts_palloc(FTS *, size_t); static FTSENT *fts_sort(FTS *, FTSENT *, int); static u_short fts_stat(FTS *, FTSENT *, int, int); -static int fts_safe_changedir(FTS *, FTSENT *, int, char *); +static int fts_safe_changedir(FTS *, FTSENT *, int, const char *); -#define ALIGNBYTES (sizeof(uintptr_t) - 1) -#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES) -void* reallocarray(void*, size_t, size_t); +/* Android: OpenBSD source compatibility workarounds. */ +#include "private/bsd_sys_param.h" +#define DEF_WEAK(s) /* nothing */ +void* recallocarray(void*, size_t, size_t, size_t); #define ISDOT(a) (a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2]))) @@ -70,12 +72,22 @@ void* reallocarray(void*, size_t, size_t); #define BNAMES 2 /* fts_children, names only */ #define BREAD 3 /* fts_read */ -FTS* __fts_open(char* const* argv, int options, int (*compar)(const FTSENT**, const FTSENT**)) { +FTS * +__fts_open(char * const *argv, int options, + int (*compar)(const FTSENT **, const FTSENT **)) +{ FTS *sp; FTSENT *p, *root; int nitems; - FTSENT *parent, *tmp; - size_t len; + FTSENT *parent, *prev; + + /* Android: options check moved to __fts_open() for ftw(). */ + + /* At least one path must be specified. */ + if (*argv == NULL) { + errno = EINVAL; + return (NULL); + } /* Allocate/initialize the stream */ if ((sp = calloc(1, sizeof(FTS))) == NULL) @@ -91,7 +103,7 @@ FTS* __fts_open(char* const* argv, int options, int (*compar)(const FTSENT**, co * Start out with 1K of path space, and enough, in any case, * to hold the user's paths. */ - if (fts_palloc(sp, MAX(fts_maxarglen(argv), PATH_MAX))) + if (fts_palloc(sp, MAXIMUM(fts_maxarglen(argv), PATH_MAX))) goto mem1; /* Allocate/initialize root's parent. */ @@ -100,21 +112,15 @@ FTS* __fts_open(char* const* argv, int options, int (*compar)(const FTSENT**, co parent->fts_level = FTS_ROOTPARENTLEVEL; /* Allocate/initialize root(s). */ - for (root = NULL, nitems = 0; *argv; ++argv, ++nitems) { - /* Don't allow zero-length paths. */ - if ((len = strlen(*argv)) == 0) { - errno = ENOENT; - goto mem3; - } - - if ((p = fts_alloc(sp, *argv, len)) == NULL) + for (root = prev = NULL, nitems = 0; *argv; ++argv, ++nitems) { + if ((p = fts_alloc(sp, *argv, strlen(*argv))) == NULL) goto mem3; p->fts_level = FTS_ROOTLEVEL; p->fts_parent = parent; p->fts_accpath = p->fts_name; p->fts_info = fts_stat(sp, p, ISSET(FTS_COMFOLLOW), -1); - // For ftw/nftw we need to fail early: http://b/31152735 + // Android: for ftw/nftw we need to fail early: http://b/31152735 if ((options & FTS_FOR_FTW) != 0 && p->fts_info == FTS_NS) goto mem3; /* Command-line "." and ".." are real directories. */ @@ -131,11 +137,10 @@ FTS* __fts_open(char* const* argv, int options, int (*compar)(const FTSENT**, co } else { p->fts_link = NULL; if (root == NULL) - tmp = root = p; - else { - tmp->fts_link = p; - tmp = p; - } + root = p; + else + prev->fts_link = p; + prev = p; } } if (compar && nitems > 1) @@ -158,7 +163,8 @@ FTS* __fts_open(char* const* argv, int options, int (*compar)(const FTSENT**, co * and ".." are all fairly nasty problems. Note, if we can't get the * descriptor we run anyway, just more slowly. */ - if (!ISSET(FTS_NOCHDIR) && (sp->fts_rfd = open(".", O_RDONLY|O_CLOEXEC, 0)) < 0) + if (!ISSET(FTS_NOCHDIR) && + (sp->fts_rfd = open(".", O_RDONLY | O_CLOEXEC)) == -1) SET(FTS_NOCHDIR); if (nitems == 0) @@ -172,6 +178,7 @@ mem2: free(sp->fts_path); mem1: free(sp); return (NULL); } +DEF_WEAK(fts_open); static void fts_load(FTS *sp, FTSENT *p) @@ -221,7 +228,8 @@ fts_close(FTS *sp) rfd = ISSET(FTS_NOCHDIR) ? -1 : sp->fts_rfd; /* Free up child linked list, sort array, path buffer, stream ptr.*/ - fts_lfree(sp->fts_child); + if (sp->fts_child) + fts_lfree(sp->fts_child); free(sp->fts_array); free(sp->fts_path); free(sp); @@ -237,6 +245,7 @@ fts_close(FTS *sp) return (error); } +DEF_WEAK(fts_close); /* * Special case of "/" at the end of the path so that slashes aren't @@ -281,7 +290,8 @@ fts_read(FTS *sp) (p->fts_info == FTS_SL || p->fts_info == FTS_SLNONE)) { p->fts_info = fts_stat(sp, p, 1, -1); if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { - if ((p->fts_symfd = open(".", O_RDONLY|O_CLOEXEC, 0)) < 0) { + if ((p->fts_symfd = + open(".", O_RDONLY | O_CLOEXEC)) == -1) { p->fts_errno = errno; p->fts_info = FTS_ERR; } else @@ -370,7 +380,8 @@ next: tmp = p; if (p->fts_instr == FTS_FOLLOW) { p->fts_info = fts_stat(sp, p, 1, -1); if (p->fts_info == FTS_D && !ISSET(FTS_NOCHDIR)) { - if ((p->fts_symfd = open(".", O_RDONLY|O_CLOEXEC, 0)) < 0) { + if ((p->fts_symfd = + open(".", O_RDONLY | O_CLOEXEC)) == -1) { p->fts_errno = errno; p->fts_info = FTS_ERR; } else @@ -432,6 +443,7 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); p->fts_info = p->fts_errno ? FTS_ERR : FTS_DP; return (sp->fts_cur = p); } +DEF_WEAK(fts_read); /* * Fts_set takes the stream as an argument although it's not used in this @@ -439,7 +451,6 @@ name: t = sp->fts_path + NAPPEND(p->fts_parent); * semantics to fts using fts_set. An error return is allowed for similar * reasons. */ -/* ARGSUSED */ int fts_set(FTS *sp __unused, FTSENT *p, int instr) { @@ -451,6 +462,7 @@ fts_set(FTS *sp __unused, FTSENT *p, int instr) p->fts_instr = instr; return (0); } +DEF_WEAK(fts_set); FTSENT * fts_children(FTS *sp, int instr) @@ -489,7 +501,8 @@ fts_children(FTS *sp, int instr) return (NULL); /* Free up any previous child list. */ - fts_lfree(sp->fts_child); + if (sp->fts_child) + fts_lfree(sp->fts_child); if (instr == FTS_NAMEONLY) { SET(FTS_NAMEONLY); @@ -508,7 +521,7 @@ fts_children(FTS *sp, int instr) ISSET(FTS_NOCHDIR)) return (sp->fts_child = fts_build(sp, instr)); - if ((fd = open(".", O_RDONLY|O_CLOEXEC, 0)) < 0) + if ((fd = open(".", O_RDONLY | O_CLOEXEC)) == -1) return (NULL); sp->fts_child = fts_build(sp, instr); if (fchdir(fd)) { @@ -518,6 +531,7 @@ fts_children(FTS *sp, int instr) (void)close(fd); return (sp->fts_child); } +DEF_WEAK(fts_children); /* * This is the tricky part -- do not casually change *anything* in here. The @@ -542,9 +556,9 @@ fts_build(FTS *sp, int type) DIR *dirp; void *oldaddr; size_t len, maxlen; - int nitems, cderrno, descend, level, nlinks, nostat = 0, doadjust; + int nitems, cderrno, descend, level, nlinks, nostat, doadjust; int saved_errno; - char *cp = NULL; + char *cp; /* Set current node pointer. */ cur = sp->fts_cur; @@ -709,8 +723,7 @@ mem1: saved_errno = errno; /* Build a file name for fts_stat to stat. */ if (ISSET(FTS_NOCHDIR)) { p->fts_accpath = p->fts_path; - assert(cp && "cp should be non-null if FTS_NOCHDIR is set"); - memmove(cp, p->fts_name, p->fts_namelen + 1); // NOLINT + memmove(cp, p->fts_name, p->fts_namelen + 1); p->fts_info = fts_stat(sp, p, 0, dirfd(dirp)); } else { p->fts_accpath = p->fts_name; @@ -806,9 +819,9 @@ fts_stat(FTS *sp, FTSENT *p, int follow, int dfd) * fail, set the errno from the stat call. */ if (ISSET(FTS_LOGICAL) || follow) { - if (fstatat(dfd, path, sbp, 0) == -1) { + if (fstatat(dfd, path, sbp, 0)) { saved_errno = errno; - if (fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW) == 0) { + if (!fstatat(dfd, path, sbp, AT_SYMLINK_NOFOLLOW)) { errno = 0; return (FTS_SLNONE); } @@ -872,19 +885,19 @@ fts_sort(FTS *sp, FTSENT *head, int nitems) if (nitems > sp->fts_nitems) { struct _ftsent **a; - sp->fts_nitems = nitems + 40; if ((a = reallocarray(sp->fts_array, - sp->fts_nitems, sizeof(FTSENT *))) == NULL) { + nitems + 40, sizeof(FTSENT *))) == NULL) { free(sp->fts_array); sp->fts_array = NULL; sp->fts_nitems = 0; return (head); } + sp->fts_nitems = nitems + 40; sp->fts_array = a; } for (ap = sp->fts_array, p = head; p; p = p->fts_link) *ap++ = p; - qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar); + qsort(sp->fts_array, nitems, sizeof(FTSENT *), sp->fts_compar); for (head = *(ap = sp->fts_array); --nitems; ++ap) ap[0]->fts_link = ap[1]; ap[0]->fts_link = NULL; @@ -892,7 +905,7 @@ fts_sort(FTS *sp, FTSENT *head, int nitems) } static FTSENT * -fts_alloc(FTS *sp, char *name, size_t namelen) +fts_alloc(FTS *sp, const char *name, size_t namelen) { FTSENT *p; size_t len; @@ -954,13 +967,14 @@ fts_palloc(FTS *sp, size_t more) errno = ENAMETOOLONG; return (1); } - sp->fts_pathlen += more; - p = realloc(sp->fts_path, sp->fts_pathlen); + p = recallocarray(sp->fts_path, sp->fts_pathlen, + sp->fts_pathlen + more, 1); if (p == NULL) { free(sp->fts_path); sp->fts_path = NULL; return (1); } + sp->fts_pathlen += more; sp->fts_path = p; return (0); } @@ -1010,7 +1024,7 @@ fts_maxarglen(char * const *argv) * Assumes p->fts_dev and p->fts_ino are filled in. */ static int -fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path) +fts_safe_changedir(FTS *sp, FTSENT *p, int fd, const char *path) { int ret, oerrno, newfd; struct stat sb; @@ -1018,9 +1032,9 @@ fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path) newfd = fd; if (ISSET(FTS_NOCHDIR)) return (0); - if (fd < 0 && (newfd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC, 0)) < 0) + if (fd == -1 && (newfd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC)) == -1) return (-1); - if (fstat(newfd, &sb)) { + if (fstat(newfd, &sb) == -1) { ret = -1; goto bail; } @@ -1032,17 +1046,21 @@ fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path) ret = fchdir(newfd); bail: oerrno = errno; - if (fd < 0) + if (fd == -1) (void)close(newfd); errno = oerrno; return (ret); } -FTS* fts_open(char* const* argv, int options, int (*compar)(const FTSENT**, const FTSENT**)) { - // Options check. - if ((options & ~FTS_OPTIONMASK) != 0) { - errno = EINVAL; - return NULL; - } - return __fts_open(argv, options, compar); +FTS * +fts_open(char * const *argv, int options, + int (*compar)(const FTSENT **, const FTSENT **)) +{ + // Android needs to an __fts_open() that doesn't make this check + // so that FTS_FOR_FTW works. + if (options & ~FTS_OPTIONMASK) { + errno = EINVAL; + return (NULL); + } + return __fts_open(argv, options, compar); } diff --git a/libc/bionic/heap_tagging.cpp b/libc/bionic/heap_tagging.cpp index 2c5d4d8cb..ffbabb9a0 100644 --- a/libc/bionic/heap_tagging.cpp +++ b/libc/bionic/heap_tagging.cpp @@ -32,7 +32,6 @@ #include <bionic/pthread_internal.h> #include <platform/bionic/malloc.h> -#include <platform/bionic/mte_kernel.h> extern "C" void scudo_malloc_disable_memory_tagging(); extern "C" void scudo_malloc_set_track_allocation_stacks(int); @@ -42,35 +41,36 @@ static HeapTaggingLevel heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE; void SetDefaultHeapTaggingLevel() { #if defined(__aarch64__) -#ifdef ANDROID_EXPERIMENTAL_MTE - // First, try enabling MTE in asynchronous mode, with tag 0 excluded. This will fail if the kernel - // or hardware doesn't support MTE, and we will fall back to just enabling tagged pointers in - // syscall arguments. - if (prctl(PR_SET_TAGGED_ADDR_CTRL, - PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_ASYNC | (0xfffe << PR_MTE_TAG_SHIFT), 0, 0, - 0) == 0) { - heap_tagging_level = M_HEAP_TAGGING_LEVEL_ASYNC; - return; - } -#endif // ANDROID_EXPERIMENTAL_MTE - - // Allow the kernel to accept tagged pointers in syscall arguments. This is a no-op (kernel - // returns -EINVAL) if the kernel doesn't understand the prctl. - if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0) { #if !__has_feature(hwaddress_sanitizer) - heap_tagging_level = M_HEAP_TAGGING_LEVEL_TBI; - __libc_globals.mutate([](libc_globals* globals) { - // Arrange for us to set pointer tags to POINTER_TAG, check tags on - // deallocation and untag when passing pointers to the allocator. - globals->heap_pointer_tag = (reinterpret_cast<uintptr_t>(POINTER_TAG) << TAG_SHIFT) | - (0xffull << CHECK_SHIFT) | (0xffull << UNTAG_SHIFT); - }); -#endif // hwaddress_sanitizer + heap_tagging_level = __libc_shared_globals()->initial_heap_tagging_level; +#endif + switch (heap_tagging_level) { + case M_HEAP_TAGGING_LEVEL_TBI: + __libc_globals.mutate([](libc_globals* globals) { + // Arrange for us to set pointer tags to POINTER_TAG, check tags on + // deallocation and untag when passing pointers to the allocator. + globals->heap_pointer_tag = (reinterpret_cast<uintptr_t>(POINTER_TAG) << TAG_SHIFT) | + (0xffull << CHECK_SHIFT) | (0xffull << UNTAG_SHIFT); + }); +#if defined(USE_SCUDO) + scudo_malloc_disable_memory_tagging(); +#endif // USE_SCUDO + break; +#if defined(USE_SCUDO) + case M_HEAP_TAGGING_LEVEL_SYNC: + scudo_malloc_set_track_allocation_stacks(1); + break; + + case M_HEAP_TAGGING_LEVEL_NONE: + scudo_malloc_disable_memory_tagging(); + break; +#endif // USE_SCUDO + default: + break; } #endif // aarch64 } -#ifdef ANDROID_EXPERIMENTAL_MTE static bool set_tcf_on_all_threads(int tcf) { static int g_tcf; g_tcf = tcf; @@ -90,7 +90,6 @@ static bool set_tcf_on_all_threads(int tcf) { }, nullptr); } -#endif pthread_mutex_t g_heap_tagging_lock = PTHREAD_MUTEX_INITIALIZER; @@ -100,12 +99,7 @@ HeapTaggingLevel GetHeapTaggingLevel() { } // Requires `g_heap_tagging_lock` to be held. -bool SetHeapTaggingLevel(void* arg, size_t arg_size) { - if (arg_size != sizeof(HeapTaggingLevel)) { - return false; - } - - auto tag_level = *reinterpret_cast<HeapTaggingLevel*>(arg); +bool SetHeapTaggingLevel(HeapTaggingLevel tag_level) { if (tag_level == heap_tagging_level) { return true; } @@ -119,13 +113,9 @@ bool SetHeapTaggingLevel(void* arg, size_t arg_size) { // tagged and checks no longer happen. globals->heap_pointer_tag = static_cast<uintptr_t>(0xffull << UNTAG_SHIFT); }); - } else { -#if defined(ANDROID_EXPERIMENTAL_MTE) - if (!set_tcf_on_all_threads(PR_MTE_TCF_NONE)) { - error_log("SetHeapTaggingLevel: set_tcf_on_all_threads failed"); - return false; - } -#endif + } else if (!set_tcf_on_all_threads(PR_MTE_TCF_NONE)) { + error_log("SetHeapTaggingLevel: set_tcf_on_all_threads failed"); + return false; } #if defined(USE_SCUDO) scudo_malloc_disable_memory_tagging(); @@ -135,8 +125,12 @@ bool SetHeapTaggingLevel(void* arg, size_t arg_size) { case M_HEAP_TAGGING_LEVEL_ASYNC: case M_HEAP_TAGGING_LEVEL_SYNC: if (heap_tagging_level == M_HEAP_TAGGING_LEVEL_NONE) { +#if !__has_feature(hwaddress_sanitizer) + // Suppress the error message in HWASan builds. Apps can try to enable TBI (or even MTE + // modes) being unaware of HWASan, fail them silently. error_log( "SetHeapTaggingLevel: re-enabling tagging after it was disabled is not supported"); +#endif return false; } else if (tag_level == M_HEAP_TAGGING_LEVEL_TBI || heap_tagging_level == M_HEAP_TAGGING_LEVEL_TBI) { @@ -145,16 +139,12 @@ bool SetHeapTaggingLevel(void* arg, size_t arg_size) { } if (tag_level == M_HEAP_TAGGING_LEVEL_ASYNC) { -#if defined(ANDROID_EXPERIMENTAL_MTE) set_tcf_on_all_threads(PR_MTE_TCF_ASYNC); -#endif #if defined(USE_SCUDO) scudo_malloc_set_track_allocation_stacks(0); #endif } else if (tag_level == M_HEAP_TAGGING_LEVEL_SYNC) { -#if defined(ANDROID_EXPERIMENTAL_MTE) set_tcf_on_all_threads(PR_MTE_TCF_SYNC); -#endif #if defined(USE_SCUDO) scudo_malloc_set_track_allocation_stacks(1); #endif diff --git a/libc/bionic/heap_tagging.h b/libc/bionic/heap_tagging.h index db45fc100..110b6ed7a 100644 --- a/libc/bionic/heap_tagging.h +++ b/libc/bionic/heap_tagging.h @@ -42,5 +42,5 @@ extern pthread_mutex_t g_heap_tagging_lock; // These functions can be called in a multithreaded context, and thus should // only be called when holding the `g_heap_tagging_lock`. -bool SetHeapTaggingLevel(void* arg, size_t arg_size); +bool SetHeapTaggingLevel(HeapTaggingLevel level); HeapTaggingLevel GetHeapTaggingLevel(); diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp index 80adbbe8e..f2c3f1c68 100644 --- a/libc/bionic/libc_init_common.cpp +++ b/libc/bionic/libc_init_common.cpp @@ -86,7 +86,7 @@ static void arc4random_fork_handler() { _thread_arc4_lock(); } -static void __libc_init_malloc_fill_contents() { +void __libc_init_scudo() { // TODO(b/158870657) make this unconditional when all devices support SCUDO. #if defined(USE_SCUDO) #if defined(SCUDO_PATTERN_FILL_CONTENTS) @@ -95,6 +95,7 @@ static void __libc_init_malloc_fill_contents() { scudo_malloc_set_zero_contents(1); #endif #endif + SetDefaultHeapTaggingLevel(); } __BIONIC_WEAK_FOR_NATIVE_BRIDGE @@ -119,9 +120,6 @@ void __libc_init_common() { __system_properties_init(); // Requires 'environ'. __libc_init_fdsan(); // Requires system properties (for debug.fdsan). __libc_init_fdtrack(); - - __libc_init_malloc_fill_contents(); - SetDefaultHeapTaggingLevel(); } void __libc_init_fork_handler() { diff --git a/libc/bionic/libc_init_common.h b/libc/bionic/libc_init_common.h index be7526f5f..a89908916 100644 --- a/libc/bionic/libc_init_common.h +++ b/libc/bionic/libc_init_common.h @@ -28,6 +28,7 @@ #pragma once +#include <stdint.h> #include <sys/cdefs.h> typedef void init_func_t(int, char*[], char*[]); @@ -57,6 +58,8 @@ __LIBC_HIDDEN__ void __libc_init_globals(); __LIBC_HIDDEN__ void __libc_init_common(); +__LIBC_HIDDEN__ void __libc_init_scudo(); + __LIBC_HIDDEN__ void __libc_init_AT_SECURE(char** envp); // The fork handler must be initialised after __libc_init_malloc, as diff --git a/libc/bionic/libc_init_dynamic.cpp b/libc/bionic/libc_init_dynamic.cpp index c9da02eab..175fa3ee9 100644 --- a/libc/bionic/libc_init_dynamic.cpp +++ b/libc/bionic/libc_init_dynamic.cpp @@ -90,6 +90,7 @@ static void __libc_preinit_impl() { __libc_init_globals(); __libc_init_common(); + __libc_init_scudo(); // Hooks for various libraries to let them know that we're starting up. __libc_globals.mutate(__libc_init_malloc); diff --git a/libc/bionic/libc_init_static.cpp b/libc/bionic/libc_init_static.cpp index 4a73918f2..2e4ee11a9 100644 --- a/libc/bionic/libc_init_static.cpp +++ b/libc/bionic/libc_init_static.cpp @@ -39,13 +39,17 @@ #include "libc_init_common.h" #include "pthread_internal.h" +#include "platform/bionic/macros.h" +#include "platform/bionic/mte.h" #include "platform/bionic/page.h" +#include "private/KernelArgumentBlock.h" +#include "private/bionic_asm.h" +#include "private/bionic_asm_note.h" #include "private/bionic_call_ifunc_resolver.h" #include "private/bionic_elf_tls.h" #include "private/bionic_globals.h" -#include "platform/bionic/macros.h" #include "private/bionic_tls.h" -#include "private/KernelArgumentBlock.h" +#include "sys/system_properties.h" #if __has_feature(hwaddress_sanitizer) #include <sanitizer/hwasan_interface.h> @@ -59,6 +63,7 @@ __LIBC_HIDDEN__ void* __libc_sysinfo; #endif extern "C" int __cxa_atexit(void (*)(void *), void *, void *); +extern "C" const char* __gnu_basename(const char* path); static void call_array(init_func_t** list, int argc, char* argv[], char* envp[]) { // First element is -1, list is null-terminated @@ -158,6 +163,170 @@ static void layout_static_tls(KernelArgumentBlock& args) { layout.finish_layout(); } +// Get the presiding config string, in the following order of priority: +// 1. Environment variables. +// 2. System properties, in the order they're specified in sys_prop_names. +// If neither of these options are specified, this function returns false. +// Otherwise, it returns true, and the presiding options string is written to +// the `options` buffer of size `size`. If this function returns true, `options` +// is guaranteed to be null-terminated. `options_size` should be at least +// PROP_VALUE_MAX. +bool get_config_from_env_or_sysprops(const char* env_var_name, const char* const* sys_prop_names, + size_t sys_prop_names_size, char* options, + size_t options_size) { + const char* env = getenv(env_var_name); + if (env && *env != '\0') { + strncpy(options, env, options_size); + options[options_size - 1] = '\0'; // Ensure null-termination. + return true; + } + + for (size_t i = 0; i < sys_prop_names_size; ++i) { + if (__system_property_get(sys_prop_names[i], options) && *options != '\0') return true; + } + return false; +} + +#ifdef __aarch64__ +static bool __read_memtag_note(const ElfW(Nhdr)* note, const char* name, const char* desc, + unsigned* result) { + if (note->n_namesz != 8 || strncmp(name, "Android", 8) != 0) { + return false; + } + if (note->n_type != NT_TYPE_MEMTAG) { + return false; + } + if (note->n_descsz != 4) { + async_safe_fatal("unrecognized android.memtag note: n_descsz = %d, expected 4", note->n_descsz); + } + *result = *reinterpret_cast<const ElfW(Word)*>(desc); + return true; +} + +static unsigned __get_memtag_note(const ElfW(Phdr)* phdr_start, size_t phdr_ct, + const ElfW(Addr) load_bias) { + for (size_t i = 0; i < phdr_ct; ++i) { + const ElfW(Phdr)* phdr = &phdr_start[i]; + if (phdr->p_type != PT_NOTE) { + continue; + } + ElfW(Addr) p = load_bias + phdr->p_vaddr; + ElfW(Addr) note_end = load_bias + phdr->p_vaddr + phdr->p_memsz; + while (p + sizeof(ElfW(Nhdr)) <= note_end) { + const ElfW(Nhdr)* note = reinterpret_cast<const ElfW(Nhdr)*>(p); + p += sizeof(ElfW(Nhdr)); + const char* name = reinterpret_cast<const char*>(p); + p += align_up(note->n_namesz, 4); + const char* desc = reinterpret_cast<const char*>(p); + p += align_up(note->n_descsz, 4); + if (p > note_end) { + break; + } + unsigned ret; + if (__read_memtag_note(note, name, desc, &ret)) { + return ret; + } + } + } + return 0; +} + +// Returns true if there's an environment setting (either sysprop or env var) +// that should overwrite the ELF note, and places the equivalent heap tagging +// level into *level. +static bool get_environment_memtag_setting(HeapTaggingLevel* level) { + static const char kMemtagPrognameSyspropPrefix[] = "arm64.memtag.process."; + + const char* progname = __libc_shared_globals()->init_progname; + if (progname == nullptr) return false; + + const char* basename = __gnu_basename(progname); + + static constexpr size_t kOptionsSize = PROP_VALUE_MAX; + char options_str[kOptionsSize]; + size_t sysprop_size = strlen(basename) + strlen(kMemtagPrognameSyspropPrefix) + 1; + char* sysprop_name = static_cast<char*>(alloca(sysprop_size)); + + async_safe_format_buffer(sysprop_name, sysprop_size, "%s%s", kMemtagPrognameSyspropPrefix, + basename); + + if (!get_config_from_env_or_sysprops("MEMTAG_OPTIONS", &sysprop_name, + /* sys_prop_names_size */ 1, options_str, kOptionsSize)) { + return false; + } + + if (strcmp("sync", options_str) == 0) { + *level = M_HEAP_TAGGING_LEVEL_SYNC; + } else if (strcmp("async", options_str) == 0) { + *level = M_HEAP_TAGGING_LEVEL_ASYNC; + } else if (strcmp("off", options_str) == 0) { + *level = M_HEAP_TAGGING_LEVEL_TBI; + } else { + async_safe_format_log( + ANDROID_LOG_ERROR, "libc", + "unrecognized memtag level: \"%s\" (options are \"sync\", \"async\", or \"off\").", + options_str); + return false; + } + + return true; +} + +// Returns the initial heap tagging level. Note: This function will never return +// M_HEAP_TAGGING_LEVEL_NONE, if MTE isn't enabled for this process we enable +// M_HEAP_TAGGING_LEVEL_TBI. +static HeapTaggingLevel __get_heap_tagging_level(const void* phdr_start, size_t phdr_ct, + uintptr_t load_bias) { + HeapTaggingLevel level; + if (get_environment_memtag_setting(&level)) return level; + + unsigned note_val = + __get_memtag_note(reinterpret_cast<const ElfW(Phdr)*>(phdr_start), phdr_ct, load_bias); + if (note_val & ~(NT_MEMTAG_LEVEL_MASK | NT_MEMTAG_HEAP)) { + async_safe_fatal("unrecognized android.memtag note: desc = %d", note_val); + } + + if (!(note_val & NT_MEMTAG_HEAP)) return M_HEAP_TAGGING_LEVEL_TBI; + + unsigned memtag_level = note_val & NT_MEMTAG_LEVEL_MASK; + switch (memtag_level) { + case NT_MEMTAG_LEVEL_ASYNC: + return M_HEAP_TAGGING_LEVEL_ASYNC; + case NT_MEMTAG_LEVEL_DEFAULT: + case NT_MEMTAG_LEVEL_SYNC: + return M_HEAP_TAGGING_LEVEL_SYNC; + default: + async_safe_fatal("unrecognized android.memtag note: level = %d", memtag_level); + } +} + +// 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(const void* phdr_start, + size_t phdr_ct, + uintptr_t load_bias) { + HeapTaggingLevel level = __get_heap_tagging_level(phdr_start, phdr_ct, load_bias); + + if (level == M_HEAP_TAGGING_LEVEL_SYNC || level == M_HEAP_TAGGING_LEVEL_ASYNC) { + unsigned long prctl_arg = PR_TAGGED_ADDR_ENABLE | PR_MTE_TAG_SET_NONZERO; + prctl_arg |= (level == M_HEAP_TAGGING_LEVEL_SYNC) ? PR_MTE_TCF_SYNC : PR_MTE_TCF_ASYNC; + + if (prctl(PR_SET_TAGGED_ADDR_CTRL, prctl_arg, 0, 0, 0) == 0) { + __libc_shared_globals()->initial_heap_tagging_level = level; + return; + } + } + + // MTE was either not enabled, or wasn't supported on this device. Try and use + // TBI. + if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == 0) { + __libc_shared_globals()->initial_heap_tagging_level = M_HEAP_TAGGING_LEVEL_TBI; + } +} +#else // __aarch64__ +void __libc_init_mte(const void*, size_t, uintptr_t) {} +#endif // __aarch64__ + __noreturn static void __real_libc_init(void *raw_args, void (*onexit)(void) __unused, int (*slingshot)(int, char**, char**), @@ -175,6 +344,9 @@ __noreturn static void __real_libc_init(void *raw_args, layout_static_tls(args); __libc_init_main_thread_final(); __libc_init_common(); + __libc_init_mte(reinterpret_cast<ElfW(Phdr)*>(getauxval(AT_PHDR)), getauxval(AT_PHNUM), + /*load_bias = */ 0); + __libc_init_scudo(); __libc_init_fork_handler(); call_ifunc_resolvers(); diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp index 0ee12a7fd..863103deb 100644 --- a/libc/bionic/malloc_common.cpp +++ b/libc/bionic/malloc_common.cpp @@ -102,6 +102,15 @@ extern "C" int malloc_info(int options, FILE* fp) { } extern "C" int mallopt(int param, int value) { + // Some are handled by libc directly rather than by the allocator. + if (param == M_BIONIC_SET_HEAP_TAGGING_LEVEL) { + ScopedPthreadMutexLocker locker(&g_heap_tagging_lock); + return SetHeapTaggingLevel(static_cast<HeapTaggingLevel>(value)); + } + if (param == M_BIONIC_DISABLE_MEMORY_MITIGATIONS) { + return DisableMemoryMitigations(value); + } + // The rest we pass on... auto dispatch_table = GetDispatchTable(); if (__predict_false(dispatch_table != nullptr)) { return dispatch_table->mallopt(param, value); @@ -316,10 +325,6 @@ extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size) { if (opcode == M_SET_ALLOCATION_LIMIT_BYTES) { return LimitEnable(arg, arg_size); } - if (opcode == M_SET_HEAP_TAGGING_LEVEL) { - ScopedPthreadMutexLocker locker(&g_heap_tagging_lock); - return SetHeapTaggingLevel(arg, arg_size); - } if (opcode == M_INITIALIZE_GWP_ASAN) { if (arg == nullptr || arg_size != sizeof(bool)) { errno = EINVAL; @@ -329,9 +334,6 @@ extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size) { return MaybeInitGwpAsan(globals, *reinterpret_cast<bool*>(arg)); }); } - if (opcode == M_DISABLE_MEMORY_MITIGATIONS) { - return DisableMemoryMitigations(arg, arg_size); - } errno = ENOTSUP; return false; } diff --git a/libc/bionic/malloc_common_dynamic.cpp b/libc/bionic/malloc_common_dynamic.cpp index 2d6a1bbcb..7a221d891 100644 --- a/libc/bionic/malloc_common_dynamic.cpp +++ b/libc/bionic/malloc_common_dynamic.cpp @@ -523,10 +523,6 @@ extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size) { } return FreeMallocLeakInfo(reinterpret_cast<android_mallopt_leak_info_t*>(arg)); } - if (opcode == M_SET_HEAP_TAGGING_LEVEL) { - ScopedPthreadMutexLocker locker(&g_heap_tagging_lock); - return SetHeapTaggingLevel(arg, arg_size); - } if (opcode == M_INITIALIZE_GWP_ASAN) { if (arg == nullptr || arg_size != sizeof(bool)) { errno = EINVAL; @@ -536,9 +532,6 @@ extern "C" bool android_mallopt(int opcode, void* arg, size_t arg_size) { return MaybeInitGwpAsan(globals, *reinterpret_cast<bool*>(arg)); }); } - if (opcode == M_DISABLE_MEMORY_MITIGATIONS) { - return DisableMemoryMitigations(arg, arg_size); - } // Try heapprofd's mallopt, as it handles options not covered here. return HeapprofdMallopt(opcode, arg, arg_size); } diff --git a/libc/bionic/malloc_tagged_pointers.h b/libc/bionic/malloc_tagged_pointers.h index de3cc2ed9..484a0802e 100644 --- a/libc/bionic/malloc_tagged_pointers.h +++ b/libc/bionic/malloc_tagged_pointers.h @@ -99,9 +99,10 @@ static inline void* MaybeUntagAndCheckPointer(const volatile void* ptr) { // check below allows us to turn *off* pointer tagging (by setting PointerCheckMask() and // FixedPointerTag() to zero) and still allow tagged heap allocations to be freed. if ((ptr_int & PointerCheckMask()) != FixedPointerTag()) { - // TODO(b/145604058) - Upstream tagged pointers documentation and provide - // a link to it in the abort message here. - async_safe_fatal("Pointer tag for %p was truncated.", ptr); + async_safe_fatal( + "Pointer tag for %p was truncated, see " + "'https://source.android.com/devices/tech/debug/tagged-pointers'.", + ptr); } return reinterpret_cast<void*>(ptr_int & PointerUntagMask()); } diff --git a/libc/bionic/memory_mitigation_state.cpp b/libc/bionic/memory_mitigation_state.cpp index 4761d8862..b262f8616 100644 --- a/libc/bionic/memory_mitigation_state.cpp +++ b/libc/bionic/memory_mitigation_state.cpp @@ -47,8 +47,8 @@ extern "C" void scudo_malloc_set_zero_contents(int zero_contents); -bool DisableMemoryMitigations(void* arg, size_t arg_size) { - if (arg || arg_size) { +bool DisableMemoryMitigations(int arg) { + if (arg != 0) { return false; } @@ -61,7 +61,7 @@ bool DisableMemoryMitigations(void* arg, size_t arg_size) { HeapTaggingLevel current_level = GetHeapTaggingLevel(); if (current_level != M_HEAP_TAGGING_LEVEL_NONE && current_level != M_HEAP_TAGGING_LEVEL_TBI) { HeapTaggingLevel level = M_HEAP_TAGGING_LEVEL_NONE; - SetHeapTaggingLevel(reinterpret_cast<void*>(&level), sizeof(level)); + SetHeapTaggingLevel(level); } return true; diff --git a/libc/bionic/memory_mitigation_state.h b/libc/bionic/memory_mitigation_state.h index ffa19121d..047b6ad3a 100644 --- a/libc/bionic/memory_mitigation_state.h +++ b/libc/bionic/memory_mitigation_state.h @@ -30,4 +30,4 @@ #include <stddef.h> -bool DisableMemoryMitigations(void* arg, size_t arg_size); +bool DisableMemoryMitigations(int arg); diff --git a/libc/bionic/recvmsg.cpp b/libc/bionic/recvmsg.cpp index 003f43d8a..4d3f98939 100644 --- a/libc/bionic/recvmsg.cpp +++ b/libc/bionic/recvmsg.cpp @@ -39,7 +39,7 @@ extern "C" int __recvmmsg(int __fd, struct mmsghdr* __msgs, unsigned int __msg_c static inline __attribute__((artificial)) __attribute__((always_inline)) void track_fds( struct msghdr* msg, const char* function_name) { - if (!__android_fdtrack_hook) { + if (!atomic_load(&__android_fdtrack_hook)) { return; } diff --git a/libc/dns/net/gethnamaddr.c b/libc/dns/net/gethnamaddr.c index 84942f876..f8212a295 100644 --- a/libc/dns/net/gethnamaddr.c +++ b/libc/dns/net/gethnamaddr.c @@ -75,9 +75,6 @@ #include <syslog.h> #include <unistd.h> -#define ALIGNBYTES (sizeof(uintptr_t) - 1) -#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES) - #ifndef LOG_AUTH # define LOG_AUTH 0 #endif diff --git a/libc/dns/net/sethostent.c b/libc/dns/net/sethostent.c index a743a543e..b2b0132c5 100644 --- a/libc/dns/net/sethostent.c +++ b/libc/dns/net/sethostent.c @@ -55,9 +55,6 @@ __RCSID("$NetBSD: sethostent.c,v 1.20 2014/03/17 13:24:23 christos Exp $"); #include "hostent.h" #include "resolv_private.h" -#define ALIGNBYTES (sizeof(uintptr_t) - 1) -#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES) - #ifndef _REENTRANT void res_close(void); #endif diff --git a/libc/include/android/api-level.h b/libc/include/android/api-level.h index bcddddd59..40846fb8b 100644 --- a/libc/include/android/api-level.h +++ b/libc/include/android/api-level.h @@ -151,6 +151,9 @@ __BEGIN_DECLS /** Names the "S" API level (31), for comparison against `__ANDROID_API__`. */ #define __ANDROID_API_S__ 31 +/* This file is included in <features.h>, and might be used from .S files. */ +#if !defined(__ASSEMBLY__) + /** * Returns the `targetSdkVersion` of the caller, or `__ANDROID_API_FUTURE__` if * there is no known target SDK version (for code not running in the context of @@ -167,7 +170,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. +/* android_get_device_api_level is a static inline before API level 29. */ #define __BIONIC_GET_DEVICE_API_LEVEL_INLINE static __inline #include <bits/get_device_api_level_inlines.h> #undef __BIONIC_GET_DEVICE_API_LEVEL_INLINE @@ -185,6 +188,8 @@ int android_get_device_api_level() __INTRODUCED_IN(29); #endif +#endif /* defined(__ASSEMBLY__) */ + __END_DECLS /** @} */ diff --git a/libc/include/android/legacy_signal_inlines.h b/libc/include/android/legacy_signal_inlines.h index 90eda7dc1..a6734464c 100644 --- a/libc/include/android/legacy_signal_inlines.h +++ b/libc/include/android/legacy_signal_inlines.h @@ -45,12 +45,16 @@ int __libc_current_sigrtmax() __attribute__((__weak__)) __VERSIONER_NO_GUARD; int __libc_current_sigrtmin() __attribute__((__weak__)) __VERSIONER_NO_GUARD; static __inline int __ndk_legacy___libc_current_sigrtmax() { - if (__libc_current_sigrtmax) return __libc_current_sigrtmax(); + if (__builtin_available(android 21, *)) { + return __libc_current_sigrtmax(); + } return __SIGRTMAX; /* Should match __libc_current_sigrtmax. */ } static __inline int __ndk_legacy___libc_current_sigrtmin() { - if (__libc_current_sigrtmin) return __libc_current_sigrtmin(); + if (__builtin_available(android 21, *)) { + return __libc_current_sigrtmin(); + } return __SIGRTMIN + 7; /* Should match __libc_current_sigrtmin. */ } diff --git a/libc/include/android/versioning.h b/libc/include/android/versioning.h index 3ea414a45..2b9a0272b 100644 --- a/libc/include/android/versioning.h +++ b/libc/include/android/versioning.h @@ -33,13 +33,62 @@ #else -#define __INTRODUCED_IN(api_level) -#define __DEPRECATED_IN(api_level) -#define __REMOVED_IN(api_level) -#define __INTRODUCED_IN_32(api_level) +// When headers are not processed by the versioner (i.e. compiled into object files), +// the availability attributed is emitted instead. The clang compiler will make the symbol weak +// when targeting old api_level and enforce the reference to the symbol to be guarded with +// __builtin_available(android api_level, *). + +// The 'strict' flag is required for NDK clients where the use of "-Wunguarded-availability" cannot +// be enforced. In the case, the absence of 'strict' makes it possible to call an unavailable API +// without the __builtin_available check, which will cause a link error at runtime. +// Android platform build system defines this macro along with -Wunguarded-availability +#if defined(__ANDROID_UNGUARDED_AVAILABILITY__) +#define __MAYBE_STRICT +#else +#define __MAYBE_STRICT ,strict +#endif + +#define __INTRODUCED_IN(api_level) \ + __attribute__((availability(android __MAYBE_STRICT,introduced=api_level))) +#define __DEPRECATED_IN(api_level) \ + __attribute__((availability(android __MAYBE_STRICT,deprecated=api_level))) +#define __REMOVED_IN(api_level) \ + __attribute__((availability(android __MAYBE_STRICT,obsoleted=api_level))) + +// The same availability attribute can't be annotated multiple times. Therefore, the macros are +// defined for the configuration that it is valid for so that declarations like the below doesn't +// cause inconsistent availability values which is an error with -Wavailability: +// +// void foo() __INTRODUCED_IN_32(30) __INTRODUCED_IN_64(31); +// +// This also takes the advantage of the fact that we never use bitness-specific macro with +// arch-specific macro. In other words, +// +// void foo() __INTRODUCED_IN_ARM(30) __INTRODUCED_IN_64(31); +// +// hasn't been supported and won't be. +#if !defined(__LP64__) +#define __INTRODUCED_IN_32(api_level) \ + __attribute__((availability(android __MAYBE_STRICT,introduced=api_level))) #define __INTRODUCED_IN_64(api_level) +#else +#define __INTRODUCED_IN_32(api_level) +#define __INTRODUCED_IN_64(api_level) \ + __attribute__((availability(android __MAYBE_STRICT,introduced=api_level))) +#endif + +#if defined(__arm__) || defined(__aarch64__) +#define __INTRODUCED_IN_ARM(api_level) \ + __attribute__((availability(android __MAYBE_STRICT,introduced=api_level))) +#define __INTRODUCED_IN_X86(api_level) +#elif defined(__i386__) || defined(__x86_64__) +#define __INTRODUCED_IN_ARM(api_level) +#define __INTRODUCED_IN_X86(api_level) \ + __attribute__((availability(android __MAYBE_STRICT,introduced=api_level))) +#else #define __INTRODUCED_IN_ARM(api_level) #define __INTRODUCED_IN_X86(api_level) +#endif #define __VERSIONER_NO_GUARD #define __VERSIONER_FORTIFY_INLINE diff --git a/libc/include/malloc.h b/libc/include/malloc.h index a237254b7..598a50bc5 100644 --- a/libc/include/malloc.h +++ b/libc/include/malloc.h @@ -204,6 +204,60 @@ int malloc_info(int __must_be_zero, FILE* __fp) __INTRODUCED_IN(23); #define M_TSDS_COUNT_MAX (-202) /** + * mallopt() option to disable heap initialization across the whole process. + * If the hardware supports memory tagging, this also disables memory tagging. + * May be called at any time, including when multiple threads are running. The + * value is unused but must be set to 0. + * + * Note that these memory mitigations are only implemented in scudo and + * therefore this will have no effect when using another allocator (such as + * jemalloc on Android Go devices). + * + * Available since API level 31. + */ +#define M_BIONIC_DISABLE_MEMORY_MITIGATIONS (-203) + +/** + * mallopt() option to change the heap tagging state. May be called at any + * time, including when multiple threads are running. + * The value must be one of the M_HEAP_TAGGING_LEVEL_ constants. + * + * Available since API level 31. + */ +#define M_BIONIC_SET_HEAP_TAGGING_LEVEL (-204) + +/** + * Constants for use with the M_BIONIC_SET_HEAP_TAGGING_LEVEL mallopt() option. + */ +enum HeapTaggingLevel { + /** + * Disable heap tagging and memory tag checks (if supported). + * Heap tagging may not be re-enabled after being disabled. + */ + M_HEAP_TAGGING_LEVEL_NONE = 0, +#define M_HEAP_TAGGING_LEVEL_NONE M_HEAP_TAGGING_LEVEL_NONE + /** + * Address-only tagging. Heap pointers have a non-zero tag in the + * most significant ("top") byte which is checked in free(). Memory + * accesses ignore the tag using arm64's Top Byte Ignore (TBI) feature. + */ + M_HEAP_TAGGING_LEVEL_TBI = 1, +#define M_HEAP_TAGGING_LEVEL_TBI M_HEAP_TAGGING_LEVEL_TBI + /** + * Enable heap tagging and asynchronous memory tag checks (if supported). + * Disable stack trace collection. + */ + M_HEAP_TAGGING_LEVEL_ASYNC = 2, +#define M_HEAP_TAGGING_LEVEL_ASYNC M_HEAP_TAGGING_LEVEL_ASYNC + /** + * Enable heap tagging and synchronous memory tag checks (if supported). + * Enable stack trace collection. + */ + M_HEAP_TAGGING_LEVEL_SYNC = 3, +#define M_HEAP_TAGGING_LEVEL_SYNC M_HEAP_TAGGING_LEVEL_SYNC +}; + +/** * [mallopt(3)](http://man7.org/linux/man-pages/man3/mallopt.3.html) modifies * heap behavior. Values of `__option` are the `M_` constants from this header. * diff --git a/libc/platform/bionic/malloc.h b/libc/platform/bionic/malloc.h index 56badf0fd..b56ca746a 100644 --- a/libc/platform/bionic/malloc.h +++ b/libc/platform/bionic/malloc.h @@ -28,6 +28,7 @@ #pragma once +#include <malloc.h> #include <stdbool.h> #include <stdint.h> @@ -85,12 +86,6 @@ enum { // arg_size = sizeof(android_mallopt_leak_info_t) M_FREE_MALLOC_LEAK_INFO = 7, #define M_FREE_MALLOC_LEAK_INFO M_FREE_MALLOC_LEAK_INFO - // Change the heap tagging state. May be called at any time including when - // multiple threads are running. - // arg = HeapTaggingLevel* - // arg_size = sizeof(HeapTaggingLevel) - M_SET_HEAP_TAGGING_LEVEL = 8, -#define M_SET_HEAP_TAGGING_LEVEL M_SET_HEAP_TAGGING_LEVEL // Query whether the current process is considered to be profileable by the // Android platform. Result is assigned to the arg pointer's destination. // arg = bool* @@ -105,28 +100,6 @@ enum { // arg_size = sizeof(bool) M_INITIALIZE_GWP_ASAN = 10, #define M_INITIALIZE_GWP_ASAN M_INITIALIZE_GWP_ASAN - // Disable heap initialization across the whole process. If the hardware supports memory - // tagging, it also disables memory tagging. May be called at any time including - // when multiple threads are running. arg and arg_size are unused and must be set to 0. - // Note that the memory mitigations are only implemented in scudo and therefore this API call will - // have no effect when using another allocator. - M_DISABLE_MEMORY_MITIGATIONS = 11, -#define M_DISABLE_MEMORY_MITIGATIONS M_DISABLE_MEMORY_MITIGATIONS -}; - -enum HeapTaggingLevel { - // Disable heap tagging and memory tag checks if supported. Heap tagging may not be re-enabled - // after being disabled. - M_HEAP_TAGGING_LEVEL_NONE = 0, - // Address-only tagging. Heap pointers have a non-zero tag in the most significant byte which is - // checked in free(). Memory accesses ignore the tag. - M_HEAP_TAGGING_LEVEL_TBI = 1, - // Enable heap tagging and asynchronous memory tag checks if supported. Disable stack trace - // collection. - M_HEAP_TAGGING_LEVEL_ASYNC = 2, - // Enable heap tagging and synchronous memory tag checks if supported. Enable stack trace - // collection. - M_HEAP_TAGGING_LEVEL_SYNC = 3, }; // Manipulates bionic-specific handling of memory allocation APIs such as diff --git a/libc/platform/bionic/mte.h b/libc/platform/bionic/mte.h index 1e393eb0c..73cd821b6 100644 --- a/libc/platform/bionic/mte.h +++ b/libc/platform/bionic/mte.h @@ -29,10 +29,16 @@ #pragma once #include <sys/auxv.h> -#include <bionic/mte_kernel.h> +#include <sys/prctl.h> + +// Note: Most PR_MTE_* constants come from the upstream kernel. This tag mask +// allows for the hardware to provision any nonzero tag. Zero tags are reserved +// for scudo to use for the chunk headers in order to prevent linear heap +// overflow/underflow. +#define PR_MTE_TAG_SET_NONZERO (0xfffeUL << PR_MTE_TAG_SHIFT) inline bool mte_supported() { -#if defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE) +#if defined(__aarch64__) static bool supported = getauxval(AT_HWCAP2) & HWCAP2_MTE; #else static bool supported = false; diff --git a/libc/private/bionic_asm.h b/libc/private/bionic_asm.h index 6d4f7d52c..d68a2d604 100644 --- a/libc/private/bionic_asm.h +++ b/libc/private/bionic_asm.h @@ -26,8 +26,10 @@ * SUCH DAMAGE. */ -#ifndef _PRIVATE_BIONIC_ASM_H_ -#define _PRIVATE_BIONIC_ASM_H_ +#pragma once + +/* https://github.com/android/ndk/issues/1422 */ +#include <features.h> #include <asm/unistd.h> /* For system call numbers. */ #define MAX_ERRNO 4095 /* For recognizing system call error returns. */ @@ -86,5 +88,3 @@ #define NOTE_GNU_PROPERTY() \ __bionic_asm_custom_note_gnu_section() - -#endif diff --git a/libc/private/bionic_asm_arm64.h b/libc/private/bionic_asm_arm64.h index c11732ae8..e73f25d36 100644 --- a/libc/private/bionic_asm_arm64.h +++ b/libc/private/bionic_asm_arm64.h @@ -69,4 +69,10 @@ .long (__bionic_asm_aarch64_feature_pac | \ __bionic_asm_aarch64_feature_bti); \ .long 0; \ - .popsection; \ + .popsection; + +#define NT_MEMTAG_LEVEL_MASK 3 +#define NT_MEMTAG_LEVEL_DEFAULT 0 +#define NT_MEMTAG_LEVEL_ASYNC 1 +#define NT_MEMTAG_LEVEL_SYNC 2 +#define NT_MEMTAG_HEAP 4 diff --git a/libc/platform/bionic/mte_kernel.h b/libc/private/bionic_asm_note.h index d81480aa7..80b8f011c 100644 --- a/libc/platform/bionic/mte_kernel.h +++ b/libc/private/bionic_asm_note.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2021 The Android Open Source Project * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,32 +28,6 @@ #pragma once -// Defines constants used as part of the interface in an experimental MTE branch -// of the Linux kernel, which may be found at: -// -// https://github.com/pcc/linux/tree/android-experimental-mte -// -// This interface should not be considered to be stable. - -#ifdef ANDROID_EXPERIMENTAL_MTE - -#define HWCAP2_MTE (1 << 18) -#define PROT_MTE 0x20 - -#define PR_MTE_TCF_SHIFT 1 -#define PR_MTE_TCF_NONE (0UL << PR_MTE_TCF_SHIFT) -#define PR_MTE_TCF_SYNC (1UL << PR_MTE_TCF_SHIFT) -#define PR_MTE_TCF_ASYNC (2UL << PR_MTE_TCF_SHIFT) -#define PR_MTE_TCF_MASK (3UL << PR_MTE_TCF_SHIFT) -#define PR_MTE_TAG_SHIFT 3 -#define PR_MTE_TAG_MASK (0xffffUL << PR_MTE_TAG_SHIFT) - -#define SEGV_MTEAERR 8 -#define SEGV_MTESERR 9 - -#define PTRACE_PEEKMTETAGS 33 -#define PTRACE_POKEMTETAGS 34 - -#define NT_ARM_TAGGED_ADDR_CTRL 0x409 - -#endif +#define NT_TYPE_IDENT 1 +#define NT_TYPE_KUSER 3 +#define NT_TYPE_MEMTAG 4 diff --git a/libc/private/bionic_fdtrack.h b/libc/private/bionic_fdtrack.h index 752dd8dc5..259897c22 100644 --- a/libc/private/bionic_fdtrack.h +++ b/libc/private/bionic_fdtrack.h @@ -58,7 +58,7 @@ extern "C" _Atomic(android_fdtrack_hook_t) __android_fdtrack_hook; event.fd = __fd; \ event.type = ANDROID_FDTRACK_EVENT_TYPE_CREATE; \ event.data.create.function_name = name; \ - __android_fdtrack_hook(&event); \ + atomic_load(&__android_fdtrack_hook)(&event); \ tls.fdtrack_disabled = false; \ } \ } \ @@ -86,7 +86,7 @@ extern "C" _Atomic(android_fdtrack_hook_t) __android_fdtrack_hook; android_fdtrack_event event; \ event.fd = __fd; \ event.type = ANDROID_FDTRACK_EVENT_TYPE_CLOSE; \ - __android_fdtrack_hook(&event); \ + atomic_load(&__android_fdtrack_hook)(&event); \ tls.fdtrack_disabled = false; \ errno = saved_errno; \ } \ diff --git a/libc/private/bionic_globals.h b/libc/private/bionic_globals.h index 5c9b726d2..813226172 100644 --- a/libc/private/bionic_globals.h +++ b/libc/private/bionic_globals.h @@ -41,6 +41,8 @@ #include "private/bionic_vdso.h" #include "private/WriteProtected.h" +#include <platform/bionic/malloc.h> + struct libc_globals { vdso_entry vdso[VDSO_END]; long setjmp_cookie; @@ -106,6 +108,8 @@ struct libc_shared_globals { const char* scudo_stack_depot = nullptr; const char* scudo_region_info = nullptr; + + HeapTaggingLevel initial_heap_tagging_level = M_HEAP_TAGGING_LEVEL_NONE; }; __LIBC_HIDDEN__ libc_shared_globals* __libc_shared_globals(); diff --git a/libc/private/bsd_sys_param.h b/libc/private/bsd_sys_param.h new file mode 100644 index 000000000..8c936c459 --- /dev/null +++ b/libc/private/bsd_sys_param.h @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2014 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. + */ + +#pragma once + +/* OpenBSD has these in <sys/param.h>, but "ALIGN" isn't something we want to reserve. */ +#define ALIGNBYTES (sizeof(uintptr_t) - 1) +#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) & ~ALIGNBYTES) diff --git a/libc/stdio/stdio.cpp b/libc/stdio/stdio.cpp index b8aced83b..c7b1ba459 100644 --- a/libc/stdio/stdio.cpp +++ b/libc/stdio/stdio.cpp @@ -57,8 +57,7 @@ #include "private/ErrnoRestorer.h" #include "private/thread_private.h" -#define ALIGNBYTES (sizeof(uintptr_t) - 1) -#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES) +#include "private/bsd_sys_param.h" // For ALIGN/ALIGNBYTES. #define NDYNAMIC 10 /* add ten more whenever necessary */ diff --git a/libc/system_properties/context_lookup_benchmark_data.h b/libc/system_properties/context_lookup_benchmark_data.h index 3cc325724..b928875dd 100644 --- a/libc/system_properties/context_lookup_benchmark_data.h +++ b/libc/system_properties/context_lookup_benchmark_data.h @@ -885,7 +885,6 @@ ro.hwui.use_vulkan u:object_r:exported_default_prop:s0 exact bool ro.kernel.qemu u:object_r:exported_default_prop:s0 exact bool ro.kernel.qemu. u:object_r:exported_default_prop:s0 ro.kernel.android.bootanim u:object_r:exported_default_prop:s0 exact int -ro.kernel.ebpf.supported u:object_r:exported_default_prop:s0 exact bool ro.oem.key1 u:object_r:exported_default_prop:s0 exact string diff --git a/libc/upstream-openbsd/android/include/openbsd-compat.h b/libc/upstream-openbsd/android/include/openbsd-compat.h index 2fc5046ad..6c21c5b49 100644 --- a/libc/upstream-openbsd/android/include/openbsd-compat.h +++ b/libc/upstream-openbsd/android/include/openbsd-compat.h @@ -25,6 +25,8 @@ #include <sys/random.h> // For getentropy. +#include "private/bsd_sys_param.h" + #define __BEGIN_HIDDEN_DECLS _Pragma("GCC visibility push(hidden)") #define __END_HIDDEN_DECLS _Pragma("GCC visibility pop") @@ -57,10 +59,6 @@ extern const char* __progname; #define explicit_bzero(p, s) memset(p, 0, s) -/* OpenBSD has these in <sys/param.h>, but "ALIGN" isn't something we want to reserve. */ -#define ALIGNBYTES (sizeof(uintptr_t) - 1) -#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES) - /* OpenBSD has this in paths.h. But this directory doesn't normally exist. * Even when it does exist, only the 'shell' user has permissions. */ |