Merge "Fix sign-compare warnings"
diff --git a/debuggerd/libdebuggerd/test/tombstone_test.cpp b/debuggerd/libdebuggerd/test/tombstone_test.cpp
index 421ce43..d24c887 100644
--- a/debuggerd/libdebuggerd/test/tombstone_test.cpp
+++ b/debuggerd/libdebuggerd/test/tombstone_test.cpp
@@ -15,6 +15,7 @@
  */
 
 #include <stdlib.h>
+#include <time.h>
 
 #include <memory>
 #include <string>
@@ -494,3 +495,10 @@
   expected += android::base::StringPrintf("ABI: '%s'\n", ABI_STRING);
   ASSERT_STREQ(expected.c_str(), amfd_data_.c_str());
 }
+
+TEST_F(TombstoneTest, dump_timestamp) {
+  setenv("TZ", "UTC", 1);
+  tzset();
+  dump_timestamp(&log_, 0);
+  ASSERT_STREQ("Timestamp: 1970-01-01 00:00:00+0000\n", amfd_data_.c_str());
+}
diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp
index 1179263..b20014f 100644
--- a/debuggerd/libdebuggerd/tombstone.cpp
+++ b/debuggerd/libdebuggerd/tombstone.cpp
@@ -78,6 +78,15 @@
   _LOG(log, logtype::HEADER, "ABI: '%s'\n", ABI_STRING);
 }
 
+static void dump_timestamp(log_t* log, time_t time) {
+  struct tm tm;
+  localtime_r(&time, &tm);
+
+  char buf[strlen("1970-01-01 00:00:00+0830") + 1];
+  strftime(buf, sizeof(buf), "%F %T%z", &tm);
+  _LOG(log, logtype::HEADER, "Timestamp: %s\n", buf);
+}
+
 static void dump_probable_cause(log_t* log, const siginfo_t* si, BacktraceMap* map) {
   std::string cause;
   if (si->si_signo == SIGSEGV && si->si_code == SEGV_MAPERR) {
@@ -654,6 +663,7 @@
 
   _LOG(&log, logtype::HEADER, "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n");
   dump_header_info(&log);
+  dump_timestamp(&log, time(nullptr));
 
   auto it = threads.find(target_thread);
   if (it == threads.end()) {
diff --git a/fs_mgr/tests/adb-remount-test.sh b/fs_mgr/tests/adb-remount-test.sh
index aaee1a7..5957e30 100755
--- a/fs_mgr/tests/adb-remount-test.sh
+++ b/fs_mgr/tests/adb-remount-test.sh
@@ -290,6 +290,11 @@
 fi
 inAdb || die "specified device not in adb mode"
 isDebuggable || die "device not a debug build"
+enforcing=true
+if ! adb_su getenforce </dev/null | grep 'Enforcing' >/dev/null; then
+  echo "${ORANGE}[  WARNING ]${NORMAL} device does not have sepolicy in enforcing mode"
+  enforcing=false
+fi
 
 # Do something
 
@@ -535,9 +540,11 @@
   die "re-read system hello after reboot"
 check_eq "${A}" "${B}" system after reboot
 # Only root can read vendor if sepolicy permissions are as expected
-B="`adb_cat /vendor/hello`" &&
-  die "re-read vendor hello after reboot w/o root"
-check_eq "cat: /vendor/hello: Permission denied" "${B}" vendor after reboot w/o root
+if ${enforcing}; then
+  B="`adb_cat /vendor/hello`" &&
+    die "re-read vendor hello after reboot w/o root"
+  check_eq "cat: /vendor/hello: Permission denied" "${B}" vendor after reboot w/o root
+fi
 adb_root &&
   B="`adb_cat /vendor/hello`" ||
   die "re-read vendor hello after reboot"
diff --git a/init/first_stage_mount.cpp b/init/first_stage_mount.cpp
index c96c381..acefdf0 100644
--- a/init/first_stage_mount.cpp
+++ b/init/first_stage_mount.cpp
@@ -42,6 +42,7 @@
 #include "uevent_listener.h"
 #include "util.h"
 
+using android::base::ReadFileToString;
 using android::base::Split;
 using android::base::Timer;
 using android::fs_mgr::AvbHandle;
@@ -73,6 +74,8 @@
     bool CreateLogicalPartitions();
     bool MountPartition(FstabEntry* fstab_entry);
     bool MountPartitions();
+    bool TrySwitchSystemAsRoot();
+    bool TrySkipMountingPartitions();
     bool IsDmLinearEnabled();
     bool GetDmLinearMetadataDevice();
     bool InitDmLinearBackingDevices(const android::fs_mgr::LpMetadata& metadata);
@@ -398,10 +401,10 @@
     return true;
 }
 
-bool FirstStageMount::MountPartitions() {
-    // If system is in the fstab then we're not a system-as-root device, and in
-    // this case, we mount system first then pivot to it.  From that point on,
-    // we are effectively identical to a system-as-root device.
+// If system is in the fstab then we're not a system-as-root device, and in
+// this case, we mount system first then pivot to it.  From that point on,
+// we are effectively identical to a system-as-root device.
+bool FirstStageMount::TrySwitchSystemAsRoot() {
     auto system_partition = std::find_if(fstab_.begin(), fstab_.end(), [](const auto& entry) {
         return entry.mount_point == "/system";
     });
@@ -416,6 +419,44 @@
         fstab_.erase(system_partition);
     }
 
+    return true;
+}
+
+// For GSI to skip mounting /product and /product_services, until there are
+// well-defined interfaces between them and /system. Otherwise, the GSI flashed
+// on /system might not be able to work with /product and /product_services.
+// When they're skipped here, /system/product and /system/product_services in
+// GSI will be used.
+bool FirstStageMount::TrySkipMountingPartitions() {
+    constexpr const char kSkipMountConfig[] = "/system/etc/init/config/skip_mount.cfg";
+
+    std::string skip_config;
+    if (!ReadFileToString(kSkipMountConfig, &skip_config)) {
+        return true;
+    }
+
+    for (const auto& skip_mount_point : Split(skip_config, "\n")) {
+        if (skip_mount_point.empty()) {
+            continue;
+        }
+        auto removing_entry =
+                std::find_if(fstab_.begin(), fstab_.end(), [&skip_mount_point](const auto& entry) {
+                    return entry.mount_point == skip_mount_point;
+                });
+        if (removing_entry != fstab_.end()) {
+            fstab_.erase(removing_entry);
+            LOG(INFO) << "Skip mounting partition: " << skip_mount_point;
+        }
+    }
+
+    return true;
+}
+
+bool FirstStageMount::MountPartitions() {
+    if (!TrySwitchSystemAsRoot()) return false;
+
+    if (!TrySkipMountingPartitions()) return false;
+
     for (auto& fstab_entry : fstab_) {
         if (!MountPartition(&fstab_entry) && !fstab_entry.fs_mgr_flags.no_fail) {
             return false;
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 349168e..6fb1a8b 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -583,8 +583,8 @@
     # Set SELinux security contexts on upgrade or policy update.
     restorecon --recursive --skip-ce /data
 
-    # Check any timezone data in /data is newer than the copy in /system, delete if not.
-    exec - system system -- /system/bin/tzdatacheck /system/usr/share/zoneinfo /data/misc/zoneinfo
+    # Check any timezone data in /data is newer than the copy in the runtime module, delete if not.
+    exec - system system -- /system/bin/tzdatacheck /apex/com.android.runtime/etc/tz /data/misc/zoneinfo
 
     # If there is no post-fs-data action in the init.<device>.rc file, you
     # must uncomment this line, otherwise encrypted filesystems