Merge "init.rc: set fsck log permission on post-fs-data"
diff --git a/init/Android.bp b/init/Android.bp
index 69ee34f..69498ac 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -61,6 +61,7 @@
     static_libs: [
         "libseccomp_policy",
         "libavb",
+        "libc++fs",
         "libcgrouprc_format",
         "libprotobuf-cpp-lite",
         "libpropertyinfoserializer",
diff --git a/init/Android.mk b/init/Android.mk
index 39af0e6..efa8d87 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -68,12 +68,14 @@
 # Set up the same mount points on the ramdisk that system-as-root contains.
 LOCAL_POST_INSTALL_CMD := mkdir -p \
     $(TARGET_RAMDISK_OUT)/apex \
+    $(TARGET_RAMDISK_OUT)/debug_ramdisk \
     $(TARGET_RAMDISK_OUT)/dev \
     $(TARGET_RAMDISK_OUT)/mnt \
     $(TARGET_RAMDISK_OUT)/proc \
     $(TARGET_RAMDISK_OUT)/sys \
 
 LOCAL_STATIC_LIBRARIES := \
+    libc++fs \
     libfs_avb \
     libfs_mgr \
     libfec \
diff --git a/init/debug_ramdisk.h b/init/debug_ramdisk.h
new file mode 100644
index 0000000..4e3a395
--- /dev/null
+++ b/init/debug_ramdisk.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#pragma once
+
+namespace android {
+namespace init {
+
+constexpr const char kDebugRamdiskProp[] = "/debug_ramdisk/adb_debug.prop";
+constexpr const char kDebugRamdiskSEPolicy[] = "/debug_ramdisk/userdebug_plat_sepolicy.cil";
+
+}  // namespace init
+}  // namespace android
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index c566676..8b95e38 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -26,6 +26,7 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#include <filesystem>
 #include <string>
 #include <vector>
 
@@ -35,6 +36,7 @@
 #include <cutils/android_reboot.h>
 #include <private/android_filesystem_config.h>
 
+#include "debug_ramdisk.h"
 #include "first_stage_mount.h"
 #include "reboot_utils.h"
 #include "switch_root.h"
@@ -44,6 +46,8 @@
 
 using namespace std::literals;
 
+namespace fs = std::filesystem;
+
 namespace android {
 namespace init {
 
@@ -159,6 +163,9 @@
     CHECKCALL(mount("tmpfs", "/apex", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
                     "mode=0755,uid=0,gid=0"));
 
+    // /debug_ramdisk is used to preserve additional files from the debug ramdisk
+    CHECKCALL(mount("tmpfs", "/debug_ramdisk", "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
+                    "mode=0755,uid=0,gid=0"));
 #undef CHECKCALL
 
     // Now that tmpfs is mounted on /dev and we have /dev/kmsg, we can actually
@@ -202,7 +209,14 @@
     // 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);
+        std::error_code ec;  // to invoke the overloaded copy_file() that won't throw.
+        if (!fs::copy_file("/adb_debug.prop", kDebugRamdiskProp, ec) ||
+            !fs::copy_file("/userdebug_plat_sepolicy.cil", kDebugRamdiskSEPolicy, ec)) {
+            LOG(ERROR) << "Failed to setup debug ramdisk";
+        } else {
+            // setenv for second-stage init to read above kDebugRamdisk* files.
+            setenv("INIT_FORCE_DEBUGGABLE", "true", 1);
+        }
     }
 
     if (!DoFirstStageMount()) {
diff --git a/init/init.cpp b/init/init.cpp
index ac0e67a..c79e459 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -621,6 +621,12 @@
     });
 }
 
+static void UmountDebugRamdisk() {
+    if (umount("/debug_ramdisk") != 0) {
+        LOG(ERROR) << "Failed to umount /debug_ramdisk";
+    }
+}
+
 int SecondStageMain(int argc, char** argv) {
     if (REBOOT_BOOTLOADER_ON_PANIC) {
         InstallRebootSignalHandlers();
@@ -690,6 +696,7 @@
     InstallSignalFdHandler(&epoll);
 
     property_load_boot_defaults(load_debug_prop);
+    UmountDebugRamdisk();
     fs_mgr_vendor_overlay_mount_all();
     export_oem_lock_status();
     StartPropertyService(&epoll);
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 467568c..bf3b317 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -56,6 +56,7 @@
 #include <selinux/label.h>
 #include <selinux/selinux.h>
 
+#include "debug_ramdisk.h"
 #include "epoll.h"
 #include "init.h"
 #include "persistent_properties.h"
@@ -887,9 +888,8 @@
     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);
+        LOG(INFO) << "Loading " << kDebugRamdiskProp;
+        load_properties_from_file(kDebugRamdiskProp, nullptr, &properties);
     }
 
     for (const auto& [name, value] : properties) {
diff --git a/init/selinux.cpp b/init/selinux.cpp
index aa66baa..132fc13 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -64,6 +64,7 @@
 #include <fs_avb/fs_avb.h>
 #include <selinux/android.h>
 
+#include "debug_ramdisk.h"
 #include "reboot_utils.h"
 #include "util.h"
 
@@ -271,8 +272,6 @@
 }
 
 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;
@@ -292,7 +291,7 @@
     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);
+             AvbHandle::IsDeviceUnlocked() && access(kDebugRamdiskSEPolicy, F_OK) == 0);
     if (use_userdebug_policy) {
         LOG(WARNING) << "Using userdebug system sepolicy";
     }
@@ -367,7 +366,7 @@
     // clang-format off
     std::vector<const char*> compile_args {
         "/system/bin/secilc",
-        use_userdebug_policy ? userdebug_plat_policy_cil_file : plat_policy_cil_file,
+        use_userdebug_policy ? kDebugRamdiskSEPolicy: plat_policy_cil_file,
         "-m", "-M", "true", "-G", "-N",
         "-c", version_as_string.c_str(),
         plat_mapping_file.c_str(),
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 0044534..c464c17 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -97,7 +97,7 @@
 #
 # create some directories (some are mount points) and symlinks
 LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
-    dev proc sys system data odm oem acct config storage mnt apex $(BOARD_ROOT_EXTRA_FOLDERS)); \
+    dev proc sys system data odm oem acct config storage mnt apex debug_ramdisk $(BOARD_ROOT_EXTRA_FOLDERS)); \
     ln -sf /system/bin $(TARGET_ROOT_OUT)/bin; \
     ln -sf /system/etc $(TARGET_ROOT_OUT)/etc; \
     ln -sf /data/user_de/0/com.android.shell/files/bugreports $(TARGET_ROOT_OUT)/bugreports; \