Merge "Don't set native_bridge_supported: true for ndk libraries"
diff --git a/apex/Android.bp b/apex/Android.bp
index c97eb15..8aec64a 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -60,6 +60,8 @@
],
native_static_libs: [
"libasync_safe",
+ "note_memtag_heap_async",
+ "note_memtag_heap_sync",
],
native_objects: [
"crtbegin_dynamic",
diff --git a/libc/Android.bp b/libc/Android.bp
index e5c954e..8f07ef4 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -93,9 +93,6 @@
ldflags: ["-Wl,-z,muldefs"],
product_variables: {
- experimental_mte: {
- cflags: ["-DANDROID_EXPERIMENTAL_MTE"],
- },
malloc_zero_contents: {
cflags: ["-DSCUDO_ZERO_CONTENTS"],
},
@@ -269,6 +266,7 @@
"-Wno-unused-parameter",
"-include netbsd-compat.h",
"-Wframe-larger-than=66000",
+ "-include private/bsd_sys_param.h",
],
local_include_dirs: [
@@ -579,6 +577,7 @@
],
local_include_dirs: [
+ "private",
"upstream-openbsd/android/include/",
"upstream-openbsd/lib/libc/include/",
"upstream-openbsd/lib/libc/gdtoa/",
@@ -1632,6 +1631,7 @@
"gwp_asan",
"libc_init_dynamic",
"libc_common_shared",
+ "libunwind-exported",
],
},
@@ -1673,8 +1673,6 @@
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
@@ -1693,10 +1691,6 @@
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.
@@ -1710,10 +1704,6 @@
strip: {
keep_symbols: true,
},
-
- shared: {
- whole_static_libs: [ "libgcc_stripped" ],
- },
},
x86_64: {
version_script: ":libc.x86_64.map",
@@ -1723,10 +1713,6 @@
strip: {
keep_symbols: true,
},
-
- shared: {
- whole_static_libs: [ "libgcc_stripped" ],
- },
},
},
diff --git a/libc/arch-arm64/dynamic_function_dispatch.cpp b/libc/arch-arm64/dynamic_function_dispatch.cpp
index 0fd331f..83e5ca4 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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/bionic/bionic_appcompat.cpp b/libc/bionic/bionic_appcompat.cpp
index 5b31c29..dcca0da 100644
--- a/libc/bionic/bionic_appcompat.cpp
+++ b/libc/bionic/bionic_appcompat.cpp
@@ -88,4 +88,4 @@
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 1976e0b..fd37035 100644
--- a/libc/bionic/bionic_appcompat.h
+++ b/libc/bionic/bionic_appcompat.h
@@ -41,4 +41,4 @@
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 8888ab1..77b4117 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 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 @@
#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 @@
* 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 @@
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 @@
} 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 @@
* 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 @@
mem1: free(sp);
return (NULL);
}
+DEF_WEAK(fts_open);
static void
fts_load(FTS *sp, FTSENT *p)
@@ -221,7 +228,8 @@
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 @@
return (error);
}
+DEF_WEAK(fts_close);
/*
* Special case of "/" at the end of the path so that slashes aren't
@@ -281,7 +290,8 @@
(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 @@
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 @@
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 @@
* 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 @@
p->fts_instr = instr;
return (0);
}
+DEF_WEAK(fts_set);
FTSENT *
fts_children(FTS *sp, int instr)
@@ -489,7 +501,8 @@
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 @@
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 @@
(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 @@
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 @@
/* 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 @@
* 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 @@
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 @@
}
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 @@
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 @@
* 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 @@
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 @@
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 72f8f1d..ffbabb9 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);
@@ -53,8 +52,11 @@
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(ANDROID_EXPERIMENTAL_MTE) && defined(USE_SCUDO)
+#if defined(USE_SCUDO)
case M_HEAP_TAGGING_LEVEL_SYNC:
scudo_malloc_set_track_allocation_stacks(1);
break;
@@ -62,14 +64,13 @@
case M_HEAP_TAGGING_LEVEL_NONE:
scudo_malloc_disable_memory_tagging();
break;
-#endif // ANDROID_EXPERIMENTAL_MTE
+#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;
@@ -89,7 +90,6 @@
},
nullptr);
}
-#endif
pthread_mutex_t g_heap_tagging_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -99,12 +99,7 @@
}
// 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;
}
@@ -118,13 +113,9 @@
// 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();
@@ -134,8 +125,12 @@
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) {
@@ -144,16 +139,12 @@
}
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 db45fc1..110b6ed 100644
--- a/libc/bionic/heap_tagging.h
+++ b/libc/bionic/heap_tagging.h
@@ -42,5 +42,5 @@
// 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_static.cpp b/libc/bionic/libc_init_static.cpp
index 3705606..2e4ee11 100644
--- a/libc/bionic/libc_init_static.cpp
+++ b/libc/bionic/libc_init_static.cpp
@@ -39,15 +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_asm.h"
-#include "private/bionic_asm_note.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>
@@ -61,6 +63,7 @@
#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
@@ -160,6 +163,30 @@
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) {
@@ -204,42 +231,94 @@
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) {
- unsigned v =
- __get_memtag_note(reinterpret_cast<const ElfW(Phdr)*>(phdr_start), phdr_ct, load_bias);
+ HeapTaggingLevel level = __get_heap_tagging_level(phdr_start, phdr_ct, load_bias);
- if (v & ~(NT_MEMTAG_LEVEL_MASK | NT_MEMTAG_HEAP)) {
- async_safe_fatal("unrecognized android.memtag note: desc = %d", v);
- }
+ 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 (v & NT_MEMTAG_HEAP) {
- unsigned memtag_level = v & NT_MEMTAG_LEVEL_MASK;
- unsigned long arg = PR_TAGGED_ADDR_ENABLE | (0xfffe << PR_MTE_TAG_SHIFT);
- HeapTaggingLevel level;
- switch (memtag_level) {
- case NT_MEMTAG_LEVEL_ASYNC:
- arg |= PR_MTE_TCF_ASYNC;
- level = M_HEAP_TAGGING_LEVEL_ASYNC;
- break;
- case NT_MEMTAG_LEVEL_DEFAULT:
- case NT_MEMTAG_LEVEL_SYNC:
- arg |= PR_MTE_TCF_SYNC;
- level = M_HEAP_TAGGING_LEVEL_SYNC;
- break;
- default:
- async_safe_fatal("unrecognized android.memtag note: level = %d", memtag_level);
- }
-
- if (prctl(PR_SET_TAGGED_ADDR_CTRL, arg, 0, 0, 0) == 0) {
+ 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;
}
diff --git a/libc/bionic/malloc_common.cpp b/libc/bionic/malloc_common.cpp
index 0ee12a7..863103d 100644
--- a/libc/bionic/malloc_common.cpp
+++ b/libc/bionic/malloc_common.cpp
@@ -102,6 +102,15 @@
}
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 @@
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 @@
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 2d6a1bb..7a221d8 100644
--- a/libc/bionic/malloc_common_dynamic.cpp
+++ b/libc/bionic/malloc_common_dynamic.cpp
@@ -523,10 +523,6 @@
}
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 @@
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/memory_mitigation_state.cpp b/libc/bionic/memory_mitigation_state.cpp
index 4761d88..b262f86 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 @@
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 ffa1912..047b6ad 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 003f43d..4d3f989 100644
--- a/libc/bionic/recvmsg.cpp
+++ b/libc/bionic/recvmsg.cpp
@@ -39,7 +39,7 @@
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 84942f8..f8212a2 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 a743a54..b2b0132 100644
--- a/libc/dns/net/sethostent.c
+++ b/libc/dns/net/sethostent.c
@@ -55,9 +55,6 @@
#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 bcddddd..40846fb 100644
--- a/libc/include/android/api-level.h
+++ b/libc/include/android/api-level.h
@@ -151,6 +151,9 @@
/** 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 @@
#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 @@
#endif
+#endif /* defined(__ASSEMBLY__) */
+
__END_DECLS
/** @} */
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index a237254..598a50b 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -204,6 +204,60 @@
#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 56badf0..b56ca74 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 @@
// 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 @@
// 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 1e393eb..73cd821 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/platform/bionic/mte_kernel.h b/libc/platform/bionic/mte_kernel.h
deleted file mode 100644
index d81480a..0000000
--- a/libc/platform/bionic/mte_kernel.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#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
diff --git a/libc/private/bionic_asm.h b/libc/private/bionic_asm.h
index 6d4f7d5..d68a2d6 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_fdtrack.h b/libc/private/bionic_fdtrack.h
index 752dd8d..259897c 100644
--- a/libc/private/bionic_fdtrack.h
+++ b/libc/private/bionic_fdtrack.h
@@ -58,7 +58,7 @@
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 @@
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/bsd_sys_param.h b/libc/private/bsd_sys_param.h
new file mode 100644
index 0000000..8c936c4
--- /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 b8aced8..c7b1ba4 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 3cc3257..b928875 100644
--- a/libc/system_properties/context_lookup_benchmark_data.h
+++ b/libc/system_properties/context_lookup_benchmark_data.h
@@ -885,7 +885,6 @@
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 2fc5046..6c21c5b 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 @@
#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.
*/
diff --git a/linker/Android.bp b/linker/Android.bp
index 3ebae59..efda312 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -232,19 +232,15 @@
arch: {
arm: {
srcs: [":linker_sources_arm"],
- static_libs: ["libunwind_llvm"],
},
arm64: {
srcs: [":linker_sources_arm64"],
- static_libs: ["libgcc_stripped"],
},
x86: {
srcs: [":linker_sources_x86"],
- static_libs: ["libgcc_stripped"],
},
x86_64: {
srcs: [":linker_sources_x86_64"],
- static_libs: ["libgcc_stripped"],
},
},
@@ -292,6 +288,7 @@
"libc_nomalloc",
"libc_dynamic_dispatch",
"libm",
+ "libunwind",
],
// Ensure that if the linker needs __gnu_Unwind_Find_exidx, then the linker will have a
diff --git a/linker/dlfcn.cpp b/linker/dlfcn.cpp
index ec6850a..af05027 100644
--- a/linker/dlfcn.cpp
+++ b/linker/dlfcn.cpp
@@ -332,7 +332,8 @@
__libdl_info->target_sdk_version_ = __ANDROID_API__;
__libdl_info->generate_handle();
#if defined(__work_around_b_24465209__)
- strlcpy(__libdl_info->old_name_, __libdl_info->soname_, sizeof(__libdl_info->old_name_));
+ strlcpy(__libdl_info->old_name_, __libdl_info->soname_.c_str(),
+ sizeof(__libdl_info->old_name_));
#endif
}
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 2481be4..c240c56 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1339,8 +1339,7 @@
const char* name,
soinfo** candidate) {
return !ns->soinfo_list().visit([&](soinfo* si) {
- const char* soname = si->get_soname();
- if (soname != nullptr && (strcmp(name, soname) == 0)) {
+ if (strcmp(name, si->get_soname()) == 0) {
*candidate = si;
return false;
}
@@ -2571,9 +2570,8 @@
const char* target_soname = si_from->get_string(verneed->vn_file);
// find it in dependencies
- soinfo* target_si = si_from->get_children().find_if([&](const soinfo* si) {
- return si->get_soname() != nullptr && strcmp(si->get_soname(), target_soname) == 0;
- });
+ soinfo* target_si = si_from->get_children().find_if(
+ [&](const soinfo* si) { return strcmp(si->get_soname(), target_soname) == 0; });
if (target_si == nullptr) {
DL_ERR("cannot find \"%s\" from verneed[%zd] in DT_NEEDED list for \"%s\"",
@@ -3195,34 +3193,32 @@
return false;
}
- // second pass - parse entries relying on strtab
- for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
- switch (d->d_tag) {
- case DT_SONAME:
- set_soname(get_string(d->d_un.d_val));
- break;
- case DT_RUNPATH:
- set_dt_runpath(get_string(d->d_un.d_val));
- break;
+ // Second pass - parse entries relying on strtab. Skip this while relocating the linker so as to
+ // avoid doing heap allocations until later in the linker's initialization.
+ if (!relocating_linker) {
+ for (ElfW(Dyn)* d = dynamic; d->d_tag != DT_NULL; ++d) {
+ switch (d->d_tag) {
+ case DT_SONAME:
+ set_soname(get_string(d->d_un.d_val));
+ break;
+ case DT_RUNPATH:
+ set_dt_runpath(get_string(d->d_un.d_val));
+ break;
+ }
}
}
- // Before M release linker was using basename in place of soname.
- // In the case when dt_soname is absent some apps stop working
- // because they can't find dt_needed library by soname.
- // This workaround should keep them working. (Applies only
- // for apps targeting sdk version < M.) Make an exception for
- // the main executable and linker; they do not need to have dt_soname.
- // TODO: >= O the linker doesn't need this workaround.
- if (soname_ == nullptr &&
- this != solist_get_somain() &&
- (flags_ & FLAG_LINKER) == 0 &&
+ // Before M release, linker was using basename in place of soname. In the case when DT_SONAME is
+ // absent some apps stop working because they can't find DT_NEEDED library by soname. This
+ // workaround should keep them working. (Applies only for apps targeting sdk version < M.) Make
+ // an exception for the main executable, which does not need to have DT_SONAME. The linker has an
+ // DT_SONAME but the soname_ field is initialized later on.
+ if (soname_.empty() && this != solist_get_somain() && !relocating_linker &&
get_application_target_sdk_version() < 23) {
soname_ = basename(realpath_.c_str());
- DL_WARN_documented_change(23,
- "missing-soname-enforced-for-api-level-23",
- "\"%s\" has no DT_SONAME (will use %s instead)",
- get_realpath(), soname_);
+ DL_WARN_documented_change(23, "missing-soname-enforced-for-api-level-23",
+ "\"%s\" has no DT_SONAME (will use %s instead)", get_realpath(),
+ soname_.c_str());
// Don't call add_dlwarning because a missing DT_SONAME isn't important enough to show in the UI
}
diff --git a/linker/linker_cfi.cpp b/linker/linker_cfi.cpp
index 87b5d34..6bc2615 100644
--- a/linker/linker_cfi.cpp
+++ b/linker/linker_cfi.cpp
@@ -133,8 +133,7 @@
static soinfo* find_libdl(soinfo* solist) {
for (soinfo* si = solist; si != nullptr; si = si->next) {
- const char* soname = si->get_soname();
- if (soname && strcmp(soname, "libdl.so") == 0) {
+ if (strcmp(si->get_soname(), "libdl.so") == 0) {
return si;
}
}
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 59e8036..0b501a7 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -725,6 +725,13 @@
// Initialize the linker's own global variables
tmp_linker_so.call_constructors();
+ // Setting the linker soinfo's soname can allocate heap memory, so delay it until here.
+ for (const ElfW(Dyn)* d = tmp_linker_so.dynamic; d->d_tag != DT_NULL; ++d) {
+ if (d->d_tag == DT_SONAME) {
+ tmp_linker_so.set_soname(tmp_linker_so.get_string(d->d_un.d_val));
+ }
+ }
+
// When the linker is run directly rather than acting as PT_INTERP, parse
// arguments and determine the executable to load. When it's instead acting
// as PT_INTERP, AT_ENTRY will refer to the loaded executable rather than the
diff --git a/linker/linker_namespaces.h b/linker/linker_namespaces.h
index 77b6622..6817901 100644
--- a/linker/linker_namespaces.h
+++ b/linker/linker_namespaces.h
@@ -56,9 +56,6 @@
}
bool is_accessible(const char* soname) const {
- if (soname == nullptr) {
- return false;
- }
return allow_all_shared_libs_ || shared_lib_sonames_.find(soname) != shared_lib_sonames_.end();
}
diff --git a/linker/linker_soinfo.cpp b/linker/linker_soinfo.cpp
index 60fd242..287e757 100644
--- a/linker/linker_soinfo.cpp
+++ b/linker/linker_soinfo.cpp
@@ -485,11 +485,8 @@
}
template <typename F>
-static void call_array(const char* array_name __unused,
- F* functions,
- size_t count,
- bool reverse,
- const char* realpath) {
+static inline void call_array(const char* array_name __unused, F* functions, size_t count,
+ bool reverse, const char* realpath) {
if (functions == nullptr) {
return;
}
@@ -695,7 +692,7 @@
if (has_min_version(2)) {
soname_ = soname;
}
- strlcpy(old_name_, soname_, sizeof(old_name_));
+ strlcpy(old_name_, soname_.c_str(), sizeof(old_name_));
#else
soname_ = soname;
#endif
@@ -704,12 +701,12 @@
const char* soinfo::get_soname() const {
#if defined(__work_around_b_24465209__)
if (has_min_version(2)) {
- return soname_;
+ return soname_.c_str();
} else {
return old_name_;
}
#else
- return soname_;
+ return soname_.c_str();
#endif
}
diff --git a/linker/linker_soinfo.h b/linker/linker_soinfo.h
index 7372a51..9c589d6 100644
--- a/linker/linker_soinfo.h
+++ b/linker/linker_soinfo.h
@@ -401,7 +401,7 @@
uint8_t* android_relocs_;
size_t android_relocs_size_;
- const char* soname_;
+ std::string soname_;
std::string realpath_;
const ElfW(Versym)* versym_;
diff --git a/tests/Android.bp b/tests/Android.bp
index 477c8fc..678eae8 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -67,12 +67,6 @@
// Use the bootstrap version of bionic because some tests call private APIs
// that aren't exposed by the APEX bionic stubs.
bootstrap: true,
-
- product_variables: {
- experimental_mte: {
- cflags: ["-DANDROID_EXPERIMENTAL_MTE"],
- },
- },
}
// -----------------------------------------------------------------------------
@@ -851,66 +845,95 @@
"elftls_dlopen_ie_error_helper",
"exec_linker_helper",
"exec_linker_helper_lib",
- "libtest_dt_runpath_a",
- "libtest_dt_runpath_b",
- "libtest_dt_runpath_c",
- "libtest_dt_runpath_x",
- "libtest_dt_runpath_y",
+ "heap_tagging_async_helper",
+ "heap_tagging_disabled_helper",
+ "heap_tagging_static_async_helper",
+ "heap_tagging_static_disabled_helper",
+ "heap_tagging_static_sync_helper",
+ "heap_tagging_sync_helper",
+ "ld_config_test_helper",
+ "ld_config_test_helper_lib1",
+ "ld_config_test_helper_lib2",
+ "ld_config_test_helper_lib3",
+ "ld_preload_test_helper",
+ "ld_preload_test_helper_lib1",
+ "ld_preload_test_helper_lib2",
"libatest_simple_zip",
"libcfi-test",
"libcfi-test-bad",
+ "libdl_preempt_test_1",
+ "libdl_preempt_test_2",
+ "libdl_test_df_1_global",
+ "libdlext_test",
"libdlext_test_different_soname",
"libdlext_test_fd",
"libdlext_test_norelro",
"libdlext_test_recursive",
"libdlext_test_runpath_zip_zipaligned",
- "libdlext_test",
"libdlext_test_zip",
"libdlext_test_zip_zipaligned",
- "libdl_preempt_test_1",
- "libdl_preempt_test_2",
- "libdl_test_df_1_global",
"libgnu-hash-table-library",
- "librelocations-ANDROID_RELR",
+ "libns_hidden_child_app",
+ "libns_hidden_child_global",
+ "libns_hidden_child_internal",
+ "libns_hidden_child_public",
+ "libnstest_dlopened",
+ "libnstest_ns_a_public1",
+ "libnstest_ns_a_public1_internal",
+ "libnstest_ns_b_public2",
+ "libnstest_ns_b_public3",
+ "libnstest_private",
+ "libnstest_private_external",
+ "libnstest_public",
+ "libnstest_public_internal",
+ "libnstest_root",
+ "libnstest_root_not_isolated",
"librelocations-ANDROID_REL",
+ "librelocations-ANDROID_RELR",
"librelocations-RELR",
"librelocations-fat",
+ "libsegment_gap_inner",
+ "libsegment_gap_outer",
"libsysv-hash-table-library",
- "libtestshared",
"libtest_atexit",
+ "libtest_check_order_dlsym",
"libtest_check_order_dlsym_1_left",
"libtest_check_order_dlsym_2_right",
"libtest_check_order_dlsym_3_c",
"libtest_check_order_dlsym_a",
"libtest_check_order_dlsym_b",
"libtest_check_order_dlsym_d",
- "libtest_check_order_dlsym",
+ "libtest_check_order_reloc_root",
"libtest_check_order_reloc_root_1",
"libtest_check_order_reloc_root_2",
- "libtest_check_order_reloc_root",
+ "libtest_check_order_reloc_siblings",
"libtest_check_order_reloc_siblings_1",
"libtest_check_order_reloc_siblings_2",
"libtest_check_order_reloc_siblings_3",
"libtest_check_order_reloc_siblings_a",
"libtest_check_order_reloc_siblings_b",
+ "libtest_check_order_reloc_siblings_c",
"libtest_check_order_reloc_siblings_c_1",
"libtest_check_order_reloc_siblings_c_2",
- "libtest_check_order_reloc_siblings_c",
"libtest_check_order_reloc_siblings_d",
"libtest_check_order_reloc_siblings_e",
"libtest_check_order_reloc_siblings_f",
- "libtest_check_order_reloc_siblings",
"libtest_check_rtld_next_from_library",
"libtest_dlopen_df_1_global",
- "libtest_dlopen_from_ctor_main",
"libtest_dlopen_from_ctor",
+ "libtest_dlopen_from_ctor_main",
"libtest_dlopen_weak_undefined_func",
"libtest_dlsym_df_1_global",
+ "libtest_dlsym_from_this",
"libtest_dlsym_from_this_child",
"libtest_dlsym_from_this_grandchild",
- "libtest_dlsym_from_this",
"libtest_dlsym_weak_func",
+ "libtest_dt_runpath_a",
+ "libtest_dt_runpath_b",
+ "libtest_dt_runpath_c",
"libtest_dt_runpath_d",
+ "libtest_dt_runpath_x",
+ "libtest_dt_runpath_y",
"libtest_elftls_dynamic",
"libtest_elftls_dynamic_filler_1",
"libtest_elftls_dynamic_filler_2",
@@ -919,83 +942,60 @@
"libtest_elftls_shared_var_ie",
"libtest_elftls_tprel",
"libtest_empty",
- "libtest_ifunc_variable_impl",
- "libtest_ifunc_variable",
"libtest_ifunc",
+ "libtest_ifunc_variable",
+ "libtest_ifunc_variable_impl",
+ "libtest_indirect_thread_local_dtor",
"libtest_init_fini_order_child",
"libtest_init_fini_order_grand_child",
- "libtest_init_fini_order_root2",
"libtest_init_fini_order_root",
- "libtest_missing_symbol_child_public",
- "libtest_missing_symbol_child_private",
- "libtest_missing_symbol_root",
+ "libtest_init_fini_order_root2",
+ "libtest_invalid-empty_shdr_table",
+ "libtest_invalid-rw_load_segment",
+ "libtest_invalid-textrels",
+ "libtest_invalid-textrels2",
+ "libtest_invalid-unaligned_shdr_offset",
+ "libtest_invalid-zero_shdr_table_content",
+ "libtest_invalid-zero_shdr_table_offset",
+ "libtest_invalid-zero_shentsize",
+ "libtest_invalid-zero_shstrndx",
"libtest_missing_symbol",
+ "libtest_missing_symbol_child_private",
+ "libtest_missing_symbol_child_public",
+ "libtest_missing_symbol_root",
"libtest_nodelete_1",
"libtest_nodelete_2",
"libtest_nodelete_dt_flags_1",
"libtest_pthread_atfork",
+ "libtest_relo_check_dt_needed_order",
"libtest_relo_check_dt_needed_order_1",
"libtest_relo_check_dt_needed_order_2",
- "libtest_relo_check_dt_needed_order",
"libtest_simple",
+ "libtest_thread_local_dtor",
+ "libtest_thread_local_dtor2",
"libtest_two_parents_child",
"libtest_two_parents_parent1",
"libtest_two_parents_parent2",
"libtest_versioned_lib",
"libtest_versioned_libv1",
"libtest_versioned_libv2",
- "libtest_versioned_otherlib_empty",
"libtest_versioned_otherlib",
+ "libtest_versioned_otherlib_empty",
"libtest_versioned_uselibv1",
- "libtest_versioned_uselibv2_other",
"libtest_versioned_uselibv2",
+ "libtest_versioned_uselibv2_other",
"libtest_versioned_uselibv3_other",
+ "libtest_with_dependency",
+ "libtest_with_dependency_loop",
"libtest_with_dependency_loop_a",
"libtest_with_dependency_loop_b",
"libtest_with_dependency_loop_c",
- "libtest_with_dependency_loop",
- "libtest_with_dependency",
- "libtest_indirect_thread_local_dtor",
- "libtest_invalid-empty_shdr_table",
- "libtest_invalid-rw_load_segment",
- "libtest_invalid-unaligned_shdr_offset",
- "libtest_invalid-zero_shdr_table_content",
- "libtest_invalid-zero_shdr_table_offset",
- "libtest_invalid-zero_shentsize",
- "libtest_invalid-zero_shstrndx",
- "libtest_invalid-textrels",
- "libtest_invalid-textrels2",
- "libtest_thread_local_dtor",
- "libtest_thread_local_dtor2",
+ "libtestshared",
+ "ns_hidden_child_helper",
"preinit_getauxval_test_helper",
"preinit_syscall_test_helper",
- "libnstest_private_external",
- "libnstest_dlopened",
- "libnstest_private",
- "libnstest_root_not_isolated",
- "libnstest_root",
- "libnstest_public",
- "libnstest_public_internal",
- "libnstest_ns_a_public1",
- "libnstest_ns_a_public1_internal",
- "libnstest_ns_b_public2",
- "libnstest_ns_b_public3",
- "ns_hidden_child_helper",
- "libns_hidden_child_global",
- "libns_hidden_child_internal",
- "libns_hidden_child_public",
- "libns_hidden_child_app",
- "libsegment_gap_inner",
- "libsegment_gap_outer",
- "ld_preload_test_helper",
- "ld_preload_test_helper_lib1",
- "ld_preload_test_helper_lib2",
- "ld_config_test_helper",
- "ld_config_test_helper_lib1",
- "ld_config_test_helper_lib2",
- "ld_config_test_helper_lib3",
- "tls_properties_helper",
"thread_exit_cb_helper",
+ "tls_properties_helper",
],
}
diff --git a/tests/heap_tagging_level_test.cpp b/tests/heap_tagging_level_test.cpp
index 1dbf455..b3c8f22 100644
--- a/tests/heap_tagging_level_test.cpp
+++ b/tests/heap_tagging_level_test.cpp
@@ -15,10 +15,12 @@
*/
#include <gtest/gtest.h>
+
+#include <malloc.h>
#include <sys/prctl.h>
#if defined(__BIONIC__)
-#include "platform/bionic/malloc.h"
+#include "gtest_globals.h"
#include "platform/bionic/mte.h"
#include "utils.h"
@@ -36,7 +38,7 @@
}
static bool SetHeapTaggingLevel(HeapTaggingLevel level) {
- return android_mallopt(M_SET_HEAP_TAGGING_LEVEL, &level, sizeof(level));
+ return mallopt(M_BIONIC_SET_HEAP_TAGGING_LEVEL, level);
}
#endif
@@ -76,21 +78,22 @@
#endif // defined(__BIONIC__)
}
-#if defined(__BIONIC__) && defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE)
+#if defined(__BIONIC__) && defined(__aarch64__)
void ExitWithSiCode(int, siginfo_t* info, void*) {
_exit(info->si_code);
}
#endif
TEST(heap_tagging_level, sync_async_bad_accesses_die) {
-#if defined(__BIONIC__) && defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE)
+#if defined(__BIONIC__) && defined(__aarch64__)
if (!(getauxval(AT_HWCAP2) & HWCAP2_MTE)) {
GTEST_SKIP() << "requires MTE support";
}
std::unique_ptr<int[]> p = std::make_unique<int[]>(4);
- // First, check that memory tagging is enabled and the default tag checking level is async.
+ // First, check that memory tagging is enabled and the default tag checking level is sync.
+ // cc_test targets get sync MTE by default.
// We assume that scudo is used on all MTE enabled hardware; scudo inserts a header with a
// mismatching tag before each allocation.
EXPECT_EXIT(
@@ -98,18 +101,20 @@
ScopedSignalHandler ssh(SIGSEGV, ExitWithSiCode, SA_SIGINFO);
p[-1] = 42;
},
- testing::ExitedWithCode(SEGV_MTEAERR), "");
+ testing::ExitedWithCode(SEGV_MTESERR), "");
- EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_SYNC));
+ EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_ASYNC));
EXPECT_EXIT(
{
ScopedSignalHandler ssh(SIGSEGV, ExitWithSiCode, SA_SIGINFO);
p[-1] = 42;
},
- testing::ExitedWithCode(SEGV_MTESERR), "");
+ testing::ExitedWithCode(SEGV_MTEAERR), "");
EXPECT_TRUE(SetHeapTaggingLevel(M_HEAP_TAGGING_LEVEL_NONE));
volatile int oob ATTRIBUTE_UNUSED = p[-1];
+#else
+ GTEST_SKIP() << "bionic/arm64 only";
#endif
}
@@ -175,3 +180,34 @@
GTEST_SKIP() << "bionic/arm64 only";
#endif
}
+
+enum class MemtagNote { NONE, ASYNC, SYNC };
+class MemtagNoteTest : public testing::TestWithParam<std::tuple<MemtagNote, bool>> {};
+
+TEST_P(MemtagNoteTest, SEGV) {
+#if defined(__BIONIC__) && defined(__aarch64__)
+ if (!(getauxval(AT_HWCAP2) & HWCAP2_MTE)) {
+ GTEST_SKIP() << "requires MTE support";
+ }
+
+ const char* kNoteSuffix[] = {"disabled", "async", "sync"};
+ const char* kExpectedOutput[] = {"normal exit\n", "SEGV_MTEAERR\n", "SEGV_MTESERR\n"};
+
+ MemtagNote note = std::get<0>(GetParam());
+ bool isStatic = std::get<1>(GetParam());
+ std::string helper_base = std::string("heap_tagging_") + (isStatic ? "static_" : "") +
+ kNoteSuffix[static_cast<int>(note)] + "_helper";
+ fprintf(stderr, "=== %s\n", helper_base.c_str());
+ std::string helper = GetTestlibRoot() + "/" + helper_base + "/" + helper_base;
+ chmod(helper.c_str(), 0755);
+ ExecTestHelper eth;
+ eth.SetArgs({helper.c_str(), nullptr});
+ eth.Run([&]() { execve(helper.c_str(), eth.GetArgs(), eth.GetEnv()); }, 0,
+ kExpectedOutput[static_cast<int>(note)]);
+#endif
+}
+
+INSTANTIATE_TEST_SUITE_P(, MemtagNoteTest,
+ testing::Combine(testing::Values(MemtagNote::NONE, MemtagNote::ASYNC,
+ MemtagNote::SYNC),
+ testing::Bool()));
diff --git a/tests/libs/Android.bp b/tests/libs/Android.bp
index 4b86faf..385d120 100644
--- a/tests/libs/Android.bp
+++ b/tests/libs/Android.bp
@@ -1579,3 +1579,85 @@
defaults: ["bionic_testlib_defaults"],
srcs: ["relocations.cpp"],
}
+
+cc_defaults {
+ name: "bionic_targets_only",
+ enabled: false,
+ target: {
+ android: {
+ enabled: true,
+ },
+ linux_bionic: {
+ enabled: true,
+ },
+ },
+}
+
+cc_test {
+ name: "heap_tagging_sync_helper",
+ defaults: ["bionic_testlib_defaults", "bionic_targets_only"],
+ srcs: ["heap_tagging_helper.cpp"],
+ sanitize: {
+ memtag_heap: true,
+ diag: {
+ memtag_heap: true,
+ },
+ },
+}
+
+cc_test {
+ name: "heap_tagging_async_helper",
+ defaults: ["bionic_testlib_defaults", "bionic_targets_only"],
+ srcs: ["heap_tagging_helper.cpp"],
+ sanitize: {
+ memtag_heap: true,
+ diag: {
+ memtag_heap: false,
+ },
+ },
+}
+
+cc_test {
+ name: "heap_tagging_disabled_helper",
+ defaults: ["bionic_testlib_defaults", "bionic_targets_only"],
+ srcs: ["heap_tagging_helper.cpp"],
+ sanitize: {
+ memtag_heap: false,
+ },
+}
+
+cc_test {
+ name: "heap_tagging_static_sync_helper",
+ defaults: ["bionic_testlib_defaults", "bionic_targets_only"],
+ srcs: ["heap_tagging_helper.cpp"],
+ static_executable: true,
+ sanitize: {
+ memtag_heap: true,
+ diag: {
+ memtag_heap: true,
+ },
+ },
+}
+
+cc_test {
+ name: "heap_tagging_static_async_helper",
+ defaults: ["bionic_testlib_defaults", "bionic_targets_only"],
+ srcs: ["heap_tagging_helper.cpp"],
+ static_executable: true,
+ sanitize: {
+ memtag_heap: true,
+ diag: {
+ memtag_heap: false,
+ },
+ },
+}
+
+cc_test {
+ name: "heap_tagging_static_disabled_helper",
+ defaults: ["bionic_testlib_defaults", "bionic_targets_only"],
+ srcs: ["heap_tagging_helper.cpp"],
+ static_executable: true,
+ sanitize: {
+ memtag_heap: false,
+ },
+}
diff --git a/tests/libs/heap_tagging_helper.cpp b/tests/libs/heap_tagging_helper.cpp
new file mode 100644
index 0000000..1a970f2
--- /dev/null
+++ b/tests/libs/heap_tagging_helper.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+#include <signal.h>
+#include <stdio.h>
+#include <sys/cdefs.h>
+#include <unistd.h>
+#include <memory>
+
+void action(int signo, siginfo_t* info __unused, void*) {
+#ifdef __ANDROID__
+ if (signo == 11 && info->si_code == SEGV_MTEAERR) {
+ fprintf(stderr, "SEGV_MTEAERR\n");
+ _exit(0);
+ }
+
+ if (signo == 11 && info->si_code == SEGV_MTESERR) {
+ fprintf(stderr, "SEGV_MTESERR\n");
+ _exit(0);
+ }
+#endif
+
+ fprintf(stderr, "signo %d\n", signo);
+ _exit(0);
+}
+
+__attribute__((optnone)) int main() {
+ struct sigaction sa = {};
+ sa.sa_sigaction = action;
+ sa.sa_flags = SA_SIGINFO;
+ sigaction(SIGSEGV, &sa, nullptr);
+
+ std::unique_ptr<int[]> p = std::make_unique<int[]>(4);
+ volatile int oob = p[-1];
+ (void)oob;
+
+ fprintf(stderr, "normal exit\n");
+ return 0;
+}
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index ddd3416..b35bba9 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -47,7 +47,6 @@
#include "platform/bionic/malloc.h"
#include "platform/bionic/mte.h"
-#include "platform/bionic/mte_kernel.h"
#include "platform/bionic/reserved_signals.h"
#include "private/bionic_config.h"
@@ -1257,13 +1256,12 @@
#endif
}
-TEST(android_mallopt, disable_memory_mitigations) {
+TEST(malloc, disable_memory_mitigations) {
#if defined(__BIONIC__)
if (!mte_supported()) {
GTEST_SKIP() << "This function can only be tested with MTE";
}
-#ifdef ANDROID_EXPERIMENTAL_MTE
sem_t sem;
ASSERT_EQ(0, sem_init(&sem, 0, 0));
@@ -1277,7 +1275,7 @@
},
&sem));
- ASSERT_TRUE(android_mallopt(M_DISABLE_MEMORY_MITIGATIONS, nullptr, 0));
+ ASSERT_EQ(1, mallopt(M_BIONIC_DISABLE_MEMORY_MITIGATIONS, 0));
ASSERT_EQ(0, sem_post(&sem));
int my_tagged_addr_ctrl = prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0);
@@ -1287,7 +1285,6 @@
ASSERT_EQ(0, pthread_join(thread, &retval));
int thread_tagged_addr_ctrl = reinterpret_cast<uintptr_t>(retval);
ASSERT_EQ(my_tagged_addr_ctrl, thread_tagged_addr_ctrl);
-#endif
#else
GTEST_SKIP() << "bionic extension";
#endif
diff --git a/tests/stack_unwinding_test.cpp b/tests/stack_unwinding_test.cpp
index 0ff6f30..7fb2247 100644
--- a/tests/stack_unwinding_test.cpp
+++ b/tests/stack_unwinding_test.cpp
@@ -82,7 +82,7 @@
static UnwindData g_unwind_data;
-static void noinline UnwindSignalHandler(int) {
+__attribute__((unused)) static void noinline UnwindSignalHandler(int) {
_Unwind_Backtrace(FrameCounter, &g_unwind_data.handler_frame_count);
g_unwind_data.handler_one_deeper_frame_count = unwind_one_frame_deeper();
@@ -98,7 +98,7 @@
EXPECT_EQ(unwind_data.handler_frame_count + 1, unwind_data.handler_one_deeper_frame_count);
}
-static void noinline UnwindTest() {
+__attribute__((unused)) static void noinline UnwindTest() {
g_unwind_data = {};
_Unwind_Backtrace(FrameCounter, &g_unwind_data.expected_frame_count);
@@ -112,14 +112,24 @@
}
TEST(stack_unwinding, unwind_through_signal_frame) {
+#if defined(__aarch64__)
+ // A newer libunwind.a update should restore signal frame unwinding on arm64.
+ GTEST_SKIP() << "signal frame unwinding temporarily broken on arm64 -- b/153025717";
+#else
ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler);
UnwindTest();
+#endif
}
// On LP32, the SA_SIGINFO flag gets you __restore_rt instead of __restore.
TEST(stack_unwinding, unwind_through_signal_frame_SA_SIGINFO) {
+#if defined(__aarch64__)
+ // A newer libunwind.a update should restore signal frame unwinding on arm64.
+ GTEST_SKIP() << "signal frame unwinding temporarily broken on arm64 -- b/153025717";
+#else
ScopedSignalHandler ssh(SIGUSR1, UnwindSignalHandler, SA_SIGINFO);
UnwindTest();
+#endif
}
diff --git a/tools/versioner/src/Driver.cpp b/tools/versioner/src/Driver.cpp
index adf93c3..24dc5ec 100644
--- a/tools/versioner/src/Driver.cpp
+++ b/tools/versioner/src/Driver.cpp
@@ -149,7 +149,7 @@
cmd.push_back("-");
auto diags = constructDiags();
- driver::Driver driver("versioner", llvm::sys::getDefaultTargetTriple(), *diags, vfs);
+ driver::Driver driver("versioner", llvm::sys::getDefaultTargetTriple(), *diags, "versioner", vfs);
driver.setCheckInputsExist(false);
llvm::SmallVector<const char*, 32> driver_args;