Merge "storaged: Fix SELinux denial with debugfs_mmc" into main
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 0e75033..64c85e2 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -342,9 +342,10 @@
     return value;
 }
 
-static int getIntField(const String8& path) {
+template <typename T = int>
+static T getIntField(const String8& path) {
     std::string buf;
-    int value = 0;
+    T value = 0;
 
     if (readFromFile(path, &buf) > 0)
         android::base::ParseInt(buf, &value);
@@ -416,11 +417,11 @@
 
     if (!mHealthdConfig->batteryManufacturingDatePath.empty())
         ensureBatteryHealthData(mHealthInfo.get())->batteryManufacturingDateSeconds =
-                getIntField(mHealthdConfig->batteryManufacturingDatePath);
+                getIntField<int64_t>(mHealthdConfig->batteryManufacturingDatePath);
 
     if (!mHealthdConfig->batteryFirstUsageDatePath.empty())
         ensureBatteryHealthData(mHealthInfo.get())->batteryFirstUsageSeconds =
-                getIntField(mHealthdConfig->batteryFirstUsageDatePath);
+                getIntField<int64_t>(mHealthdConfig->batteryFirstUsageDatePath);
 
     mHealthInfo->batteryTemperatureTenthsCelsius =
             mBatteryFixedTemperature ? mBatteryFixedTemperature
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index 6bb0ad7..e06a645 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -402,7 +402,7 @@
 
     // /second_stage_resources is used to preserve files from first to second
     // stage init
-    CHECKCALL(mount("tmpfs", kSecondStageRes, "tmpfs", MS_NOSUID | MS_NODEV,
+    CHECKCALL(mount("tmpfs", kSecondStageRes, "tmpfs", MS_NOEXEC | MS_NOSUID | MS_NODEV,
                     "mode=0755,uid=0,gid=0"));
 
     if (IsMicrodroid() && android::virtualization::IsOpenDiceChangesFlagEnabled()) {
diff --git a/init/selinux.cpp b/init/selinux.cpp
index 2a27c1d..03fd2d2 100644
--- a/init/selinux.cpp
+++ b/init/selinux.cpp
@@ -56,6 +56,7 @@
 #include <linux/audit.h>
 #include <linux/netlink.h>
 #include <stdlib.h>
+#include <sys/mount.h>
 #include <sys/wait.h>
 #include <unistd.h>
 
@@ -701,8 +702,8 @@
 }
 
 #ifdef ALLOW_REMOUNT_OVERLAYS
-void SetupOverlays() {
-    if (android::fs_mgr::use_override_creds) return;
+bool EarlySetupOverlays() {
+    if (android::fs_mgr::use_override_creds) return false;
 
     bool has_overlays = false;
     std::string contents;
@@ -715,8 +716,16 @@
             break;
         }
 
-    if (!has_overlays) return;
+    if (!has_overlays) return false;
+    if (mount("tmpfs", kSecondStageRes, "tmpfs", MS_REMOUNT | MS_NOSUID | MS_NODEV,
+              "mode=0755,uid=0,gid=0") == -1) {
+        PLOG(FATAL) << "Failed to remount tmpfs on " << kSecondStageRes << " to remove NO_EXEC";
+    }
 
+    return true;
+}
+
+void SetupOverlays() {
     // After adb remount, we mount all r/o volumes with overlayfs to allow writing.
     // However, since overlayfs performs its file operations in the context of the
     // mounting process, this will not work as is - init is in the kernel domain in
@@ -728,7 +737,6 @@
     // We will call overlay_remounter which will do the unmounts/mounts.
     // But for that to work, the volumes must not be busy, so we need to copy
     // overlay_remounter from system to a ramdisk and run it from there.
-
     const char* kOverlayRemounter = "overlay_remounter";
     auto or_src = std::filesystem::path("/system/xbin/") / kOverlayRemounter;
     auto or_dest = std::filesystem::path(kSecondStageRes) / kOverlayRemounter;
@@ -756,6 +764,9 @@
     PLOG(FATAL) << "execv(\"" << or_dest << "\") failed";
 }
 #else
+bool EarlySetupOverlays() {
+    return false;
+}
 void SetupOverlays() {}
 #endif
 
@@ -771,6 +782,9 @@
 
     SelinuxSetupKernelLogging();
 
+    // Test to see if we should use overlays, and if so remount tmpfs before selinux will block
+    bool use_overlays = EarlySetupOverlays();
+
     // TODO(b/287206497): refactor into different headers to only include what we need.
     if (IsMicrodroid()) {
         LoadSelinuxPolicyMicrodroid();
@@ -801,7 +815,7 @@
 
     // SetupOverlays does not return if overlays exist, instead it execs overlay_remounter
     // which then execs second stage init
-    SetupOverlays();
+    if (use_overlays) SetupOverlays();
 
     const char* path = "/system/bin/init";
     const char* args[] = {path, "second_stage", nullptr};