Merge changes from topic "fusectl" into rvc-dev

* changes:
  Abort FUSE filesystems during shutdown.
  Abort FUSE filesystem when Zygote restarts.
  Mount fusectl filesystem.
diff --git a/adb/Android.bp b/adb/Android.bp
index cb5c1df..f8e5b38 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -567,7 +567,6 @@
 cc_binary {
     name: "adbd",
     defaults: ["adbd_defaults", "host_adbd_supported", "libadbd_binary_dependencies"],
-    stl: "libc++_static",
     recovery_available: true,
     apex_available: ["com.android.adbd"],
 
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index 7fff05a..a663871 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -231,7 +231,14 @@
                 offset += write_size;
             }
         }
-        SubmitWrites();
+
+        // Wake up the worker thread to submit writes.
+        uint64_t notify = 1;
+        ssize_t rc = adb_write(worker_event_fd_.get(), &notify, sizeof(notify));
+        if (rc < 0) {
+            PLOG(FATAL) << "failed to notify worker eventfd to submit writes";
+        }
+
         return true;
     }
 
@@ -443,6 +450,9 @@
                 }
 
                 ReadEvents();
+
+                std::lock_guard<std::mutex> lock(write_mutex_);
+                SubmitWrites();
             }
         });
     }
@@ -626,8 +636,6 @@
         write_requests_.erase(it);
         size_t outstanding_writes = --writes_submitted_;
         LOG(DEBUG) << "USB write: reaped, down to " << outstanding_writes;
-
-        SubmitWrites();
     }
 
     IoWriteBlock CreateWriteBlock(std::shared_ptr<Block> payload, size_t offset, size_t len,
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index f3f1cb7..fa4ac39 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -402,16 +402,17 @@
     return fstab_result;
 }
 
-// Identify path to fstab file. Lookup is based on pattern fstab.<hardware>,
-// fstab.<hardware.platform> in folders /odm/etc, vendor/etc, or /.
+// Identify path to fstab file. Lookup is based on pattern
+// fstab.<fstab_suffix>, fstab.<hardware>, fstab.<hardware.platform> in
+// folders /odm/etc, vendor/etc, or /.
 std::string GetFstabPath() {
-    for (const char* prop : {"hardware", "hardware.platform"}) {
-        std::string hw;
+    for (const char* prop : {"fstab_suffix", "hardware", "hardware.platform"}) {
+        std::string suffix;
 
-        if (!fs_mgr_get_boot_config(prop, &hw)) continue;
+        if (!fs_mgr_get_boot_config(prop, &suffix)) continue;
 
         for (const char* prefix : {"/odm/etc/fstab.", "/vendor/etc/fstab.", "/fstab."}) {
-            std::string fstab_path = prefix + hw;
+            std::string fstab_path = prefix + suffix;
             if (access(fstab_path.c_str(), F_OK) == 0) {
                 return fstab_path;
             }
diff --git a/init/README.md b/init/README.md
index b70366b..0dd1490 100644
--- a/init/README.md
+++ b/init/README.md
@@ -547,13 +547,16 @@
   * `ref`: use the systemwide DE key
   * `per_boot_ref`: use the key freshly generated on each boot.
 
-`mount_all <fstab> [ <path> ]\* [--<option>]`
+`mount_all [ <fstab> ] [--<option>]`
 > Calls fs\_mgr\_mount\_all on the given fs\_mgr-format fstab with optional
   options "early" and "late".
   With "--early" set, the init executable will skip mounting entries with
   "latemount" flag and triggering fs encryption state event. With "--late" set,
   init executable will only mount entries with "latemount" flag. By default,
   no option is set, and mount\_all will process all entries in the given fstab.
+  If the fstab parameter is not specified, fstab.${ro.boot.fstab_suffix},
+  fstab.${ro.hardware} or fstab.${ro.hardware.platform} will be scanned for
+  under /odm/etc, /vendor/etc, or / at runtime, in that order.
 
 `mount <type> <device> <dir> [ <flag>\* ] [<options>]`
 > Attempt to mount the named device at the directory _dir_
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 149a766..e918e12 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -518,21 +518,21 @@
 
 /* Imports .rc files from the specified paths. Default ones are applied if none is given.
  *
- * start_index: index of the first path in the args list
+ * rc_paths: list of paths to rc files to import
  */
-static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {
+static void import_late(const std::vector<std::string>& rc_paths) {
     auto& action_manager = ActionManager::GetInstance();
     auto& service_list = ServiceList::GetInstance();
     Parser parser = CreateParser(action_manager, service_list);
-    if (end_index <= start_index) {
+    if (rc_paths.empty()) {
         // Fallbacks for partitions on which early mount isn't enabled.
         for (const auto& path : late_import_paths) {
             parser.ParseConfig(path);
         }
         late_import_paths.clear();
     } else {
-        for (size_t i = start_index; i < end_index; ++i) {
-            parser.ParseConfig(args[i]);
+        for (const auto& rc_path : rc_paths) {
+            parser.ParseConfig(rc_path);
         }
     }
 
@@ -633,48 +633,44 @@
 
 static int initial_mount_fstab_return_code = -1;
 
-/* mount_all <fstab> [ <path> ]* [--<options>]*
+/* <= Q: mount_all <fstab> [ <path> ]* [--<options>]*
+ * >= R: mount_all [ <fstab> ] [--<options>]*
  *
  * This function might request a reboot, in which case it will
  * not return.
  */
 static Result<void> do_mount_all(const BuiltinArguments& args) {
-    std::size_t na = 0;
-    bool import_rc = true;
-    bool queue_event = true;
-    int mount_mode = MOUNT_MODE_DEFAULT;
-    const auto& fstab_file = args[1];
-    std::size_t path_arg_end = args.size();
-    const char* prop_post_fix = "default";
+    auto mount_all = ParseMountAll(args.args);
+    if (!mount_all.ok()) return mount_all.error();
 
-    for (na = args.size() - 1; na > 1; --na) {
-        if (args[na] == "--early") {
-            path_arg_end = na;
-            queue_event = false;
-            mount_mode = MOUNT_MODE_EARLY;
-            prop_post_fix = "early";
-        } else if (args[na] == "--late") {
-            path_arg_end = na;
-            import_rc = false;
-            mount_mode = MOUNT_MODE_LATE;
-            prop_post_fix = "late";
-        }
+    const char* prop_post_fix = "default";
+    bool queue_event = true;
+    if (mount_all->mode == MOUNT_MODE_EARLY) {
+        prop_post_fix = "early";
+        queue_event = false;
+    } else if (mount_all->mode == MOUNT_MODE_LATE) {
+        prop_post_fix = "late";
     }
 
     std::string prop_name = "ro.boottime.init.mount_all."s + prop_post_fix;
     android::base::Timer t;
 
     Fstab fstab;
-    if (!ReadFstabFromFile(fstab_file, &fstab)) {
-        return Error() << "Could not read fstab";
+    if (mount_all->fstab_path.empty()) {
+        if (!ReadDefaultFstab(&fstab)) {
+            return Error() << "Could not read default fstab";
+        }
+    } else {
+        if (!ReadFstabFromFile(mount_all->fstab_path, &fstab)) {
+            return Error() << "Could not read fstab";
+        }
     }
 
-    auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_mode);
+    auto mount_fstab_return_code = fs_mgr_mount_all(&fstab, mount_all->mode);
     SetProperty(prop_name, std::to_string(t.duration().count()));
 
-    if (import_rc && SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
-        /* Paths of .rc files are specified at the 2nd argument and beyond */
-        import_late(args.args, 2, path_arg_end);
+    if (mount_all->import_rc) {
+        import_late(mount_all->rc_paths);
     }
 
     if (queue_event) {
@@ -690,11 +686,20 @@
     return {};
 }
 
-/* umount_all <fstab> */
+/* umount_all [ <fstab> ] */
 static Result<void> do_umount_all(const BuiltinArguments& args) {
+    auto umount_all = ParseUmountAll(args.args);
+    if (!umount_all.ok()) return umount_all.error();
+
     Fstab fstab;
-    if (!ReadFstabFromFile(args[1], &fstab)) {
-        return Error() << "Could not read fstab";
+    if (umount_all->empty()) {
+        if (!ReadDefaultFstab(&fstab)) {
+            return Error() << "Could not read default fstab";
+        }
+    } else {
+        if (!ReadFstabFromFile(*umount_all, &fstab)) {
+            return Error() << "Could not read fstab";
+        }
     }
 
     if (auto result = fs_mgr_umount_all(&fstab); result != 0) {
@@ -1349,11 +1354,11 @@
         // mount_all is currently too complex to run in vendor_init as it queues action triggers,
         // imports rc scripts, etc.  It should be simplified and run in vendor_init context.
         // mount and umount are run in the same context as mount_all for symmetry.
-        {"mount_all",               {1,     kMax, {false,  do_mount_all}}},
+        {"mount_all",               {0,     kMax, {false,  do_mount_all}}},
         {"mount",                   {3,     kMax, {false,  do_mount}}},
         {"perform_apex_config",     {0,     0,    {false,  do_perform_apex_config}}},
         {"umount",                  {1,     1,    {false,  do_umount}}},
-        {"umount_all",              {1,     1,    {false,  do_umount_all}}},
+        {"umount_all",              {0,     1,    {false,  do_umount_all}}},
         {"update_linker_config",    {0,     0,    {false,  do_update_linker_config}}},
         {"readahead",               {1,     2,    {true,   do_readahead}}},
         {"remount_userdata",        {0,     0,    {false,  do_remount_userdata}}},
diff --git a/init/check_builtins.cpp b/init/check_builtins.cpp
index d1a84f3..450c079 100644
--- a/init/check_builtins.cpp
+++ b/init/check_builtins.cpp
@@ -123,6 +123,14 @@
     return {};
 }
 
+Result<void> check_mount_all(const BuiltinArguments& args) {
+    auto options = ParseMountAll(args.args);
+    if (!options.ok()) {
+        return options.error();
+    }
+    return {};
+}
+
 Result<void> check_mkdir(const BuiltinArguments& args) {
     auto options = ParseMkdir(args.args);
     if (!options.ok()) {
@@ -204,6 +212,14 @@
     return {};
 }
 
+Result<void> check_umount_all(const BuiltinArguments& args) {
+    auto options = ParseUmountAll(args.args);
+    if (!options.ok()) {
+        return options.error();
+    }
+    return {};
+}
+
 Result<void> check_wait(const BuiltinArguments& args) {
     if (args.size() == 3 && !args[2].empty()) {
         double timeout_double;
diff --git a/init/check_builtins.h b/init/check_builtins.h
index fb34556..725a6fd 100644
--- a/init/check_builtins.h
+++ b/init/check_builtins.h
@@ -32,11 +32,13 @@
 Result<void> check_load_system_props(const BuiltinArguments& args);
 Result<void> check_loglevel(const BuiltinArguments& args);
 Result<void> check_mkdir(const BuiltinArguments& args);
+Result<void> check_mount_all(const BuiltinArguments& args);
 Result<void> check_restorecon(const BuiltinArguments& args);
 Result<void> check_restorecon_recursive(const BuiltinArguments& args);
 Result<void> check_setprop(const BuiltinArguments& args);
 Result<void> check_setrlimit(const BuiltinArguments& args);
 Result<void> check_sysclktz(const BuiltinArguments& args);
+Result<void> check_umount_all(const BuiltinArguments& args);
 Result<void> check_wait(const BuiltinArguments& args);
 Result<void> check_wait_for_prop(const BuiltinArguments& args);
 
diff --git a/init/util.cpp b/init/util.cpp
index 24f94ec..90ac50c 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -570,6 +570,48 @@
     return MkdirOptions{args[1], mode, *uid, *gid, fscrypt_action, ref_option};
 }
 
+Result<MountAllOptions> ParseMountAll(const std::vector<std::string>& args) {
+    bool compat_mode = false;
+    bool import_rc = false;
+    if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
+        if (args.size() <= 1) {
+            return Error() << "mount_all requires at least 1 argument";
+        }
+        compat_mode = true;
+        import_rc = true;
+    }
+
+    std::size_t first_option_arg = args.size();
+    enum mount_mode mode = MOUNT_MODE_DEFAULT;
+
+    // If we are <= Q, then stop looking for non-fstab arguments at slot 2.
+    // Otherwise, stop looking at slot 1 (as the fstab path argument is optional >= R).
+    for (std::size_t na = args.size() - 1; na > (compat_mode ? 1 : 0); --na) {
+        if (args[na] == "--early") {
+            first_option_arg = na;
+            mode = MOUNT_MODE_EARLY;
+        } else if (args[na] == "--late") {
+            first_option_arg = na;
+            mode = MOUNT_MODE_LATE;
+            import_rc = false;
+        }
+    }
+
+    std::string fstab_path;
+    if (first_option_arg > 1) {
+        fstab_path = args[1];
+    } else if (compat_mode) {
+        return Error() << "mount_all argument 1 must be the fstab path";
+    }
+
+    std::vector<std::string> rc_paths;
+    for (std::size_t na = 2; na < first_option_arg; ++na) {
+        rc_paths.push_back(args[na]);
+    }
+
+    return MountAllOptions{rc_paths, fstab_path, mode, import_rc};
+}
+
 Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
         const std::vector<std::string>& args) {
     struct flag_type {
@@ -610,6 +652,15 @@
     return std::pair(flag, paths);
 }
 
+Result<std::string> ParseUmountAll(const std::vector<std::string>& args) {
+    if (SelinuxGetVendorAndroidVersion() <= __ANDROID_API_Q__) {
+        if (args.size() <= 1) {
+            return Error() << "umount_all requires at least 1 argument";
+        }
+    }
+    return args[1];
+}
+
 static void InitAborter(const char* abort_message) {
     // When init forks, it continues to use this aborter for LOG(FATAL), but we want children to
     // simply abort instead of trying to reboot the system.
diff --git a/init/util.h b/init/util.h
index ad322d9..a7f813b 100644
--- a/init/util.h
+++ b/init/util.h
@@ -22,6 +22,7 @@
 #include <chrono>
 #include <functional>
 #include <string>
+#include <vector>
 
 #include <android-base/chrono_utils.h>
 
@@ -33,6 +34,12 @@
 namespace android {
 namespace init {
 
+enum mount_mode {
+    MOUNT_MODE_DEFAULT = 0,
+    MOUNT_MODE_EARLY = 1,
+    MOUNT_MODE_LATE = 2,
+};
+
 static const char kColdBootDoneProp[] = "ro.cold_boot_done";
 
 extern void (*trigger_shutdown)(const std::string& command);
@@ -73,9 +80,20 @@
 
 Result<MkdirOptions> ParseMkdir(const std::vector<std::string>& args);
 
+struct MountAllOptions {
+    std::vector<std::string> rc_paths;
+    std::string fstab_path;
+    mount_mode mode;
+    bool import_rc;
+};
+
+Result<MountAllOptions> ParseMountAll(const std::vector<std::string>& args);
+
 Result<std::pair<int, std::vector<std::string>>> ParseRestorecon(
         const std::vector<std::string>& args);
 
+Result<std::string> ParseUmountAll(const std::vector<std::string>& args);
+
 void SetStdioToDevNull(char** argv);
 void InitKernelLogging(char** argv);
 bool IsRecoveryMode();
diff --git a/libstats/pull/Android.bp b/libstats/pull/Android.bp
index 2658639..a8b4a4f 100644
--- a/libstats/pull/Android.bp
+++ b/libstats/pull/Android.bp
@@ -85,13 +85,18 @@
         "libstatssocket",
     ],
     test_suites: ["general-tests", "mts"],
+    test_config: "libstatspull_test.xml",
+
     //TODO(b/153588990): Remove when the build system properly separates 
     //32bit and 64bit architectures.
     compile_multilib: "both",
     multilib: {
         lib64: {
             suffix: "64",
-        }
+        },
+        lib32: {
+            suffix: "32",
+        },
     },
     cflags: [
         "-Wall",
diff --git a/libstats/pull/libstatspull_test.xml b/libstats/pull/libstatspull_test.xml
new file mode 100644
index 0000000..233fc1f
--- /dev/null
+++ b/libstats/pull/libstatspull_test.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs libstatspull_test.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+    <option name="test-suite-tag" value="mts" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+       <option name="cleanup" value="true" />
+       <option name="push" value="libstatspull_test->/data/local/tmp/libstatspull_test" />
+       <option name="append-bitness" value="true" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="libstatspull_test" />
+    </test>
+
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
+        <option name="mainline-module-package-name" value="com.google.android.os.statsd" />
+    </object>
+</configuration>
diff --git a/libstats/socket/Android.bp b/libstats/socket/Android.bp
index 4e89b94..2bf0261 100644
--- a/libstats/socket/Android.bp
+++ b/libstats/socket/Android.bp
@@ -127,13 +127,17 @@
         "libutils",
     ],
     test_suites: ["device-tests", "mts"],
+    test_config: "libstatssocket_test.xml",
     //TODO(b/153588990): Remove when the build system properly separates 
     //32bit and 64bit architectures.
     compile_multilib: "both",
     multilib: {
         lib64: {
             suffix: "64",
-        }
+        },
+        lib32: {
+            suffix: "32",
+        },
     },
     require_root: true,
 }
diff --git a/libstats/socket/libstatssocket_test.xml b/libstats/socket/libstatssocket_test.xml
new file mode 100644
index 0000000..d2694d1
--- /dev/null
+++ b/libstats/socket/libstatssocket_test.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<configuration description="Runs libstatssocket_test.">
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="apct-native" />
+    <option name="test-suite-tag" value="mts" />
+
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
+    <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher">
+       <option name="cleanup" value="true" />
+       <option name="push" value="libstatssocket_test->/data/local/tmp/libstatssocket_test" />
+       <option name="append-bitness" value="true" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.GTest" >
+        <option name="native-test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="libstatssocket_test" />
+    </test>
+
+    <object type="module_controller" class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
+        <option name="mainline-module-package-name" value="com.google.android.os.statsd" />
+    </object>
+</configuration>
+
diff --git a/libutils/FileMap.cpp b/libutils/FileMap.cpp
index 1d899ab..0abb861 100644
--- a/libutils/FileMap.cpp
+++ b/libutils/FileMap.cpp
@@ -189,7 +189,11 @@
 
     int adjust = offset % mPageSize;
     off64_t adjOffset = offset - adjust;
-    size_t adjLength = length + adjust;
+    size_t adjLength;
+    if (__builtin_add_overflow(length, adjust, &adjLength)) {
+        ALOGE("adjusted length overflow: length %zu adjust %d", length, adjust);
+        return false;
+    }
 
     int flags = MAP_SHARED;
     int prot = PROT_READ;
diff --git a/libutils/FileMap_test.cpp b/libutils/FileMap_test.cpp
index 9f7ce85..fd1c9b0 100644
--- a/libutils/FileMap_test.cpp
+++ b/libutils/FileMap_test.cpp
@@ -52,3 +52,16 @@
     ASSERT_EQ(0u, m.getDataLength());
     ASSERT_EQ(offset, m.getDataOffset());
 }
+
+TEST(FileMap, offset_overflow) {
+    // Make sure that an end that overflows SIZE_MAX will not abort.
+    // See http://b/156997193.
+    TemporaryFile tf;
+    ASSERT_TRUE(tf.fd != -1);
+
+    off64_t offset = 200;
+    size_t length = SIZE_MAX;
+
+    android::FileMap m;
+    ASSERT_FALSE(m.create("test", tf.fd, offset, length, true));
+}