Merge "Disable strict abigail checking pending asm fix."
diff --git a/OWNERS b/OWNERS
index e02ad9f..670f88d 100644
--- a/OWNERS
+++ b/OWNERS
@@ -2,9 +2,5 @@
 
 cferris@google.com
 danalbert@google.com
-hhb@google.com
 rprichard@google.com
 yabinc@google.com
-
-# Still the best reviewer for changes related to the dynamic linker.
-dimitry@google.com
diff --git a/README.md b/README.md
index d96608e..f397fee 100644
--- a/README.md
+++ b/README.md
@@ -147,11 +147,11 @@
 The answer is "yes" if the system call is part of the POSIX standard.
 
 The answer is probably "yes" if the system call has a wrapper in at
-least one other C library.
+least one other C library (typically glibc/musl or Apple's libc).
 
 The answer may be "yes" if the system call has three/four distinct
-users in different projects, and there isn't a more specific library
-that would make more sense as the place to add the wrapper.
+users in different projects, and there isn't a more specific higher-level
+library that would make more sense as the place to add the wrapper.
 
 In all other cases, you should use
 [syscall(3)](http://man7.org/linux/man-pages/man2/syscall.2.html) instead.
@@ -166,14 +166,47 @@
      the appropriate POSIX header file in libc/include/ includes the
      relevant file or files.
   3. Add function declarations to the appropriate header file. Don't forget
-     to include the appropriate `__INTRODUCED_IN()`.
-  4. Add the function name to the correct section in libc/libc.map.txt.
-  5. Add at least basic tests. Even a test that deliberately supplies
-     an invalid argument helps check that we're generating the right symbol
-     and have the right declaration in the header file, and that you correctly
-     updated the maps in step 5. (You can use strace(1) to confirm that the
-     correct system call is being made.)
+     to include the appropriate `__INTRODUCED_IN()`. If you need to create a new
+     header file, libc/include/sys/sysinfo.h is a good short example to copy and
+     paste from.
+  4. Add basic documentation to the header file. libc/include/sys/sysinfo.h is a
+     good short example that shows the expected style. Most of the detail
+     should actually be left to the man7.org page, with only a brief
+     one-sentence explanation in our documentation. Alway include the return
+     value/error reporting details. Explicitly say which version of Android the
+     function was added to. Explicitly call out any Android-specific
+     changes/additions/limitations because they won't be on the man7.org page.
+  5. Add the function name to the correct section in libc/libc.map.txt.
+  6. Add a basic test. Don't try to test everything; concentrate on just testing
+     the code that's actually in *bionic*, not all the functionality that's
+     implemented in the kernel. For simple syscalls, that's just the
+     auto-generated argument and return value marshalling.
 
+     A trivial test that deliberately supplies an invalid argument helps check
+     that we're generating the right symbol and have the right declaration in
+     the header file, and that the change to libc.map.txt from step 5 is
+     correct. (You can use strace(1) manually to confirm that the correct
+     system call is being made.)
+
+     For testing the *kernel* side of things, we should prefer to rely on
+     https://github.com/linux-test-project/ltp for kernel testing, but you'll
+     want to check that external/ltp does contain tests for the syscall you're
+     adding. Also check that external/ltp is using the libc wrapper for the
+     syscall rather than calling it "directly" via syscall(3)!
+
+Some system calls are harder than others. The most common problem is a 64-bit
+argument such as `off64_t` (a *pointer* to a 64-bit argument is fine, since
+pointers are always the "natural" size for the architecture regardless of the
+size of the thing they point to). Whenever you have a function that takes
+`off_t` or `off64_t`, you'll need to consider whether you actually need a foo()
+and a foo64(), and whether they will use the same underlying system call or are
+implemented as two different system calls. It's usually easiest to find a
+similar system call and copy and paste from that. You'll definitely need to test
+both on 32-bit and 64-bit. (These special cases warrant more testing than the
+easy cases, even if only manual testing with strace. Sadly it isn't always
+feasible to write a working test for the interesting cases -- offsets larger
+than 2GiB, say -- so you may end up just writing a "meaningless" program whose
+only purpose is to give you patterns to look for when run under strace(1).)
 
 ## Updating kernel header files
 
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 65fc12b..2db0efe 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -40,10 +40,39 @@
       "name": "memunreachable_unit_test"
     }
   ],
-
-  "hwasan-postsubmit": [
+  "hwasan-presubmit": [
+    {
+      "name": "bionic-unit-tests"
+    },
+    {
+      "name": "bionic-unit-tests-static"
+    },
+    {
+      "name": "linker-unit-tests"
+    },
     {
       "name": "CtsBionicTestCases"
+    },
+    {
+      "name": "CtsGwpAsanTestCases"
+    },
+    {
+      "name": "debuggerd_test"
+    },
+    {
+      "name": "fdtrack_test"
+    },
+    {
+      "name": "gwp_asan_unittest"
+    },
+    {
+      "name": "malloc_debug_unit_tests"
+    },
+    {
+      "name": "malloc_debug_system_tests"
+    },
+    {
+      "name": "malloc_hooks_system_tests"
     }
   ]
 }
diff --git a/libc/async_safe/Android.bp b/libc/async_safe/Android.bp
index e4a5837..531317d 100644
--- a/libc/async_safe/Android.bp
+++ b/libc/async_safe/Android.bp
@@ -36,6 +36,7 @@
         "com.android.art.debug",
         "com.android.media",
         "com.android.media.swcodec",
+        "com.android.virt",
     ],
     min_sdk_version: "apex_inherit",
 }
diff --git a/libc/bionic/android_set_abort_message.cpp b/libc/bionic/android_set_abort_message.cpp
index 2ea12ee..d5f8cb9 100644
--- a/libc/bionic/android_set_abort_message.cpp
+++ b/libc/bionic/android_set_abort_message.cpp
@@ -77,6 +77,10 @@
     return;
   }
 
+  if (msg == nullptr) {
+    msg = "(null)";
+  }
+
   size_t size = sizeof(magic_abort_msg_t) + strlen(msg) + 1;
   void* map = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
   if (map == MAP_FAILED) {
diff --git a/libc/bionic/gwp_asan_wrappers.cpp b/libc/bionic/gwp_asan_wrappers.cpp
index 8c51347..79b4b69 100644
--- a/libc/bionic/gwp_asan_wrappers.cpp
+++ b/libc/bionic/gwp_asan_wrappers.cpp
@@ -144,10 +144,21 @@
 }
 
 void* gwp_asan_realloc(void* old_mem, size_t bytes) {
+  // GPA::pointerIsMine(p) always returns false where `p == nullptr` (and thus
+  // malloc(bytes) is requested). We always fall back to the backing allocator,
+  // technically missing some coverage, but reducing an extra conditional
+  // branch.
   if (__predict_false(GuardedAlloc.pointerIsMine(old_mem))) {
-    size_t old_size = GuardedAlloc.getSize(old_mem);
+    if (__predict_false(bytes == 0)) {
+      GuardedAlloc.deallocate(old_mem);
+      return nullptr;
+    }
     void* new_ptr = gwp_asan_malloc(bytes);
-    if (new_ptr) memcpy(new_ptr, old_mem, (bytes < old_size) ? bytes : old_size);
+    // If malloc() fails, then don't destroy the old memory.
+    if (__predict_false(new_ptr == nullptr)) return nullptr;
+
+    size_t old_size = GuardedAlloc.getSize(old_mem);
+    memcpy(new_ptr, old_mem, (bytes < old_size) ? bytes : old_size);
     GuardedAlloc.deallocate(old_mem);
     return new_ptr;
   }
diff --git a/libc/malloc_debug/Android.bp b/libc/malloc_debug/Android.bp
index f779b73..7ff3db2 100644
--- a/libc/malloc_debug/Android.bp
+++ b/libc/malloc_debug/Android.bp
@@ -166,6 +166,7 @@
 
     include_dirs: [
         "bionic/libc",
+        "bionic", // For SKIP_WITH_HWASAN.
     ],
 
     header_libs: [
diff --git a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
index eaf86c5..92679e4 100644
--- a/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_system_tests.cpp
@@ -41,6 +41,7 @@
 
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
+#include <android-base/test_utils.h>
 #include <gtest/gtest.h>
 #include <log/log_read.h>
 
@@ -55,6 +56,7 @@
 #include <backtrace/BacktraceMap.h>
 
 #include <bionic/malloc.h>
+#include <tests/utils.h>
 
 // All DISABLED_ tests are designed to be executed after malloc debug
 // is enabled. These tests don't run be default, and are executed
@@ -610,6 +612,7 @@
 }
 
 TEST_F(MallocDebugSystemTest, verify_leak_allocation_limit) {
+  SKIP_WITH_HWASAN;
   VerifyLeak("leak_memory_limit_");
 }
 
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 46de3e9..ea2dc78 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -40,6 +40,7 @@
 #include <android-base/file.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
+#include <android-base/test_utils.h>
 
 #include <platform/bionic/macros.h>
 #include <private/bionic_malloc_dispatch.h>
@@ -2063,6 +2064,7 @@
 }
 
 TEST_F(MallocDebugTest, debug_mallinfo) {
+  SKIP_WITH_HWASAN;
   Init("guard");
 
   void* pointer = debug_malloc(150);
@@ -2475,6 +2477,7 @@
 }
 
 TEST_F(MallocDebugTest, malloc_info_no_pointer_tracking) {
+  SKIP_WITH_HWASAN;
   Init("fill");
 
   TemporaryFile tf;
diff --git a/libc/malloc_hooks/tests/malloc_hooks_tests.cpp b/libc/malloc_hooks/tests/malloc_hooks_tests.cpp
index ca064c2..3ff2537 100644
--- a/libc/malloc_hooks/tests/malloc_hooks_tests.cpp
+++ b/libc/malloc_hooks/tests/malloc_hooks_tests.cpp
@@ -38,6 +38,7 @@
 
 #include <gtest/gtest.h>
 
+#include <android-base/test_utils.h>
 #include <bionic/malloc.h>
 #include <private/bionic_malloc_dispatch.h>
 #include <tests/utils.h>
@@ -178,6 +179,7 @@
 }
 
 TEST_F(MallocHooksTest, other_malloc_functions) {
+  SKIP_WITH_HWASAN; // HWASan does not implement mallinfo.
   RunTest("*.DISABLED_other_malloc_functions");
 }
 
diff --git a/linker/arch/arm_neon/linker_gnu_hash_neon.cpp b/linker/arch/arm_neon/linker_gnu_hash_neon.cpp
index 11cf5a3..159c66e 100644
--- a/linker/arch/arm_neon/linker_gnu_hash_neon.cpp
+++ b/linker/arch/arm_neon/linker_gnu_hash_neon.cpp
@@ -81,6 +81,8 @@
 //      return h;
 //    }
 //
+// This does an within-alignment out-of-bounds read for performance reasons.
+__attribute__((no_sanitize("hwaddress")))
 std::pair<uint32_t, uint32_t> calculate_gnu_hash_neon(const char* name) {
 
   // The input string may be misaligned by 0-7 bytes (K). This function loads the first aligned
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 3488f5c..c6588d2 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -3351,18 +3351,15 @@
 }
 
 // Given an `executable_path` starting with "/apex/<name>/bin/, return
-// "/linkerconfig/<name>/ld.config.txt" (or "/apex/<name>/etc/ld.config.txt", if
-// the former does not exist).
+// "/linkerconfig/<name>/ld.config.txt", which is the auto-generated config file for the APEX by the
+// linkerconfig tool.
 static std::string get_ld_config_file_apex_path(const char* executable_path) {
   std::vector<std::string> paths = android::base::Split(executable_path, "/");
   if (paths.size() >= 5 && paths[1] == "apex" && paths[3] == "bin") {
-    // Check auto-generated ld.config.txt first
     std::string generated_apex_config = "/linkerconfig/" + paths[2] + "/ld.config.txt";
     if (file_exists(generated_apex_config.c_str())) {
       return generated_apex_config;
     }
-
-    return std::string("/apex/") + paths[2] + "/etc/ld.config.txt";
   }
   return "";
 }
diff --git a/tests/Android.bp b/tests/Android.bp
index 48149c7..2ea6087 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -343,6 +343,7 @@
         "__cxa_demangle_test.cpp",
         "alloca_test.cpp",
         "android_get_device_api_level.cpp",
+        "android_set_abort_message_test.cpp",
         "arpa_inet_test.cpp",
         "async_safe_test.cpp",
         "assert_test.cpp",
diff --git a/tests/NOTICE b/tests/NOTICE
index c9b65d0..8c3483c 100644
--- a/tests/NOTICE
+++ b/tests/NOTICE
@@ -382,3 +382,31 @@
 
 -------------------------------------------------------------------
 
+Copyright (C) 2022 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.
+
+-------------------------------------------------------------------
+
diff --git a/tests/android_set_abort_message_test.cpp b/tests/android_set_abort_message_test.cpp
new file mode 100644
index 0000000..d6553de
--- /dev/null
+++ b/tests/android_set_abort_message_test.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2022 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 <sys/cdefs.h>
+
+#include <gtest/gtest.h>
+
+#if defined(__BIONIC__)
+extern "C" void android_set_abort_message(const char* msg);
+#endif
+
+TEST(android_set_abort_message_test, nullptr_check) {
+#if defined(__BIONIC__)
+  android_set_abort_message(nullptr);
+#else
+  GTEST_SKIP() << "This test is only supported on bionic.";
+#endif
+}
diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp
index bf32bd5..a61586b 100644
--- a/tests/dl_test.cpp
+++ b/tests/dl_test.cpp
@@ -34,6 +34,7 @@
 
 #include "gtest_globals.h"
 #include <android-base/file.h>
+#include <android-base/test_utils.h>
 #include "utils.h"
 
 extern "C" int main_global_default_serial() {
diff --git a/tests/getcwd_test.cpp b/tests/getcwd_test.cpp
index 97b1d4f..4fec40b 100644
--- a/tests/getcwd_test.cpp
+++ b/tests/getcwd_test.cpp
@@ -20,6 +20,8 @@
 #include <limits.h>
 #include <unistd.h>
 
+#include <android-base/test_utils.h>
+
 #include "utils.h"
 
 TEST(getcwd, auto_full) {
diff --git a/tests/headers/posix/stdio_h.c b/tests/headers/posix/stdio_h.c
index cbeb0bc..57be0a0 100644
--- a/tests/headers/posix/stdio_h.c
+++ b/tests/headers/posix/stdio_h.c
@@ -110,7 +110,8 @@
   FUNCTION(getchar_unlocked, int (*f)(void));
   FUNCTION(getdelim, ssize_t (*f)(char**, size_t*, int, FILE*));
   FUNCTION(getline, ssize_t (*f)(char**, size_t*, FILE*));
-  FUNCTION(gets, char* (*f)(char*));
+  // gets() was removed in C11.
+  // FUNCTION(gets, char* (*f)(char*));
   FUNCTION(open_memstream, FILE* (*f)(char**, size_t*));
   FUNCTION(pclose, int (*f)(FILE*));
   FUNCTION(perror, void (*f)(const char*));
diff --git a/tests/heap_tagging_level_test.cpp b/tests/heap_tagging_level_test.cpp
index c493e1d..96c2ffd 100644
--- a/tests/heap_tagging_level_test.cpp
+++ b/tests/heap_tagging_level_test.cpp
@@ -26,6 +26,7 @@
 
 #include "SignalUtils.h"
 
+#include <android-base/test_utils.h>
 #include <bionic/malloc_tagged_pointers.h>
 
 static bool KernelSupportsTaggedPointers() {
diff --git a/tests/malloc_iterate_test.cpp b/tests/malloc_iterate_test.cpp
index e896c90..297f637 100644
--- a/tests/malloc_iterate_test.cpp
+++ b/tests/malloc_iterate_test.cpp
@@ -26,6 +26,7 @@
 
 #include <vector>
 
+#include <android-base/test_utils.h>
 #include <async_safe/log.h>
 #include <procinfo/process_map.h>
 
diff --git a/tests/malloc_test.cpp b/tests/malloc_test.cpp
index f157ec4..1b875cd 100644
--- a/tests/malloc_test.cpp
+++ b/tests/malloc_test.cpp
@@ -41,6 +41,7 @@
 #include <tinyxml2.h>
 
 #include <android-base/file.h>
+#include <android-base/test_utils.h>
 
 #include "utils.h"
 
diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp
index ee126eb..472aa20 100644
--- a/tests/setjmp_test.cpp
+++ b/tests/setjmp_test.cpp
@@ -22,6 +22,7 @@
 #include <unistd.h>
 
 #include <android-base/silent_death_test.h>
+#include <android-base/test_utils.h>
 
 #include "SignalUtils.h"
 
@@ -273,6 +274,7 @@
 }
 
 TEST(setjmp, bug_152210274) {
+  SKIP_WITH_HWASAN; // b/227390656
   // Ensure that we never have a mangled value in the stack pointer.
 #if defined(__BIONIC__)
   struct sigaction sa = {.sa_flags = SA_SIGINFO, .sa_sigaction = [](int, siginfo_t*, void*) {}};
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 6dbd741..465e61a 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -33,6 +33,7 @@
 #include <android-base/file.h>
 #include <android-base/macros.h>
 #include <android-base/silent_death_test.h>
+#include <android-base/test_utils.h>
 #include <gtest/gtest.h>
 
 #include "math_data_test.h"
diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp
index c306a08..6d7e687 100644
--- a/tests/unistd_test.cpp
+++ b/tests/unistd_test.cpp
@@ -1529,11 +1529,21 @@
 }
 
 TEST(UNISTD_TEST, exec_argv0_null) {
-  // http://b/33276926
+  // http://b/33276926 and http://b/227498625.
+  //
+  // With old kernels, bionic will see the null pointer and use "<unknown>" but
+  // with new (5.18+) kernels, the kernel will already have substituted the
+  // empty string, so we don't make any assertion here about what (if anything)
+  // comes before the first ':'.
+  //
+  // If this ever causes trouble, we could change bionic to replace _either_ the
+  // null pointer or the empty string. We could also use the actual name from
+  // readlink() on /proc/self/exe if we ever had reason to disallow programs
+  // from trying to hide like this.
   char* args[] = {nullptr};
   char* envs[] = {nullptr};
   ASSERT_EXIT(execve("/system/bin/run-as", args, envs), testing::ExitedWithCode(1),
-              "<unknown>: usage: run-as");
+              ": usage: run-as");
 }
 
 TEST(UNISTD_TEST, fexecve_failure) {
diff --git a/tests/utils.h b/tests/utils.h
index 284140a..a62dde6 100644
--- a/tests/utils.h
+++ b/tests/utils.h
@@ -69,14 +69,6 @@
   return (dlopen("libc.so", 0) != nullptr);
 }
 
-extern "C" void __hwasan_init() __attribute__((weak));
-
-static inline bool running_with_hwasan() {
-  return &__hwasan_init != 0;
-}
-
-#define SKIP_WITH_HWASAN if (running_with_hwasan()) GTEST_SKIP()
-
 static inline bool running_with_native_bridge() {
 #if defined(__BIONIC__)
   static const prop_info* pi = __system_property_find("ro.dalvik.vm.isa." ABI_STRING);