Merge "storageproxyd: Remove setuid, setgid, and capset"
diff --git a/fs_mgr/fs_mgr_fstab.cpp b/fs_mgr/fs_mgr_fstab.cpp
index f1071b0..43961da 100644
--- a/fs_mgr/fs_mgr_fstab.cpp
+++ b/fs_mgr/fs_mgr_fstab.cpp
@@ -439,34 +439,6 @@
     return fstab_result;
 }
 
-// Return the path to the fstab file.  There may be multiple fstab files; the
-// one that is returned will be the first that exists of fstab.<fstab_suffix>,
-// fstab.<hardware>, and fstab.<hardware.platform>.  The fstab is searched for
-// in /odm/etc/ and /vendor/etc/, as well as in the locations where it may be in
-// the first stage ramdisk during early boot.  Previously, the first stage
-// ramdisk's copy of the fstab had to be located in the root directory, but now
-// the system/etc directory is supported too and is the preferred location.
-std::string GetFstabPath() {
-    for (const char* prop : {"fstab_suffix", "hardware", "hardware.platform"}) {
-        std::string suffix;
-
-        if (!fs_mgr_get_boot_config(prop, &suffix)) continue;
-
-        for (const char* prefix : {// late-boot/post-boot locations
-                                   "/odm/etc/fstab.", "/vendor/etc/fstab.",
-                                   // early boot locations
-                                   "/system/etc/fstab.", "/first_stage_ramdisk/system/etc/fstab.",
-                                   "/fstab.", "/first_stage_ramdisk/fstab."}) {
-            std::string fstab_path = prefix + suffix;
-            if (access(fstab_path.c_str(), F_OK) == 0) {
-                return fstab_path;
-            }
-        }
-    }
-
-    return "";
-}
-
 /* Extracts <device>s from the by-name symlinks specified in a fstab:
  *   /dev/block/<type>/<device>/by-name/<partition>
  *
@@ -526,6 +498,34 @@
 
 }  // namespace
 
+// Return the path to the fstab file.  There may be multiple fstab files; the
+// one that is returned will be the first that exists of fstab.<fstab_suffix>,
+// fstab.<hardware>, and fstab.<hardware.platform>.  The fstab is searched for
+// in /odm/etc/ and /vendor/etc/, as well as in the locations where it may be in
+// the first stage ramdisk during early boot.  Previously, the first stage
+// ramdisk's copy of the fstab had to be located in the root directory, but now
+// the system/etc directory is supported too and is the preferred location.
+std::string GetFstabPath() {
+    for (const char* prop : {"fstab_suffix", "hardware", "hardware.platform"}) {
+        std::string suffix;
+
+        if (!fs_mgr_get_boot_config(prop, &suffix)) continue;
+
+        for (const char* prefix : {// late-boot/post-boot locations
+                                   "/odm/etc/fstab.", "/vendor/etc/fstab.",
+                                   // early boot locations
+                                   "/system/etc/fstab.", "/first_stage_ramdisk/system/etc/fstab.",
+                                   "/fstab.", "/first_stage_ramdisk/fstab."}) {
+            std::string fstab_path = prefix + suffix;
+            if (access(fstab_path.c_str(), F_OK) == 0) {
+                return fstab_path;
+            }
+        }
+    }
+
+    return "";
+}
+
 bool ParseFstabFromString(const std::string& fstab_str, bool proc_mounts, Fstab* fstab_out) {
     const int expected_fields = proc_mounts ? 4 : 5;
 
@@ -804,7 +804,7 @@
 
     std::string default_fstab_path;
     // Use different fstab paths for normal boot and recovery boot, respectively
-    if (access("/system/bin/recovery", F_OK) == 0) {
+    if ((access("/sbin/recovery", F_OK) == 0) || (access("/system/bin/recovery", F_OK) == 0)) {
         default_fstab_path = "/etc/recovery.fstab";
     } else {  // normal boot
         default_fstab_path = GetFstabPath();
diff --git a/fs_mgr/fs_mgr_overlayfs.cpp b/fs_mgr/fs_mgr_overlayfs.cpp
index 82b5275..07eaf58 100644
--- a/fs_mgr/fs_mgr_overlayfs.cpp
+++ b/fs_mgr/fs_mgr_overlayfs.cpp
@@ -642,6 +642,10 @@
     if (ret) {
         PERROR << "__mount(target=" << mount_point
                << ",flag=" << (shared_flag ? "MS_SHARED" : "MS_PRIVATE") << ")=" << ret;
+        // If "/system" doesn't look like a mountpoint, retry with "/".
+        if (errno == EINVAL && mount_point == "/system") {
+            return fs_mgr_overlayfs_set_shared_mount("/", shared_flag);
+        }
         return false;
     }
     return true;
@@ -1140,7 +1144,13 @@
         return 0;
     }
 
-    return std::min(super_info.size, (uint64_t(s.f_frsize) * s.f_bfree) / 2);
+    auto ideal_size = std::min(super_info.size, (uint64_t(s.f_frsize) * s.f_bfree) / 2);
+
+    // Align up to the filesystem block size.
+    if (auto remainder = ideal_size % s.f_bsize; remainder > 0) {
+        ideal_size += s.f_bsize - remainder;
+    }
+    return ideal_size;
 }
 
 static bool CreateScratchOnData(std::string* scratch_device, bool* partition_exists, bool* change) {
diff --git a/fs_mgr/include_fstab/fstab/fstab.h b/fs_mgr/include_fstab/fstab/fstab.h
index 8f200a8..689d18b 100644
--- a/fs_mgr/include_fstab/fstab/fstab.h
+++ b/fs_mgr/include_fstab/fstab/fstab.h
@@ -95,6 +95,8 @@
 
 // Exported for testability. Regular users should use ReadFstabFromFile().
 bool ParseFstabFromString(const std::string& fstab_str, bool proc_mounts, Fstab* fstab_out);
+// Exported for testability. Regular users should use ReadDefaultFstab().
+std::string GetFstabPath();
 
 bool ReadFstabFromFile(const std::string& path, Fstab* fstab);
 bool ReadFstabFromDt(Fstab* fstab, bool verbose = true);
diff --git a/fs_mgr/tests/vts_fs_test.cpp b/fs_mgr/tests/vts_fs_test.cpp
index ae8e459..b8b34e2 100644
--- a/fs_mgr/tests/vts_fs_test.cpp
+++ b/fs_mgr/tests/vts_fs_test.cpp
@@ -23,6 +23,9 @@
 #include <gtest/gtest.h>
 #include <libdm/dm.h>
 
+using testing::Contains;
+using testing::Not;
+
 static int GetVsrLevel() {
     return android::base::GetIntProperty("ro.vendor.api_level", -1);
 }
@@ -117,3 +120,30 @@
     android::fs_mgr::Fstab fstab;
     EXPECT_FALSE(android::fs_mgr::ReadFstabFromDt(&fstab, false));
 }
+
+TEST(fs, NoLegacyVerifiedBoot) {
+    if (GetVsrLevel() < __ANDROID_API_T__) {
+        GTEST_SKIP();
+    }
+
+    const auto& default_fstab_path = android::fs_mgr::GetFstabPath();
+    EXPECT_FALSE(default_fstab_path.empty());
+
+    std::string fstab_str;
+    EXPECT_TRUE(android::base::ReadFileToString(default_fstab_path, &fstab_str,
+                                                /* follow_symlinks = */ true));
+
+    for (const auto& line : android::base::Split(fstab_str, "\n")) {
+        auto fields = android::base::Tokenize(line, " \t");
+        // Ignores empty lines and comments.
+        if (fields.empty() || android::base::StartsWith(fields.front(), '#')) {
+            continue;
+        }
+        // Each line in a fstab should have at least five entries.
+        //   <src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
+        ASSERT_GE(fields.size(), 5);
+        EXPECT_THAT(android::base::Split(fields[4], ","), Not(Contains("verify")))
+                << "AVB 1.0 isn't supported now, but the 'verify' flag is found:\n"
+                << "  " << line;
+    }
+}
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index 4bbbc20..07ce458 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -507,16 +507,16 @@
         SaveRamdiskPathToSnapuserd();
     }
 
-    if (MountPartition(system_partition, false /* erase_same_mounts */)) {
-        if (dsu_not_on_userdata_ && fs_mgr_verity_is_check_at_most_once(*system_partition)) {
-            LOG(ERROR) << "check_most_at_once forbidden on external media";
-            return false;
-        }
-        SwitchRoot("/system");
-    } else {
+    if (!MountPartition(system_partition, false /* erase_same_mounts */)) {
         PLOG(ERROR) << "Failed to mount /system";
         return false;
     }
+    if (dsu_not_on_userdata_ && fs_mgr_verity_is_check_at_most_once(*system_partition)) {
+        LOG(ERROR) << "check_at_most_once forbidden on external media";
+        return false;
+    }
+
+    SwitchRoot("/system");
 
     return true;
 }
diff --git a/init/init.cpp b/init/init.cpp
index 0658942..535033d 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -54,6 +54,7 @@
 #include <libavb/libavb.h>
 #include <libgsi/libgsi.h>
 #include <libsnapshot/snapshot.h>
+#include <logwrap/logwrap.h>
 #include <processgroup/processgroup.h>
 #include <processgroup/setup.h>
 #include <selinux/android.h>
@@ -442,17 +443,43 @@
     return {};
 }
 
-static void DoUnloadApex(const std::string& apex_name) {
+static Result<void> DoUnloadApex(const std::string& apex_name) {
     std::string prop_name = "init.apex." + apex_name;
     // TODO(b/232114573) remove services and actions read from the apex
     // TODO(b/232799709) kill services from the apex
     SetProperty(prop_name, "unloaded");
+    return {};
 }
 
-static void DoLoadApex(const std::string& apex_name) {
+static Result<void> UpdateApexLinkerConfig(const std::string& apex_name) {
+    // Do not invoke linkerconfig when there's no bin/ in the apex.
+    const std::string bin_path = "/apex/" + apex_name + "/bin";
+    if (access(bin_path.c_str(), R_OK) != 0) {
+        return {};
+    }
+    const char* linkerconfig_binary = "/apex/com.android.runtime/bin/linkerconfig";
+    const char* linkerconfig_target = "/linkerconfig";
+    const char* arguments[] = {linkerconfig_binary, "--target", linkerconfig_target, "--apex",
+                               apex_name.c_str(),   "--strict"};
+
+    if (logwrap_fork_execvp(arraysize(arguments), arguments, nullptr, false, LOG_KLOG, false,
+                            nullptr) != 0) {
+        return ErrnoError() << "failed to execute linkerconfig";
+    }
+    LOG(INFO) << "Generated linker configuration for " << apex_name;
+    return {};
+}
+
+static Result<void> DoLoadApex(const std::string& apex_name) {
     std::string prop_name = "init.apex." + apex_name;
     // TODO(b/232799709) read .rc files from the apex
+
+    if (auto result = UpdateApexLinkerConfig(apex_name); !result.ok()) {
+        return result.error();
+    }
+
     SetProperty(prop_name, "loaded");
+    return {};
 }
 
 enum class ControlTarget {
@@ -478,17 +505,14 @@
     return control_message_functions;
 }
 
-static bool HandleApexControlMessage(std::string_view action, const std::string& name,
-                                     std::string_view message) {
+static Result<void> HandleApexControlMessage(std::string_view action, const std::string& name,
+                                             std::string_view message) {
     if (action == "load") {
-        DoLoadApex(name);
-        return true;
+        return DoLoadApex(name);
     } else if (action == "unload") {
-        DoUnloadApex(name);
-        return true;
+        return DoUnloadApex(name);
     } else {
-        LOG(ERROR) << "Unknown control msg '" << message << "'";
-        return false;
+        return Error() << "Unknown control msg '" << message << "'";
     }
 }
 
@@ -505,7 +529,15 @@
 
     auto action = message;
     if (ConsumePrefix(&action, "apex_")) {
-        return HandleApexControlMessage(action, name, message);
+        if (auto result = HandleApexControlMessage(action, name, message); !result.ok()) {
+            LOG(ERROR) << "Control message: Could not ctl." << message << " for '" << name
+                       << "' from pid: " << from_pid << " (" << process_cmdline
+                       << "): " << result.error();
+            return false;
+        }
+        LOG(INFO) << "Control message: Processed ctl." << message << " for '" << name
+                  << "' from pid: " << from_pid << " (" << process_cmdline << ")";
+        return true;
     }
 
     Service* service = nullptr;
diff --git a/init/security.cpp b/init/security.cpp
index 970696e..0e9f6c2 100644
--- a/init/security.cpp
+++ b/init/security.cpp
@@ -15,6 +15,7 @@
  */
 
 #include "security.h"
+#include "util.h"
 
 #include <errno.h>
 #include <fcntl.h>
@@ -89,7 +90,7 @@
 
 // Set /proc/sys/vm/mmap_rnd_bits and potentially
 // /proc/sys/vm/mmap_rnd_compat_bits to the maximum supported values.
-// Returns -1 if unable to set these to an acceptable value.
+// Returns an error if unable to set these to an acceptable value.
 //
 // To support this sysctl, the following upstream commits are needed:
 //
@@ -105,13 +106,20 @@
     // uml does not support mmap_rnd_bits
     return {};
 #elif defined(__aarch64__)
-    // arm64 supports 18 - 33 bits depending on pagesize and VA_SIZE
-    if (SetMmapRndBitsMin(33, 24, false) && SetMmapRndBitsMin(16, 16, true)) {
+    // arm64 architecture supports 18 - 33 rnd bits depending on pagesize and
+    // VA_SIZE. However the kernel might have been compiled with a narrower
+    // range using CONFIG_ARCH_MMAP_RND_BITS_MIN/MAX. To use the maximum
+    // supported number of bits, we start from the theoretical maximum of 33
+    // bits and try smaller values until we reach 24 bits which is the
+    // Android-specific minimum. Don't go lower even if the configured maximum
+    // is smaller than 24.
+    if (SetMmapRndBitsMin(33, 24, false) && (!Has32BitAbi() || SetMmapRndBitsMin(16, 16, true))) {
         return {};
     }
 #elif defined(__x86_64__)
-    // x86_64 supports 28 - 32 bits
-    if (SetMmapRndBitsMin(32, 32, false) && SetMmapRndBitsMin(16, 16, true)) {
+    // x86_64 supports 28 - 32 rnd bits, but Android wants to ensure that the
+    // theoretical maximum of 32 bits is always supported and used.
+    if (SetMmapRndBitsMin(32, 32, false) && (!Has32BitAbi() || SetMmapRndBitsMin(16, 16, true))) {
         return {};
     }
 #elif defined(__arm__) || defined(__i386__)
diff --git a/init/service.cpp b/init/service.cpp
index 01dd685..8c4ee93 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -315,7 +315,9 @@
 #else
     static bool is_apex_updatable = false;
 #endif
-    const bool is_process_updatable = !use_bootstrap_ns_ && is_apex_updatable;
+    const bool use_default_mount_ns =
+            mount_namespace_.has_value() && *mount_namespace_ == NS_DEFAULT;
+    const bool is_process_updatable = use_default_mount_ns && is_apex_updatable;
 
     // If we crash > 4 times in 'fatal_crash_window_' minutes or before boot_completed,
     // reboot into bootloader or set crashing property
@@ -474,10 +476,9 @@
 }
 
 // Enters namespaces, sets environment variables, writes PID files and runs the service executable.
-void Service::RunService(const std::optional<MountNamespace>& override_mount_namespace,
-                         const std::vector<Descriptor>& descriptors,
+void Service::RunService(const std::vector<Descriptor>& descriptors,
                          std::unique_ptr<std::array<int, 2>, decltype(&ClosePipe)> pipefd) {
-    if (auto result = EnterNamespaces(namespaces_, name_, override_mount_namespace); !result.ok()) {
+    if (auto result = EnterNamespaces(namespaces_, name_, mount_namespace_); !result.ok()) {
         LOG(FATAL) << "Service '" << name_ << "' failed to set up namespaces: " << result.error();
     }
 
@@ -581,26 +582,9 @@
         scon = *result;
     }
 
-    // APEXd is always started in the "current" namespace because it is the process to set up
-    // the current namespace.
-    const bool is_apexd = args_[0] == "/system/bin/apexd";
-
-    if (!IsDefaultMountNamespaceReady() && !is_apexd) {
-        // If this service is started before APEXes and corresponding linker configuration
-        // get available, mark it as pre-apexd one. Note that this marking is
-        // permanent. So for example, if the service is re-launched (e.g., due
-        // to crash), it is still recognized as pre-apexd... for consistency.
-        use_bootstrap_ns_ = true;
-    }
-
-    // For pre-apexd services, override mount namespace as "bootstrap" one before starting.
-    // Note: "ueventd" is supposed to be run in "default" mount namespace even if it's pre-apexd
-    // to support loading firmwares from APEXes.
-    std::optional<MountNamespace> override_mount_namespace;
-    if (name_ == "ueventd") {
-        override_mount_namespace = NS_DEFAULT;
-    } else if (use_bootstrap_ns_) {
-        override_mount_namespace = NS_BOOTSTRAP;
+    if (!mount_namespace_.has_value()) {
+        // remember from which mount namespace the service should start
+        SetMountNamespace();
     }
 
     post_data_ = ServiceList::GetInstance().IsPostData();
@@ -633,7 +617,7 @@
 
     if (pid == 0) {
         umask(077);
-        RunService(override_mount_namespace, descriptors, std::move(pipefd));
+        RunService(descriptors, std::move(pipefd));
         _exit(127);
     }
 
@@ -684,6 +668,33 @@
     return {};
 }
 
+// Set mount namespace for the service.
+// The reason why remember the mount namespace:
+//   If this service is started before APEXes and corresponding linker configuration
+//   get available, mark it as pre-apexd one. Note that this marking is
+//   permanent. So for example, if the service is re-launched (e.g., due
+//   to crash), it is still recognized as pre-apexd... for consistency.
+void Service::SetMountNamespace() {
+    // APEXd is always started in the "current" namespace because it is the process to set up
+    // the current namespace. So, leave mount_namespace_ as empty.
+    if (args_[0] == "/system/bin/apexd") {
+        return;
+    }
+    // Services in the following list start in the "default" mount namespace.
+    // Note that they should use bootstrap bionic if they start before APEXes are ready.
+    static const std::set<std::string> kUseDefaultMountNamespace = {
+            "ueventd",           // load firmwares from APEXes
+            "hwservicemanager",  // load VINTF fragments from APEXes
+            "servicemanager",    // load VINTF fragments from APEXes
+    };
+    if (kUseDefaultMountNamespace.find(name_) != kUseDefaultMountNamespace.end()) {
+        mount_namespace_ = NS_DEFAULT;
+        return;
+    }
+    // Use the "default" mount namespace only if it's ready
+    mount_namespace_ = IsDefaultMountNamespaceReady() ? NS_DEFAULT : NS_BOOTSTRAP;
+}
+
 void Service::SetStartedInFirstStage(pid_t pid) {
     LOG(INFO) << "adding first-stage service '" << name_ << "'...";
 
diff --git a/init/service.h b/init/service.h
index d233cbf..4adbaa2 100644
--- a/init/service.h
+++ b/init/service.h
@@ -32,6 +32,7 @@
 #include "action.h"
 #include "capabilities.h"
 #include "keyword_map.h"
+#include "mount_namespace.h"
 #include "parser.h"
 #include "service_utils.h"
 #include "subcontext.h"
@@ -151,10 +152,9 @@
     Result<void> CheckConsole();
     void ConfigureMemcg();
     void RunService(
-            const std::optional<MountNamespace>& override_mount_namespace,
             const std::vector<Descriptor>& descriptors,
             std::unique_ptr<std::array<int, 2>, void (*)(const std::array<int, 2>* pipe)> pipefd);
-
+    void SetMountNamespace();
     static unsigned long next_start_order_;
     static bool is_exec_service_running_;
     static std::chrono::time_point<std::chrono::steady_clock> exec_service_started_;
@@ -219,7 +219,7 @@
 
     std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_;
 
-    bool use_bootstrap_ns_ = false;
+    std::optional<MountNamespace> mount_namespace_;
 
     bool post_data_ = false;
 
diff --git a/init/util.cpp b/init/util.cpp
index 1801d17..523cce4 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -733,5 +733,10 @@
     return is_microdroid;
 }
 
+bool Has32BitAbi() {
+    static bool has = !android::base::GetProperty("ro.product.cpu.abilist32", "").empty();
+    return has;
+}
+
 }  // namespace init
 }  // namespace android
diff --git a/init/util.h b/init/util.h
index 47d4ff5..099b9ee 100644
--- a/init/util.h
+++ b/init/util.h
@@ -106,5 +106,6 @@
 void SetDefaultMountNamespaceReady();
 
 bool IsMicrodroid();
+bool Has32BitAbi();
 }  // namespace init
 }  // namespace android
diff --git a/libsync/libsync.map.txt b/libsync/libsync.map.txt
index aac6b57..32df91e 100644
--- a/libsync/libsync.map.txt
+++ b/libsync/libsync.map.txt
@@ -19,7 +19,7 @@
     sync_merge; # introduced=26
     sync_file_info; # introduced=26
     sync_file_info_free; # introduced=26
-    sync_wait; # llndk apex
+    sync_wait; # llndk systemapi
     sync_fence_info; # llndk
     sync_pt_info; # llndk
     sync_fence_info_free; # llndk
diff --git a/libvndksupport/libvndksupport.map.txt b/libvndksupport/libvndksupport.map.txt
index a44ed18..1d94b9d 100644
--- a/libvndksupport/libvndksupport.map.txt
+++ b/libvndksupport/libvndksupport.map.txt
@@ -1,8 +1,8 @@
 LIBVNDKSUPPORT {
   global:
-    android_is_in_vendor_process; # llndk apex
-    android_load_sphal_library; # llndk apex
-    android_unload_sphal_library; # llndk apex
+    android_is_in_vendor_process; # llndk systemapi
+    android_load_sphal_library; # llndk systemapi
+    android_unload_sphal_library; # llndk systemapi
   local:
     *;
 };
diff --git a/rootdir/init.rc b/rootdir/init.rc
index a819c7a..660f18c 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -832,6 +832,7 @@
     mkdir /data/misc/odsign 0710 root system
     # directory used for odsign metrics
     mkdir /data/misc/odsign/metrics 0770 root system
+
     # Directory for VirtualizationService temporary image files.
     # Delete any stale files owned by the old virtualizationservice uid (b/230056726).
     chmod 0770 /data/misc/virtualizationservice
@@ -1040,7 +1041,8 @@
     exec_start update_verifier_nonencrypted
     start statsd
     start netd
-    trigger zygote-run
+    start zygote
+    start zygote_secondary
 
 on zygote-start && property:ro.crypto.state=unsupported
     wait_for_prop odsign.verification.done 1
@@ -1048,7 +1050,8 @@
     exec_start update_verifier_nonencrypted
     start statsd
     start netd
-    trigger zygote-run
+    start zygote
+    start zygote_secondary
 
 on zygote-start && property:ro.crypto.state=encrypted && property:ro.crypto.type=file
     wait_for_prop odsign.verification.done 1
@@ -1056,15 +1059,6 @@
     exec_start update_verifier_nonencrypted
     start statsd
     start netd
-    trigger zygote-run
-
-on zygote-run && property:ro.zygote=zygote32
-    start zygote
-
-on zygote-run && property:ro.zygote=zygote64
-    start zygote
-
-on zygote-run && property:ro.zygote=zygote64_32
     start zygote
     start zygote_secondary
 
diff --git a/rootdir/init.zygote64_32.rc b/rootdir/init.zygote64_32.rc
index dfe1645..efb30d6 100644
--- a/rootdir/init.zygote64_32.rc
+++ b/rootdir/init.zygote64_32.rc
@@ -25,4 +25,3 @@
     socket usap_pool_secondary stream 660 root system
     onrestart restart zygote
     task_profiles ProcessCapacityHigh MaxPerformance
-    disabled