Merge "Snap for 8253222 from 39837afad7ba9411445677497f8c60b01a0b4195 to sdk-release" into sdk-release
diff --git a/docs/status.md b/docs/status.md
index 9521da8..bf246a6 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -50,7 +50,7 @@
Current libc symbols: https://android.googlesource.com/platform/bionic/+/master/libc/libc.map.txt
-New libc functions in T (API level 32):
+New libc functions in T (API level 33):
* `backtrace`, `backtrace_symbols`, `backtrace_symbols_fd` (`<execinfo.h>`).
* New system call wrappers: `preadv2`, `preadv64v2`, `pwritev2`,
`pwritev64v2`.
diff --git a/libc/Android.bp b/libc/Android.bp
index f45b044..1c4876e 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -2615,10 +2615,6 @@
stl: "none",
}
-subdirs = [
- "bionic/scudo",
-]
-
// Export kernel uapi headers to be used in the musl sysroot.
// Also include the execinfo headers for the libexecinfo and the
// b64 headers for libb64 embedded in musl libc.
@@ -2639,8 +2635,6 @@
"execinfo/include/**/*.h",
"b64/include/**/*.h",
- // This file is used to identify the location of the bionic/libc directory
- // to simplify accessing the rest of the files.
"NOTICE",
":libc_musl_sysroot_bionic_arch_headers",
@@ -2653,6 +2647,8 @@
],
cmd: "BIONIC_LIBC_DIR=$$(dirname $(location NOTICE)) && " +
"$(location soong_zip) -o $(genDir)/sysroot.zip -symlinks=false" +
+ // NOTICE
+ " -j -f $(location NOTICE) " +
// headers
" -P include " +
" -C $${BIONIC_LIBC_DIR}/kernel/uapi " +
@@ -2666,7 +2662,11 @@
" -C $${BIONIC_LIBC_DIR}/b64/include " +
" -D $${BIONIC_LIBC_DIR}/b64/include " +
" && " +
- "$(location merge_zips) $(out) $(location :libc_musl_sysroot_bionic_arch_headers) $(genDir)/sysroot.zip",
+ "$(location zip2zip) -i $(genDir)/sysroot.zip -o $(genDir)/sysroot-renamed.zip " +
+ " include/**/*:include/ " +
+ " NOTICE:NOTICE.bionic " +
+ " && " +
+ "$(location merge_zips) $(out) $(location :libc_musl_sysroot_bionic_arch_headers) $(genDir)/sysroot-renamed.zip",
}
// The architecture-specific bits have to be handled separately because the label varies based
diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp
index 8b2a32b..2380e68 100644
--- a/libc/async_safe/async_safe_log.cpp
+++ b/libc/async_safe/async_safe_log.cpp
@@ -251,6 +251,7 @@
char sign = '\0';
int width = -1;
int prec = -1;
+ bool alternate = false;
size_t bytelen = sizeof(int);
int slen;
char buffer[32]; /* temporary buffer used to format numbers */
@@ -293,6 +294,9 @@
} else if (c == ' ' || c == '+') {
sign = c;
continue;
+ } else if (c == '#') {
+ alternate = true;
+ continue;
}
break;
}
@@ -344,9 +348,6 @@
if (c == 's') {
/* string */
str = va_arg(args, const char*);
- if (str == nullptr) {
- str = "(null)";
- }
} else if (c == 'c') {
/* character */
/* NOTE: char is promoted to int when passed through the stack */
@@ -357,6 +358,9 @@
buffer[0] = '0';
buffer[1] = 'x';
format_integer(buffer + 2, sizeof(buffer) - 2, value, 'x');
+ } else if (c == 'm') {
+ char buf[256];
+ str = strerror_r(errno, buf, sizeof(buf));
} else if (c == 'd' || c == 'i' || c == 'o' || c == 'u' || c == 'x' || c == 'X') {
/* integers - first read value from stack */
uint64_t value;
@@ -388,8 +392,19 @@
value = static_cast<uint64_t>((static_cast<int64_t>(value << shift)) >> shift);
}
- /* format the number properly into our buffer */
- format_integer(buffer, sizeof(buffer), value, c);
+ if (alternate && value != 0 && (c == 'x' || c == 'o')) {
+ if (c == 'x') {
+ buffer[0] = '0';
+ buffer[1] = 'x';
+ format_integer(buffer + 2, sizeof(buffer) - 2, value, c);
+ } else {
+ buffer[0] = '0';
+ format_integer(buffer + 1, sizeof(buffer) - 1, value, c);
+ }
+ } else {
+ /* format the number properly into our buffer */
+ format_integer(buffer, sizeof(buffer), value, c);
+ }
} else if (c == '%') {
buffer[0] = '%';
buffer[1] = '\0';
@@ -397,6 +412,10 @@
__assert(__FILE__, __LINE__, "conversion specifier unsupported");
}
+ if (str == nullptr) {
+ str = "(null)";
+ }
+
/* if we are here, 'str' points to the content that must be
* outputted. handle padding and alignment now */
diff --git a/libc/bionic/android_profiling_dynamic.cpp b/libc/bionic/android_profiling_dynamic.cpp
index 4fafd67..3460a6d 100644
--- a/libc/bionic/android_profiling_dynamic.cpp
+++ b/libc/bionic/android_profiling_dynamic.cpp
@@ -33,6 +33,7 @@
#include <fcntl.h>
#include <signal.h>
#include <string.h>
+#include <sys/prctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -137,13 +138,25 @@
return;
}
+ // If the process is undumpable, /proc/self/mem will be owned by root:root, and therefore
+ // inaccessible to the process itself (see man 5 proc). We temporarily mark the process as
+ // dumpable to allow for the open. Note: prctl is not async signal safe per posix, but bionic's
+ // implementation is. Error checking on prctls is omitted due to them being trivial.
+ int orig_dumpable = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
+ if (!orig_dumpable) {
+ prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
+ }
ScopedFd maps_fd{ open("/proc/self/maps", O_RDONLY | O_CLOEXEC) };
+ ScopedFd mem_fd{ open("/proc/self/mem", O_RDONLY | O_CLOEXEC) };
+ if (!orig_dumpable) {
+ prctl(PR_SET_DUMPABLE, orig_dumpable, 0, 0, 0);
+ }
+
if (maps_fd.get() == -1) {
async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/maps: %s",
strerror(errno));
return;
}
- ScopedFd mem_fd{ open("/proc/self/mem", O_RDONLY | O_CLOEXEC) };
if (mem_fd.get() == -1) {
async_safe_format_log(ANDROID_LOG_ERROR, "libc", "failed to open /proc/self/mem: %s",
strerror(errno));
diff --git a/libc/bionic/spawn.cpp b/libc/bionic/spawn.cpp
index e73828f..2067a1a 100644
--- a/libc/bionic/spawn.cpp
+++ b/libc/bionic/spawn.cpp
@@ -69,7 +69,17 @@
// Failure to close is ignored.
close(fd);
} else {
- if (dup2(fd, new_fd) == -1) _exit(127);
+ // It's a dup2.
+ if (fd == new_fd) {
+ // dup2(2) is a no-op if fd == new_fd, but POSIX suggests that we should
+ // manually remove the O_CLOEXEC flag in that case (because otherwise
+ // what use is the dup?).
+ // See https://www.austingroupbugs.net/view.php?id=411 for details.
+ int flags = fcntl(fd, F_GETFD, 0);
+ if (flags == -1 || fcntl(fd, F_SETFD, flags & ~FD_CLOEXEC) == -1) _exit(127);
+ } else {
+ if (dup2(fd, new_fd) == -1) _exit(127);
+ }
}
}
};
diff --git a/libc/include/sys/cdefs.h b/libc/include/sys/cdefs.h
index 99a200a..5b9d99b 100644
--- a/libc/include/sys/cdefs.h
+++ b/libc/include/sys/cdefs.h
@@ -327,12 +327,7 @@
#define __overloadable __attribute__((overloadable))
-// TODO(pirama) Remove this version check after switching to clang-r445002
-#if __clang_major__ == 14 && __clang_patchlevel__ >= 2
#define __diagnose_as_builtin(...) __attribute__((diagnose_as_builtin(__VA_ARGS__)))
-#else
-#define __diagnose_as_builtin(...)
-#endif
/* Used to tag non-static symbols that are private and never exposed by the shared library. */
#define __LIBC_HIDDEN__ __attribute__((visibility("hidden")))
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index da26d15..662f5f8 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -641,6 +641,13 @@
for the best way to use malloc debug in Android O or later on non-rooted
devices.
+**NOTE**: Android 12 introduced a bug that can cause the wrap.\<APP\> property to
+no longer work. Use the commands below so that the wrap.\<APP\> instructions will work:
+
+ adb shell setprop dalvik.vm.force-java-zygote-fork-loop true
+ adb shell stop
+ adb shell start
+
If you do have a rooted device, you can enable malloc debug for a specific
program/application (Android O or later):
diff --git a/tests/Android.bp b/tests/Android.bp
index b30eac9..3061142 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -493,6 +493,12 @@
},
generated_headers: ["generated_android_ids"],
+
+ // Bug: http://b/218788252 IR verifier too strict for ifunc resolver that
+ // accept parameters.
+ lto: {
+ never: true,
+ },
}
cc_test_library {
diff --git a/tests/async_safe_test.cpp b/tests/async_safe_test.cpp
index 6c4758e..f52387e 100644
--- a/tests/async_safe_test.cpp
+++ b/tests/async_safe_test.cpp
@@ -64,6 +64,10 @@
async_safe_format_buffer(buf, sizeof(buf), "a%ldb", 70000L);
EXPECT_STREQ("a70000b", buf);
+ errno = EINVAL;
+ async_safe_format_buffer(buf, sizeof(buf), "a%mZ");
+ EXPECT_STREQ("aInvalid argumentZ", buf);
+
async_safe_format_buffer(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234));
EXPECT_STREQ("a0xb0001234b", buf);
@@ -97,6 +101,30 @@
async_safe_format_buffer(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5);
EXPECT_STREQ("a005:5:05z", buf);
+ async_safe_format_buffer(buf, sizeof(buf), "a%#xZ", 34);
+ EXPECT_STREQ("a0x22Z", buf);
+
+ async_safe_format_buffer(buf, sizeof(buf), "a%#xZ", 0);
+ EXPECT_STREQ("a0Z", buf);
+
+ async_safe_format_buffer(buf, sizeof(buf), "a%#5xZ", 20);
+ EXPECT_STREQ("a 0x14Z", buf);
+
+ snprintf(buf, sizeof(buf), "a%#08.8xZ", 1);
+ EXPECT_STREQ("a0x00000001Z", buf);
+
+ async_safe_format_buffer(buf, sizeof(buf), "a%#oZ", 777);
+ EXPECT_STREQ("a01411Z", buf);
+
+ async_safe_format_buffer(buf, sizeof(buf), "a%#oZ", 0);
+ EXPECT_STREQ("a0Z", buf);
+
+ async_safe_format_buffer(buf, sizeof(buf), "a%#6oZ", 15);
+ EXPECT_STREQ("a 017Z", buf);
+
+ snprintf(buf, sizeof(buf), "a%#08.8oZ", 11);
+ EXPECT_STREQ("a00000013Z", buf);
+
void* p = nullptr;
async_safe_format_buffer(buf, sizeof(buf), "a%d,%pz", 5, p);
EXPECT_STREQ("a5,0x0z", buf);
diff --git a/tests/cfi_test.cpp b/tests/cfi_test.cpp
index dd65a81..1c45946 100644
--- a/tests/cfi_test.cpp
+++ b/tests/cfi_test.cpp
@@ -19,7 +19,6 @@
#include <vector>
-#include <android-base/silent_death_test.h>
#include <gtest/gtest.h>
#include "gtest_globals.h"
@@ -36,7 +35,45 @@
size_t __cfi_shadow_size();
}
-using cfi_test_DeathTest = SilentDeathTest;
+// Disables debuggerd stack traces to speed up death tests, make them less
+// noisy in logcat, and avoid expected deaths from showing up in stability
+// metrics.
+// We don't use the usual libbase class because (a) we don't care about most
+// of the signals it blocks but (b) we do need to block SIGILL, which normal
+// death tests shouldn't ever hit. (It's possible that a design where a
+// deathtest always declares its expected signals up front is a better one,
+// and maybe that's an interesting future direction for libbase.)
+//
+// We include SIGSEGV because there's a test that passes heap addresses to
+// __cfi_slowpath and we only map the executable code shadow as readable.
+// We don't always get SIGSEGV there though: if the heap allocation happens
+// to be close enough to an executable mapping that its shadow is in the
+// same page as the executable shadow, we'll get SIGILL/SIGTRAP.
+class cfi_test_DeathTest : public testing::Test {
+ protected:
+ void SetUp() override {
+ struct sigaction64 action = {.sa_handler = SIG_DFL};
+ sigaction64(SIGILL, &action, &previous_sigill_);
+ sigaction64(SIGSEGV, &action, &previous_sigsegv_);
+ sigaction64(SIGTRAP, &action, &previous_sigtrap_);
+ }
+
+ void TearDown() override {
+ sigaction64(SIGTRAP, &previous_sigtrap_, nullptr);
+ sigaction64(SIGSEGV, &previous_sigsegv_, nullptr);
+ sigaction64(SIGILL, &previous_sigill_, nullptr);
+ }
+
+ private:
+ struct sigaction64 previous_sigill_;
+ struct sigaction64 previous_sigsegv_;
+ struct sigaction64 previous_sigtrap_;
+};
+
+static bool KilledByCfi(int status) {
+ return WIFSIGNALED(status) &&
+ (WTERMSIG(status) == SIGTRAP || WTERMSIG(status) == SIGILL || WTERMSIG(status) == SIGSEGV);
+}
static void f() {}
@@ -102,7 +139,7 @@
// It's possible that this allocation could wind up in the same CFI granule as
// an unchecked library, which means the below might not crash. To force a
// crash keep allocating up to a max until there is a crash.
- EXPECT_DEATH(test_cfi_slowpath_with_alloc(), "");
+ EXPECT_EXIT(test_cfi_slowpath_with_alloc(), KilledByCfi, "");
// Check all the addresses.
const size_t bss_size = 1024 * 1024;
@@ -128,7 +165,7 @@
// CFI check for a function inside the unloaded DSO. This is always invalid and gets the process
// killed.
- EXPECT_DEATH(__cfi_slowpath(45, reinterpret_cast<void*>(code_ptr)), "");
+ EXPECT_EXIT(__cfi_slowpath(45, reinterpret_cast<void*>(code_ptr)), KilledByCfi, "");
#endif
}
diff --git a/tests/dlfcn_test.cpp b/tests/dlfcn_test.cpp
index 0bf8775..e3664fd 100644
--- a/tests/dlfcn_test.cpp
+++ b/tests/dlfcn_test.cpp
@@ -258,6 +258,9 @@
dlclose(handle);
}
+// HWASan uses an ifunc to describe the location of its shadow memory,
+// so even though it's an unusual case, Android needs to support
+// "ifunc variables".
TEST(dlfcn, ifunc_variable) {
typedef const char* (*fn_ptr)();
diff --git a/tests/libs/dlopen_testlib_ifunc_variable_impl.cpp b/tests/libs/dlopen_testlib_ifunc_variable_impl.cpp
index 4b13eba..624ae74 100644
--- a/tests/libs/dlopen_testlib_ifunc_variable_impl.cpp
+++ b/tests/libs/dlopen_testlib_ifunc_variable_impl.cpp
@@ -43,11 +43,13 @@
extern "C" const char* v1 = "unset";
extern "C" const char* v2 = "set";
-extern "C" void* is_ctor_called_ifun() {
- return g_flag == 0 ? &var_false : &var_true;
+typedef const char* (*fn_ptr)();
+
+extern "C" fn_ptr is_ctor_called_ifun() {
+ return (fn_ptr)(g_flag == 0 ? &var_false : &var_true);
}
-extern "C" void* foo_ifunc() {
- char* choice = getenv("IFUNC_CHOICE");
- return choice == nullptr ? &v1 : &v2;
+extern "C" fn_ptr foo_ifunc() {
+ char* choice = getenv("IFUNC_CHOICE");
+ return (fn_ptr)(choice == nullptr ? &v1 : &v2);
}
diff --git a/tests/spawn_test.cpp b/tests/spawn_test.cpp
index f3c5b9a..a9563b8 100644
--- a/tests/spawn_test.cpp
+++ b/tests/spawn_test.cpp
@@ -508,3 +508,42 @@
AssertChildExited(pid, 99);
}
+
+TEST(spawn, posix_spawn_dup2_CLOEXEC) {
+ int fds[2];
+ ASSERT_NE(-1, pipe(fds));
+
+ posix_spawn_file_actions_t fa;
+ ASSERT_EQ(0, posix_spawn_file_actions_init(&fa));
+
+ int fd = open("/proc/version", O_RDONLY | O_CLOEXEC);
+ ASSERT_NE(-1, fd);
+
+ ASSERT_EQ(0, posix_spawn_file_actions_addclose(&fa, fds[0]));
+ ASSERT_EQ(0, posix_spawn_file_actions_adddup2(&fa, fds[1], 1));
+ // dup2() is a no-op when the two fds are the same, so this won't clear
+ // O_CLOEXEC unless we're doing extra work to make that happen.
+ ASSERT_EQ(0, posix_spawn_file_actions_adddup2(&fa, fd, fd));
+
+ // Read /proc/self/fd/<fd> in the child...
+ std::string fdinfo_path = android::base::StringPrintf("/proc/self/fd/%d", fd);
+ ExecTestHelper eth;
+ eth.SetArgs({"cat", fdinfo_path.c_str(), nullptr});
+ pid_t pid;
+ ASSERT_EQ(0, posix_spawnp(&pid, eth.GetArg0(), &fa, nullptr, eth.GetArgs(), eth.GetEnv()));
+ ASSERT_EQ(0, posix_spawn_file_actions_destroy(&fa));
+ ASSERT_EQ(0, close(fds[1]));
+ std::string content;
+ ASSERT_TRUE(android::base::ReadFdToString(fds[0], &content));
+ ASSERT_EQ(0, close(fds[0]));
+
+ // ...and compare that to the parent. This is overkill really, since the very
+ // fact that the child had a valid file descriptor strongly implies that we
+ // removed O_CLOEXEC, but we may as well check that the child ended up with
+ // the *right* file descriptor :-)
+ std::string expected;
+ ASSERT_TRUE(android::base::ReadFdToString(fd, &expected));
+ ASSERT_EQ(expected, content);
+
+ AssertChildExited(pid, 0);
+}