Merge "adb: attempt to exec newer adb servers on Linux."
diff --git a/adb/Android.bp b/adb/Android.bp
index 1e085a7..01e00dd 100644
--- a/adb/Android.bp
+++ b/adb/Android.bp
@@ -24,7 +24,8 @@
         "-Wno-missing-field-initializers",
         "-Wthread-safety",
         "-Wvla",
-        "-DADB_HOST=1", // overridden by adbd_defaults
+        "-DADB_HOST=1",         // overridden by adbd_defaults
+        "-DALLOW_ADBD_ROOT=0",  // overridden by adbd_defaults
     ],
     cpp_std: "experimental",
 
@@ -79,7 +80,8 @@
     product_variables: {
         debuggable: {
             cflags: [
-                "-DALLOW_ADBD_ROOT",
+                "-UALLOW_ADBD_ROOT",
+                "-DALLOW_ADBD_ROOT=1",
                 "-DALLOW_ADBD_DISABLE_VERITY",
                 "-DALLOW_ADBD_NO_AUTH",
             ],
diff --git a/adb/daemon/file_sync_service.cpp b/adb/daemon/file_sync_service.cpp
index 70deb31..29bd798 100644
--- a/adb/daemon/file_sync_service.cpp
+++ b/adb/daemon/file_sync_service.cpp
@@ -25,7 +25,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/mount.h>
 #include <sys/stat.h>
 #include <sys/time.h>
 #include <sys/types.h>
@@ -211,22 +210,6 @@
     return WriteFdExactly(s, &msg.dent, sizeof(msg.dent));
 }
 
-static bool is_mountpoint(const std::string& path, pid_t tid) {
-    const std::string mountinfo_path = "/proc/" + std::to_string(tid) + "/mountinfo";
-    std::string mountinfo;
-    if (!android::base::ReadFileToString(mountinfo_path, &mountinfo)) {
-        PLOG(ERROR) << "Failed to open " << mountinfo_path;
-        return false;
-    }
-    std::vector<std::string> lines = android::base::Split(mountinfo, "\n");
-    return std::find_if(lines.begin(), lines.end(), [&path](const auto& line) {
-               auto tokens = android::base::Split(line, " ");
-               // line format is ...
-               // mountid parentmountid major:minor sourcepath targetpath option ...
-               return tokens.size() >= 4 && tokens[4] == path;
-           }) != lines.end();
-}
-
 // Make sure that SendFail from adb_io.cpp isn't accidentally used in this file.
 #pragma GCC poison SendFail
 
@@ -432,18 +415,6 @@
     struct stat st;
     bool do_unlink = (lstat(path.c_str(), &st) == -1) || S_ISREG(st.st_mode) ||
                      (S_ISLNK(st.st_mode) && !S_ISLNK(mode));
-
-    // If the path is a file that is a mount point, don't unlink it, but instead
-    // truncate to zero. If unlinked, existing mounts on the path is all
-    // unmounted
-    if (S_ISREG(st.st_mode) && is_mountpoint(path, getpid())) {
-        do_unlink = false;
-        if (truncate(path.c_str(), 0) == -1) {
-            SendSyncFail(s, "truncate to zero failed");
-            return false;
-        }
-    }
-
     if (do_unlink) {
         adb_unlink(path.c_str());
     }
@@ -591,64 +562,7 @@
     return true;
 }
 
-#if defined(__ANDROID__)
-class FileSyncPreparer {
-  public:
-    FileSyncPreparer() : saved_ns_fd_(-1), rooted_(getuid() == 0) {
-        const std::string namespace_path = "/proc/" + std::to_string(gettid()) + "/ns/mnt";
-        const int ns_fd = adb_open(namespace_path.c_str(), O_RDONLY | O_CLOEXEC);
-        if (ns_fd == -1) {
-            if (rooted_) PLOG(ERROR) << "Failed to save mount namespace";
-            return;
-        }
-        saved_ns_fd_.reset(ns_fd);
-
-        // Note: this is for the current thread only
-        if (unshare(CLONE_NEWNS) != 0) {
-            if (rooted_) PLOG(ERROR) << "Failed to clone mount namespace";
-            return;
-        }
-
-        // Set the propagation type of / to private so that unmount below is
-        // not propagated to other mount namespaces.
-        if (mount(nullptr, "/", nullptr, MS_PRIVATE | MS_REC, nullptr) == -1) {
-            if (rooted_) PLOG(ERROR) << "Could not change propagation type of / to MS_PRIVATE";
-            return;
-        }
-
-        // unmount /bionic which is bind-mount to itself by init. Under /bionic,
-        // there are other bind mounts for the bionic files. By unmounting this,
-        // we unmount them all thus revealing the raw file system that is the
-        // same as the local file system seen by the adb client.
-        if (umount2("/bionic", MNT_DETACH) == -1 && errno != ENOENT) {
-            if (rooted_) PLOG(ERROR) << "Could not unmount /bionic to reveal raw filesystem";
-            return;
-        }
-    }
-
-    ~FileSyncPreparer() {
-        if (saved_ns_fd_.get() != -1) {
-            // In fact, this is not strictly required because this thread for file
-            // sync service will be destroyed after the current transfer is all
-            // done. However, let's restore the ns in case the same thread is
-            // reused by multiple transfers in the future refactoring.
-            if (setns(saved_ns_fd_, CLONE_NEWNS) == -1) {
-                PLOG(ERROR) << "Failed to restore saved mount namespace";
-            }
-        }
-    }
-
-  private:
-    unique_fd saved_ns_fd_;
-    bool rooted_;
-};
-#endif
-
 void file_sync_service(unique_fd fd) {
-#if defined(__ANDROID__)
-    FileSyncPreparer preparer;
-#endif
-
     std::vector<char> buffer(SYNC_DATA_MAX);
 
     while (handle_sync_command(fd.get(), buffer)) {
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index fce3a4f..e5a4917 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -58,17 +58,23 @@
 #if defined(__ANDROID__)
 static const char* root_seclabel = nullptr;
 
+static inline bool is_device_unlocked() {
+    return "orange" == android::base::GetProperty("ro.boot.verifiedbootstate", "");
+}
+
 static bool should_drop_capabilities_bounding_set() {
-#if defined(ALLOW_ADBD_ROOT)
-    if (__android_log_is_debuggable()) {
-        return false;
+    if (ALLOW_ADBD_ROOT || is_device_unlocked()) {
+        if (__android_log_is_debuggable()) {
+            return false;
+        }
     }
-#endif
     return true;
 }
 
 static bool should_drop_privileges() {
-#if defined(ALLOW_ADBD_ROOT)
+    // "adb root" not allowed, always drop privileges.
+    if (!ALLOW_ADBD_ROOT && !is_device_unlocked()) return true;
+
     // The properties that affect `adb root` and `adb unroot` are ro.secure and
     // ro.debuggable. In this context the names don't make the expected behavior
     // particularly obvious.
@@ -98,9 +104,6 @@
     }
 
     return drop;
-#else
-    return true; // "adb root" not allowed, always drop privileges.
-#endif // ALLOW_ADBD_ROOT
 }
 
 static void drop_privileges(int server_port) {
@@ -205,6 +208,10 @@
 #if defined(ALLOW_ADBD_NO_AUTH)
     // If ro.adb.secure is unset, default to no authentication required.
     auth_required = android::base::GetBoolProperty("ro.adb.secure", false);
+#elif defined(__ANDROID__)
+    if (is_device_unlocked()) {  // allows no authentication when the device is unlocked.
+        auth_required = android::base::GetBoolProperty("ro.adb.secure", false);
+    }
 #endif
 
     adbd_auth_init();
diff --git a/fs_mgr/fs_mgr_remount.cpp b/fs_mgr/fs_mgr_remount.cpp
index 5c4008c..e2a4d16 100644
--- a/fs_mgr/fs_mgr_remount.cpp
+++ b/fs_mgr/fs_mgr_remount.cpp
@@ -80,29 +80,6 @@
     return &(*it);
 }
 
-void try_unmount_bionic(android::fs_mgr::Fstab* mounts) {
-    static constexpr const char* kBionic = "/bionic";
-
-    auto entry = GetEntryForMountPoint(mounts, kBionic);
-    if (!entry) return;
-
-    struct statfs buf;
-    if (::statfs(kBionic, &buf) == -1) {
-        PLOG(ERROR) << "statfs of " << kBionic;
-        return;
-    }
-    if (buf.f_flags & MS_RDONLY) {
-        // /bionic is on a read-only partition; can happen for
-        // non-system-as-root-devices. Don' try to unmount.
-        return;
-    }
-    fs_mgr_set_blk_ro(entry->blk_device, false);
-    if (::mount(entry->blk_device.c_str(), entry->mount_point.c_str(), entry->fs_type.c_str(),
-                MS_REMOUNT, nullptr) == -1) {
-        PLOG(ERROR) << "remount of " << kBionic;
-    }
-}
-
 void MyLogger(android::base::LogId id, android::base::LogSeverity severity, const char* tag,
               const char* file, unsigned int line, const char* message) {
     static const char log_characters[] = "VD\0WEFF";
@@ -395,7 +372,5 @@
 
     if (reboot_later) reboot(false);
 
-    try_unmount_bionic(&mounts);
-
     return retval;
 }
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 6511d29..8437e37 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -1118,14 +1118,6 @@
     }
 }
 
-static Result<Success> do_setup_runtime_bionic(const BuiltinArguments& args) {
-    if (SetupRuntimeBionic()) {
-        return Success();
-    } else {
-        return Error() << "Failed to setup runtime bionic";
-    }
-}
-
 static Result<Success> do_enter_default_mount_ns(const BuiltinArguments& args) {
     if (SwitchToDefaultMountNamespace()) {
         return Success();
@@ -1181,7 +1173,6 @@
         {"rmdir",                   {1,     1,    {true,   do_rmdir}}},
         {"setprop",                 {2,     2,    {true,   do_setprop}}},
         {"setrlimit",               {3,     3,    {false,  do_setrlimit}}},
-        {"setup_runtime_bionic",    {0,     0,    {false,  do_setup_runtime_bionic}}},
         {"start",                   {1,     1,    {false,  do_start}}},
         {"stop",                    {1,     1,    {false,  do_stop}}},
         {"swapon_all",              {1,     1,    {false,  do_swapon_all}}},
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index 7cf4c3f..c566676 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -199,6 +199,12 @@
         SwitchRoot("/first_stage_ramdisk");
     }
 
+    // If this file is present, the second-stage init will use a userdebug sepolicy
+    // and load adb_debug.prop to allow adb root, if the device is unlocked.
+    if (access("/force_debuggable", F_OK) == 0) {
+        setenv("INIT_FORCE_DEBUGGABLE", "true", 1);
+    }
+
     if (!DoFirstStageMount()) {
         LOG(FATAL) << "Failed to mount required partitions early ...";
     }
diff --git a/init/init.cpp b/init/init.cpp
index bbef1a9..7182fda 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -39,6 +39,7 @@
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
 #include <cutils/android_reboot.h>
+#include <fs_avb/fs_avb.h>
 #include <fs_mgr_vendor_overlay.h>
 #include <keyutils.h>
 #include <libavb/libavb.h>
@@ -74,6 +75,7 @@
 using android::base::StringPrintf;
 using android::base::Timer;
 using android::base::Trim;
+using android::fs_mgr::AvbHandle;
 
 namespace android {
 namespace init {
@@ -92,6 +94,7 @@
 static bool shutting_down;
 static std::string shutdown_command;
 static bool do_shutdown = false;
+static bool load_debug_prop = false;
 
 std::vector<std::string> late_import_paths;
 
@@ -655,10 +658,17 @@
     const char* avb_version = getenv("INIT_AVB_VERSION");
     if (avb_version) property_set("ro.boot.avb_version", avb_version);
 
+    // See if need to load debug props to allow adb root, when the device is unlocked.
+    const char* force_debuggable_env = getenv("INIT_FORCE_DEBUGGABLE");
+    if (force_debuggable_env && AvbHandle::IsDeviceUnlocked()) {
+        load_debug_prop = "true"s == force_debuggable_env;
+    }
+
     // Clean up our environment.
     unsetenv("INIT_STARTED_AT");
     unsetenv("INIT_SELINUX_TOOK");
     unsetenv("INIT_AVB_VERSION");
+    unsetenv("INIT_FORCE_DEBUGGABLE");
 
     // Now set up SELinux for second stage.
     SelinuxSetupKernelLogging();
@@ -672,7 +682,7 @@
 
     InstallSignalFdHandler(&epoll);
 
-    property_load_boot_defaults();
+    property_load_boot_defaults(load_debug_prop);
     fs_mgr_vendor_overlay_mount_all();
     export_oem_lock_status();
     StartPropertyService(&epoll);
diff --git a/init/mount_namespace.cpp b/init/mount_namespace.cpp
index 4161df2..5305dc7 100644
--- a/init/mount_namespace.cpp
+++ b/init/mount_namespace.cpp
@@ -33,37 +33,6 @@
 namespace init {
 namespace {
 
-static constexpr const char* kLinkerMountPoint = "/bionic/bin/linker";
-static constexpr const char* kBootstrapLinkerPath = "/system/bin/bootstrap/linker";
-static constexpr const char* kRuntimeLinkerPath = "/apex/com.android.runtime/bin/linker";
-
-static constexpr const char* kBionicLibsMountPointDir = "/bionic/lib/";
-static constexpr const char* kBootstrapBionicLibsDir = "/system/lib/bootstrap/";
-static constexpr const char* kRuntimeBionicLibsDir = "/apex/com.android.runtime/lib/bionic/";
-
-static constexpr const char* kLinkerMountPoint64 = "/bionic/bin/linker64";
-static constexpr const char* kBootstrapLinkerPath64 = "/system/bin/bootstrap/linker64";
-static constexpr const char* kRuntimeLinkerPath64 = "/apex/com.android.runtime/bin/linker64";
-
-static constexpr const char* kBionicLibsMountPointDir64 = "/bionic/lib64/";
-static constexpr const char* kBootstrapBionicLibsDir64 = "/system/lib64/bootstrap/";
-static constexpr const char* kRuntimeBionicLibsDir64 = "/apex/com.android.runtime/lib64/bionic/";
-
-static const std::vector<std::string> kBionicLibFileNames = {"libc.so", "libm.so", "libdl.so"};
-
-static bool BindMount(const std::string& source, const std::string& mount_point,
-                      bool recursive = false) {
-    unsigned long mountflags = MS_BIND;
-    if (recursive) {
-        mountflags |= MS_REC;
-    }
-    if (mount(source.c_str(), mount_point.c_str(), nullptr, mountflags, nullptr) == -1) {
-        PLOG(ERROR) << "Could not bind-mount " << source << " to " << mount_point;
-        return false;
-    }
-    return true;
-}
-
 static bool MakeShared(const std::string& mount_point, bool recursive = false) {
     unsigned long mountflags = MS_SHARED;
     if (recursive) {
@@ -105,34 +74,6 @@
     return ret;
 }
 
-static bool BindMountBionic(const std::string& linker_source, const std::string& lib_dir_source,
-                            const std::string& linker_mount_point,
-                            const std::string& lib_mount_dir) {
-    if (access(linker_source.c_str(), F_OK) != 0) {
-        PLOG(INFO) << linker_source << " does not exist. skipping mounting bionic there.";
-        // This can happen for 64-bit bionic in 32-bit only device.
-        // It is okay to skip mounting the 64-bit bionic.
-        return true;
-    }
-    if (!BindMount(linker_source, linker_mount_point)) {
-        return false;
-    }
-    if (!MakePrivate(linker_mount_point)) {
-        return false;
-    }
-    for (const auto& libname : kBionicLibFileNames) {
-        std::string mount_point = lib_mount_dir + libname;
-        std::string source = lib_dir_source + libname;
-        if (!BindMount(source, mount_point)) {
-            return false;
-        }
-        if (!MakePrivate(mount_point)) {
-            return false;
-        }
-    }
-    return true;
-}
-
 static bool IsApexUpdatable() {
     static bool updatable = android::sysprop::ApexProperties::updatable().value_or(false);
     return updatable;
@@ -154,26 +95,7 @@
     // point to private.
     if (!MakeShared("/", true /*recursive*/)) return false;
 
-    // Since different files (bootstrap or runtime APEX) should be mounted to
-    // the same mount point paths (e.g. /bionic/bin/linker, /bionic/lib/libc.so,
-    // etc.) across the two mount namespaces, we create a private mount point at
-    // /bionic so that a mount event for the bootstrap bionic in the mount
-    // namespace for pre-apexd processes is not propagated to the other mount
-    // namespace for post-apexd process, and vice versa.
-    //
-    // Other mount points other than /bionic, however, are all still shared.
-    if (!BindMount("/bionic", "/bionic", true /*recursive*/)) return false;
-    if (!MakePrivate("/bionic")) return false;
-
-    // Bind-mount bootstrap bionic.
-    if (!BindMountBionic(kBootstrapLinkerPath, kBootstrapBionicLibsDir, kLinkerMountPoint,
-                         kBionicLibsMountPointDir))
-        return false;
-    if (!BindMountBionic(kBootstrapLinkerPath64, kBootstrapBionicLibsDir64, kLinkerMountPoint64,
-                         kBionicLibsMountPointDir64))
-        return false;
-
-    // /apex is also a private mountpoint to give different sets of APEXes for
+    // /apex is a private mountpoint to give different sets of APEXes for
     // the bootstrap and default mount namespaces. The processes running with
     // the bootstrap namespace get APEXes from the read-only partition.
     if (!(MakePrivate("/apex"))) return false;
@@ -181,12 +103,11 @@
     bootstrap_ns_fd.reset(OpenMountNamespace());
     bootstrap_ns_id = GetMountNamespaceId();
 
-    // When bionic is updatable via the runtime APEX, we create separate mount
+    // When APEXes are updatable (e.g. not-flattened), we create separate mount
     // namespaces for processes that are started before and after the APEX is
-    // activated by apexd. In the namespace for pre-apexd processes, the bionic
-    // from the /system partition (that we call bootstrap bionic) is
-    // bind-mounted. In the namespace for post-apexd processes, the bionic from
-    // the runtime APEX is bind-mounted.
+    // activated by apexd. In the namespace for pre-apexd processes, small
+    // number of essential APEXes (e.g. com.android.runtime) are activated.
+    // In the namespace for post-apexd processes, all APEXes are activated.
     bool success = true;
     if (IsApexUpdatable() && !IsRecoveryMode()) {
         // Creating a new namespace by cloning, saving, and switching back to
@@ -198,15 +119,6 @@
         default_ns_fd.reset(OpenMountNamespace());
         default_ns_id = GetMountNamespaceId();
 
-        // By this unmount, the bootstrap bionic are not mounted in the default
-        // mount namespace.
-        if (umount2("/bionic", MNT_DETACH) == -1) {
-            PLOG(ERROR) << "Cannot unmount /bionic";
-            // Don't return here. We have to switch back to the bootstrap
-            // namespace.
-            success = false;
-        }
-
         if (setns(bootstrap_ns_fd.get(), CLONE_NEWNS) == -1) {
             PLOG(ERROR) << "Cannot switch back to bootstrap mount namespace";
             return false;
@@ -237,28 +149,6 @@
     return true;
 }
 
-// TODO(jiyong): remove this when /system/lib/libc.so becomes
-// a symlink to /apex/com.android.runtime/lib/bionic/libc.so
-bool SetupRuntimeBionic() {
-    if (IsRecoveryMode()) {
-        // We don't have multiple namespaces in recovery mode
-        return true;
-    }
-    // Bind-mount bionic from the runtime APEX since it is now available. Note
-    // that in case of IsApexUpdatable() == false, these mounts are over the
-    // existing existing bind mounts for the bootstrap bionic, which effectively
-    // becomes hidden.
-    if (!BindMountBionic(kRuntimeLinkerPath, kRuntimeBionicLibsDir, kLinkerMountPoint,
-                         kBionicLibsMountPointDir))
-        return false;
-    if (!BindMountBionic(kRuntimeLinkerPath64, kRuntimeBionicLibsDir64, kLinkerMountPoint64,
-                         kBionicLibsMountPointDir64))
-        return false;
-
-    LOG(INFO) << "Runtime bionic is set up";
-    return true;
-}
-
 bool SwitchToBootstrapMountNamespaceIfNeeded() {
     if (IsRecoveryMode()) {
         // we don't have multiple namespaces in recovery mode
diff --git a/init/mount_namespace.h b/init/mount_namespace.h
index 4eef785..c41a449 100644
--- a/init/mount_namespace.h
+++ b/init/mount_namespace.h
@@ -20,7 +20,6 @@
 namespace init {
 
 bool SetupMountNamespaces();
-bool SetupRuntimeBionic();
 bool SwitchToDefaultMountNamespace();
 bool SwitchToBootstrapMountNamespaceIfNeeded();
 
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 4bc857a..fc5538c 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -866,7 +866,7 @@
     }
 }
 
-void property_load_boot_defaults() {
+void property_load_boot_defaults(bool load_debug_prop) {
     // TODO(b/117892318): merge prop.default and build.prop files into one
     // We read the properties and their values into a map, in order to always allow properties
     // loaded in the later property files to override the properties in loaded in the earlier
@@ -888,6 +888,12 @@
     load_properties_from_file("/product_services/build.prop", nullptr, &properties);
     load_properties_from_file("/factory/factory.prop", "ro.*", &properties);
 
+    if (load_debug_prop) {
+        constexpr static const char kAdbDebugProp[] = "/system/etc/adb_debug.prop";
+        LOG(INFO) << "Loading " << kAdbDebugProp;
+        load_properties_from_file(kAdbDebugProp, nullptr, &properties);
+    }
+
     for (const auto& [name, value] : properties) {
         std::string error;
         if (PropertySet(name, value, &error) != PROP_SUCCESS) {
diff --git a/init/property_service.h b/init/property_service.h
index 9022f5a..85e7bc0 100644
--- a/init/property_service.h
+++ b/init/property_service.h
@@ -36,7 +36,7 @@
 extern bool PropertyChildReap(pid_t pid);
 
 void property_init(void);
-void property_load_boot_defaults(void);
+void property_load_boot_defaults(bool);
 void load_persist_props(void);
 void load_system_props(void);
 void StartPropertyService(Epoll* epoll);
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 3fadfed..797c4e0 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -61,14 +61,18 @@
 #include <android-base/parseint.h>
 #include <android-base/unique_fd.h>
 #include <cutils/android_reboot.h>
+#include <fs_avb/fs_avb.h>
 #include <selinux/android.h>
 
 #include "reboot_utils.h"
 #include "util.h"
 
+using namespace std::string_literals;
+
 using android::base::ParseInt;
 using android::base::Timer;
 using android::base::unique_fd;
+using android::fs_mgr::AvbHandle;
 
 namespace android {
 namespace init {
@@ -267,6 +271,8 @@
 }
 
 constexpr const char plat_policy_cil_file[] = "/system/etc/selinux/plat_sepolicy.cil";
+constexpr const char userdebug_plat_policy_cil_file[] =
+        "/system/etc/selinux/userdebug_plat_sepolicy.cil";
 
 bool IsSplitPolicyDevice() {
     return access(plat_policy_cil_file, R_OK) != -1;
@@ -282,10 +288,21 @@
     // secilc is invoked to compile the above three policy files into a single monolithic policy
     // file. This file is then loaded into the kernel.
 
+    // See if we need to load userdebug_plat_sepolicy.cil instead of plat_sepolicy.cil.
+    const char* force_debuggable_env = getenv("INIT_FORCE_DEBUGGABLE");
+    bool use_userdebug_policy =
+            ((force_debuggable_env && "true"s == force_debuggable_env) &&
+             AvbHandle::IsDeviceUnlocked() && access(userdebug_plat_policy_cil_file, F_OK) == 0);
+    if (use_userdebug_policy) {
+        LOG(WARNING) << "Using userdebug system sepolicy";
+    }
+
     // Load precompiled policy from vendor image, if a matching policy is found there. The policy
     // must match the platform policy on the system image.
     std::string precompiled_sepolicy_file;
-    if (FindPrecompiledSplitPolicy(&precompiled_sepolicy_file)) {
+    // use_userdebug_policy requires compiling sepolicy with userdebug_plat_sepolicy.cil.
+    // Thus it cannot use the precompiled policy from vendor image.
+    if (!use_userdebug_policy && FindPrecompiledSplitPolicy(&precompiled_sepolicy_file)) {
         unique_fd fd(open(precompiled_sepolicy_file.c_str(), O_RDONLY | O_CLOEXEC | O_BINARY));
         if (fd != -1) {
             if (selinux_android_load_policy_from_fd(fd, precompiled_sepolicy_file.c_str()) < 0) {
@@ -358,7 +375,7 @@
     // clang-format off
     std::vector<const char*> compile_args {
         "/system/bin/secilc",
-        plat_policy_cil_file,
+        use_userdebug_policy ? userdebug_plat_policy_cil_file : plat_policy_cil_file,
         "-m", "-M", "true", "-G", "-N",
         // Target the highest policy language version supported by the kernel
         "-c", version_as_string.c_str(),
diff --git a/libprocessgroup/task_profiles.cpp b/libprocessgroup/task_profiles.cpp
index dcf53f9..f1fbcde 100644
--- a/libprocessgroup/task_profiles.cpp
+++ b/libprocessgroup/task_profiles.cpp
@@ -202,7 +202,7 @@
     std::string procs_path = controller_->GetProcsFilePath(path_, uid, pid);
     unique_fd tmp_fd(TEMP_FAILURE_RETRY(open(procs_path.c_str(), O_WRONLY | O_CLOEXEC)));
     if (tmp_fd < 0) {
-        PLOG(WARNING) << "Failed to open " << procs_path << ": " << strerror(errno);
+        PLOG(WARNING) << "Failed to open " << procs_path;
         return false;
     }
     if (!AddTidToCgroup(pid, tmp_fd)) {
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index 552d685..641a536 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -83,7 +83,7 @@
 namespace.default.permitted.paths += /%PRODUCT_SERVICES%/priv-app
 namespace.default.permitted.paths += /data
 namespace.default.permitted.paths += /mnt/expand
-namespace.default.permitted.paths += /bionic/${LIB}
+namespace.default.permitted.paths += /apex/com.android.runtime/${LIB}/bionic
 namespace.default.permitted.paths += /system/${LIB}/bootstrap
 
 namespace.default.asan.search.paths  = /data/asan/system/${LIB}
@@ -119,7 +119,7 @@
 namespace.default.asan.permitted.paths += /%PRODUCT_SERVICES%/app
 namespace.default.asan.permitted.paths += /%PRODUCT_SERVICES%/priv-app
 namespace.default.asan.permitted.paths += /mnt/expand
-namespace.default.asan.permitted.paths += /bionic/${LIB}
+namespace.default.asan.permitted.paths += /apex/com.android.runtime/${LIB}/bionic
 namespace.default.asan.permitted.paths += /system/${LIB}/bootstrap
 
 # Keep in sync with ld.config.txt in the com.android.runtime APEX.
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 3854c73..4c52596 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -578,8 +578,6 @@
 
     # Wait for apexd to finish activating APEXes before starting more processes.
     wait_for_prop apexd.status ready
-    # TODO(jiyong): remove setup_runtime_bionic
-    setup_runtime_bionic
     parse_apex_configs
 
     init_user0