Merge "Reduce libziparchive internal hashtable memory size"
diff --git a/debuggerd/crash_dump.cpp b/debuggerd/crash_dump.cpp
index 93f7572..577e336 100644
--- a/debuggerd/crash_dump.cpp
+++ b/debuggerd/crash_dump.cpp
@@ -34,6 +34,7 @@
 
 #include <android-base/file.h>
 #include <android-base/logging.h>
+#include <android-base/macros.h>
 #include <android-base/parseint.h>
 #include <android-base/properties.h>
 #include <android-base/stringprintf.h>
@@ -282,6 +283,7 @@
   switch (crash_info->header.version) {
     case 2:
       *fdsan_table_address = crash_info->data.v2.fdsan_table_address;
+      FALLTHROUGH_INTENDED;
     case 1:
       *abort_msg_address = crash_info->data.v1.abort_msg_address;
       *siginfo = crash_info->data.v1.siginfo;
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index 388facb..bea8b43 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -37,6 +37,7 @@
 #include <android-base/macros.h>
 #include <android-base/parseint.h>
 #include <android-base/properties.h>
+#include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <android-base/test_utils.h>
 #include <android-base/unique_fd.h>
@@ -1053,3 +1054,42 @@
   ASSERT_TRUE(android::base::ReadFully(output_fd.get(), outbuf, sizeof(outbuf)));
   ASSERT_STREQ("any", outbuf);
 }
+
+TEST(tombstoned, interceptless_backtrace) {
+  // Generate 50 backtraces, and then check to see that we haven't created 50 new tombstones.
+  auto get_tombstone_timestamps = []() -> std::map<int, time_t> {
+    std::map<int, time_t> result;
+    for (int i = 0; i < 99; ++i) {
+      std::string path = android::base::StringPrintf("/data/tombstones/tombstone_%02d", i);
+      struct stat st;
+      if (stat(path.c_str(), &st) == 0) {
+        result[i] = st.st_mtim.tv_sec;
+      }
+    }
+    return result;
+  };
+
+  auto before = get_tombstone_timestamps();
+  for (int i = 0; i < 50; ++i) {
+    raise_debugger_signal(kDebuggerdNativeBacktrace);
+  }
+  auto after = get_tombstone_timestamps();
+
+  int diff = 0;
+  for (int i = 0; i < 99; ++i) {
+    if (after.count(i) == 0) {
+      continue;
+    }
+    if (before.count(i) == 0) {
+      ++diff;
+      continue;
+    }
+    if (before[i] != after[i]) {
+      ++diff;
+    }
+  }
+
+  // We can't be sure that nothing's crash looping in the background.
+  // This should be good enough, though...
+  ASSERT_LT(diff, 10) << "too many new tombstones; is something crashing in the background?";
+}
diff --git a/debuggerd/tombstoned/tombstoned.cpp b/debuggerd/tombstoned/tombstoned.cpp
index 15ae406..ad92067 100644
--- a/debuggerd/tombstoned/tombstoned.cpp
+++ b/debuggerd/tombstoned/tombstoned.cpp
@@ -212,8 +212,13 @@
   bool intercepted =
       intercept_manager->GetIntercept(crash->crash_pid, crash->crash_type, &output_fd);
   if (!intercepted) {
-    std::tie(crash->crash_tombstone_path, output_fd) = CrashQueue::for_crash(crash)->get_output();
-    crash->crash_tombstone_fd.reset(dup(output_fd.get()));
+    if (crash->crash_type == kDebuggerdNativeBacktrace) {
+      // Don't generate tombstones for native backtrace requests.
+      output_fd.reset(open("/dev/null", O_WRONLY | O_CLOEXEC));
+    } else {
+      std::tie(crash->crash_tombstone_path, output_fd) = CrashQueue::for_crash(crash)->get_output();
+      crash->crash_tombstone_fd.reset(dup(output_fd.get()));
+    }
   }
 
   TombstonedCrashPacket response = {
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 817afd0..8e6c125 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -148,6 +148,11 @@
     { nullptr,    "system_other.img", "system.sig",   "system",   true,  ImageType::Normal },
     { "userdata", "userdata.img",     "userdata.sig", "userdata", true,  ImageType::Extra },
     { "vbmeta",   "vbmeta.img",       "vbmeta.sig",   "vbmeta",   true,  ImageType::BootCritical },
+    { "vbmeta_mainline",
+                  "vbmeta_mainline.img",
+                                      "vbmeta_mainline.sig",
+                                                      "vbmeta_mainline",
+                                                                  true,  ImageType::BootCritical },
     { "vendor",   "vendor.img",       "vendor.sig",   "vendor",   true,  ImageType::Normal },
     { nullptr,    "vendor_other.img", "vendor.sig",   "vendor",   true,  ImageType::Normal },
         // clang-format on
diff --git a/init/Android.mk b/init/Android.mk
index dc400ad..5554995 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -61,9 +61,9 @@
 # Set up the same mount points on the ramdisk that system-as-root contains.
 LOCAL_POST_INSTALL_CMD := \
     mkdir -p $(TARGET_RAMDISK_OUT)/dev \
-    mkdir -p $(TARGET_RAMDISK_OUT)/mnt \
-    mkdir -p $(TARGET_RAMDISK_OUT)/proc \
-    mkdir -p $(TARGET_RAMDISK_OUT)/sys \
+    $(TARGET_RAMDISK_OUT)/mnt \
+    $(TARGET_RAMDISK_OUT)/proc \
+    $(TARGET_RAMDISK_OUT)/sys \
 
 LOCAL_STATIC_LIBRARIES := \
     libfs_mgr \
diff --git a/init/init.cpp b/init/init.cpp
index 3ab0a52..e5c1548 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -19,6 +19,7 @@
 #include <dirent.h>
 #include <fcntl.h>
 #include <pthread.h>
+#include <seccomp_policy.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
@@ -40,6 +41,7 @@
 #include <cutils/android_reboot.h>
 #include <keyutils.h>
 #include <libavb/libavb.h>
+#include <selinux/android.h>
 
 #ifndef RECOVERY
 #include <binder/ProcessState.h>
@@ -585,6 +587,43 @@
     android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
 }
 
+static void GlobalSeccomp() {
+    import_kernel_cmdline(false, [](const std::string& key, const std::string& value,
+                                    bool in_qemu) {
+        if (key == "androidboot.seccomp" && value == "global" && !set_global_seccomp_filter()) {
+            LOG(FATAL) << "Failed to globally enable seccomp!";
+        }
+    });
+}
+
+static void SetupSelinux(char** argv) {
+    android::base::InitLogging(argv, &android::base::KernelLogger, [](const char*) {
+        RebootSystem(ANDROID_RB_RESTART2, "bootloader");
+    });
+
+    // Set up SELinux, loading the SELinux policy.
+    SelinuxSetupKernelLogging();
+    SelinuxInitialize();
+
+    // We're in the kernel domain and want to transition to the init domain.  File systems that
+    // store SELabels in their xattrs, such as ext4 do not need an explicit restorecon here,
+    // but other file systems do.  In particular, this is needed for ramdisks such as the
+    // recovery image for A/B devices.
+    if (selinux_android_restorecon("/system/bin/init", 0) == -1) {
+        PLOG(FATAL) << "restorecon failed of /system/bin/init failed";
+    }
+
+    setenv("SELINUX_INITIALIZED", "true", 1);
+
+    const char* path = "/system/bin/init";
+    const char* args[] = {path, nullptr};
+    execv(path, const_cast<char**>(args));
+
+    // execv() only returns if an error happened, in which case we
+    // panic and never return from this function.
+    PLOG(FATAL) << "execv(\"" << path << "\") failed";
+}
+
 int main(int argc, char** argv) {
     if (!strcmp(basename(argv[0]), "ueventd")) {
         return ueventd_main(argc, argv);
@@ -600,9 +639,16 @@
         InstallRebootSignalHandlers();
     }
 
+    if (getenv("SELINUX_INITIALIZED") == nullptr) {
+        SetupSelinux(argv);
+    }
+
     InitKernelLogging(argv);
     LOG(INFO) << "init second stage started!";
 
+    // Enable seccomp if global boot option was passed (otherwise it is enabled in zygote).
+    GlobalSeccomp();
+
     // Set up a session keyring that all processes will have access to. It
     // will hold things like FBE encryption keys. No process should override
     // its session keyring.
@@ -631,6 +677,7 @@
     if (avb_version) property_set("ro.boot.avb_version", avb_version);
 
     // Clean up our environment.
+    unsetenv("SELINUX_INITIALIZED");
     unsetenv("INIT_STARTED_AT");
     unsetenv("INIT_SELINUX_TOOK");
     unsetenv("INIT_AVB_VERSION");
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index 466cde3..0c4a110 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -15,7 +15,6 @@
  */
 
 #include <paths.h>
-#include <seccomp_policy.h>
 #include <stdlib.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
@@ -30,11 +29,9 @@
 #include <android-base/logging.h>
 #include <cutils/android_reboot.h>
 #include <private/android_filesystem_config.h>
-#include <selinux/android.h>
 
 #include "first_stage_mount.h"
 #include "reboot_utils.h"
-#include "selinux.h"
 #include "util.h"
 
 using android::base::boot_clock;
@@ -42,15 +39,6 @@
 namespace android {
 namespace init {
 
-static void GlobalSeccomp() {
-    import_kernel_cmdline(false, [](const std::string& key, const std::string& value,
-                                    bool in_qemu) {
-        if (key == "androidboot.seccomp" && value == "global" && !set_global_seccomp_filter()) {
-            LOG(FATAL) << "Failed to globally enable seccomp!";
-        }
-    });
-}
-
 int main(int argc, char** argv) {
     if (REBOOT_BOOTLOADER_ON_PANIC) {
         InstallRebootSignalHandlers();
@@ -130,22 +118,6 @@
 
     SetInitAvbVersionInRecovery();
 
-    // Does this need to be done in first stage init or can it be done later?
-    // Enable seccomp if global boot option was passed (otherwise it is enabled in zygote).
-    GlobalSeccomp();
-
-    // Set up SELinux, loading the SELinux policy.
-    SelinuxSetupKernelLogging();
-    SelinuxInitialize();
-
-    // We're in the kernel domain and want to transition to the init domain when we exec second
-    // stage init.  File systems that store SELabels in their xattrs, such as ext4 do not need an
-    // explicit restorecon here, but other file systems do.  In particular, this is needed for
-    // ramdisks such as the recovery image for A/B devices.
-    if (selinux_android_restorecon("/system/bin/init", 0) == -1) {
-        PLOG(FATAL) << "restorecon failed of /system/bin/init failed";
-    }
-
     static constexpr uint32_t kNanosecondsPerMillisecond = 1e6;
     uint64_t start_ms = start_time.time_since_epoch().count() / kNanosecondsPerMillisecond;
     setenv("INIT_STARTED_AT", std::to_string(start_ms).c_str(), 1);
diff --git a/init/modalias_handler.cpp b/init/modalias_handler.cpp
index 1e0db57..c61c210 100644
--- a/init/modalias_handler.cpp
+++ b/init/modalias_handler.cpp
@@ -50,7 +50,7 @@
     }
 
     // Key is striped module name to match names in alias file
-    std::size_t start = args[0].find_last_of("/");
+    std::size_t start = args[0].find_last_of('/');
     std::size_t end = args[0].find(".ko:");
     if ((end - start) <= 1) return Error() << "malformed dependency line";
     auto mod_name = args[0].substr(start + 1, (end - start) - 1);
diff --git a/init/tokenizer.cpp b/init/tokenizer.cpp
index bb143f1..7e05a0a 100644
--- a/init/tokenizer.cpp
+++ b/init/tokenizer.cpp
@@ -1,5 +1,7 @@
 #include "tokenizer.h"
 
+#include <android-base/macros.h>
+
 namespace android {
 namespace init {
 
@@ -106,6 +108,7 @@
                     continue;
                 }
                 x++;
+                FALLTHROUGH_INTENDED;
             case '\n':
                     /* \ <lf> -> line continuation */
                 state->line++;
diff --git a/libunwindstack/DwarfSection.cpp b/libunwindstack/DwarfSection.cpp
index 6061f61..57a780e 100644
--- a/libunwindstack/DwarfSection.cpp
+++ b/libunwindstack/DwarfSection.cpp
@@ -461,6 +461,7 @@
       if (reg == eval_info->cie->return_address_register) {
         eval_info->return_address_undefined = true;
       }
+      break;
     default:
       break;
   }
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index f2892f8..d3e80c9 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -8,7 +8,6 @@
 dir.system = /system/bin/
 dir.system = /system/xbin/
 dir.system = /%PRODUCT%/bin/
-dir.system = /%PRODUCT_SERVICES%/bin/
 
 dir.vendor = /odm/bin/
 dir.vendor = /vendor/bin/
@@ -78,9 +77,9 @@
 namespace.default.asan.search.paths  = /data/asan/system/${LIB}
 namespace.default.asan.search.paths +=           /system/${LIB}
 namespace.default.asan.search.paths += /data/asan/product/${LIB}
-namespace.default.asan.search.paths +=           /product/${LIB}
+namespace.default.asan.search.paths +=           /%PRODUCT%/${LIB}
 namespace.default.asan.search.paths += /data/asan/product_services/${LIB}
-namespace.default.asan.search.paths +=           /product_services/${LIB}
+namespace.default.asan.search.paths +=           /%PRODUCT_SERVICES%/${LIB}
 
 namespace.default.asan.permitted.paths  = /data
 namespace.default.asan.permitted.paths += /system/${LIB}/drm
@@ -345,7 +344,9 @@
 namespace.system.asan.search.paths  = /data/asan/system/${LIB}
 namespace.system.asan.search.paths +=           /system/${LIB}
 namespace.system.asan.search.paths += /data/asan/product/${LIB}
-namespace.system.asan.search.paths +=           /product/${LIB}
+namespace.system.asan.search.paths +=           /%PRODUCT%/${LIB}
+namespace.system.asan.search.paths += /data/asan/product_services/${LIB}
+namespace.system.asan.search.paths +=           /%PRODUCT_SERVICES%/${LIB}
 
 ###############################################################################
 # Namespace config for binaries under /postinstall.
diff --git a/rootdir/etc/ld.config.vndk_lite.txt b/rootdir/etc/ld.config.vndk_lite.txt
index db65c14..7e354ac 100644
--- a/rootdir/etc/ld.config.vndk_lite.txt
+++ b/rootdir/etc/ld.config.vndk_lite.txt
@@ -7,7 +7,7 @@
 # absolute path of an executable is selected.
 dir.system = /system/bin/
 dir.system = /system/xbin/
-dir.system = /product/bin/
+dir.system = /%PRODUCT%/bin/
 
 dir.vendor = /odm/bin/
 dir.vendor = /vendor/bin/
@@ -41,7 +41,8 @@
 namespace.default.search.paths  = /system/${LIB}
 namespace.default.search.paths += /odm/${LIB}
 namespace.default.search.paths += /vendor/${LIB}
-namespace.default.search.paths += /product/${LIB}
+namespace.default.search.paths += /%PRODUCT%/${LIB}
+namespace.default.search.paths += /%PRODUCT_SERVICES%/${LIB}
 
 namespace.default.asan.search.paths  = /data/asan/system/${LIB}
 namespace.default.asan.search.paths +=           /system/${LIB}
@@ -50,7 +51,9 @@
 namespace.default.asan.search.paths += /data/asan/vendor/${LIB}
 namespace.default.asan.search.paths +=           /vendor/${LIB}
 namespace.default.asan.search.paths += /data/asan/product/${LIB}
-namespace.default.asan.search.paths +=           /product/${LIB}
+namespace.default.asan.search.paths +=           /%PRODUCT%/${LIB}
+namespace.default.asan.search.paths += /data/asan/product_services/${LIB}
+namespace.default.asan.search.paths +=           /%PRODUCT_SERVICES%/${LIB}
 
 ###############################################################################
 # "sphal" namespace
@@ -209,7 +212,8 @@
 namespace.default.search.paths += /system/${LIB}/vndk%VNDK_VER%
 namespace.default.search.paths += /system/${LIB}/vndk-sp%VNDK_VER%
 namespace.default.search.paths += /system/${LIB}
-namespace.default.search.paths += /product/${LIB}
+namespace.default.search.paths += /%PRODUCT%/${LIB}
+namespace.default.search.paths += /%PRODUCT_SERVICES%/${LIB}
 
 namespace.default.asan.search.paths  = /data/asan/odm/${LIB}
 namespace.default.asan.search.paths +=           /odm/${LIB}
@@ -230,7 +234,9 @@
 namespace.default.asan.search.paths += /data/asan/system/${LIB}
 namespace.default.asan.search.paths +=           /system/${LIB}
 namespace.default.asan.search.paths += /data/asan/product/${LIB}
-namespace.default.asan.search.paths +=           /product/${LIB}
+namespace.default.asan.search.paths +=           /%PRODUCT%/${LIB}
+namespace.default.asan.search.paths += /data/asan/product_services/${LIB}
+namespace.default.asan.search.paths +=           /%PRODUCT_SERVICES%/${LIB}
 
 ###############################################################################
 # Namespace config for binaries under /postinstall.
@@ -243,4 +249,5 @@
 [postinstall]
 namespace.default.isolated = false
 namespace.default.search.paths  = /system/${LIB}
-namespace.default.search.paths += /product/${LIB}
+namespace.default.search.paths += /%PRODUCT%/${LIB}
+namespace.default.search.paths += /%PRODUCT_SERVICES%/${LIB}
diff --git a/rootdir/etc/public.libraries.android.txt b/rootdir/etc/public.libraries.android.txt
index e20b95d..d8f6095 100644
--- a/rootdir/etc/public.libraries.android.txt
+++ b/rootdir/etc/public.libraries.android.txt
@@ -1,6 +1,7 @@
 # See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
 libandroid.so
 libaaudio.so
+libbinder_ndk.so
 libc.so
 libcamera2ndk.so
 libdl.so
diff --git a/rootdir/etc/public.libraries.iot.txt b/rootdir/etc/public.libraries.iot.txt
index ff0813d..20905bf 100644
--- a/rootdir/etc/public.libraries.iot.txt
+++ b/rootdir/etc/public.libraries.iot.txt
@@ -2,6 +2,7 @@
 libandroid.so
 libandroidthings.so
 libaaudio.so
+libbinder_ndk.so
 libc.so
 libcamera2ndk.so
 libdl.so
diff --git a/rootdir/etc/public.libraries.wear.txt b/rootdir/etc/public.libraries.wear.txt
index 3c46094..4ece5b5 100644
--- a/rootdir/etc/public.libraries.wear.txt
+++ b/rootdir/etc/public.libraries.wear.txt
@@ -1,6 +1,7 @@
 # See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
 libandroid.so
 libaaudio.so
+libbinder_ndk.so
 libc.so
 libcamera2ndk.so
 libdl.so