Merge "lmkd: limit capability set to minimum"
diff --git a/adb/test_device.py b/adb/test_device.py
index b1ad043..f995be2 100644
--- a/adb/test_device.py
+++ b/adb/test_device.py
@@ -188,8 +188,6 @@
         finally:
             self.device.reverse_remove_all()
 
-    # Note: If you run this test when adb connect'd to a physical device over
-    # TCP, it will fail in adb reverse due to https://code.google.com/p/android/issues/detail?id=189821
     def test_forward_reverse_echo(self):
         """Send data through adb forward and read it back via adb reverse"""
         forward_port = 12345
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index e60e6be..c2688e9 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -38,6 +38,7 @@
 #include <android-base/file.h>
 #include <android-base/logging.h>
 #include <android-base/parseint.h>
+#include <android-base/properties.h>
 #include <android-base/strings.h>
 #include <android/log.h>
 #include <cutils/android_reboot.h>
@@ -1096,14 +1097,28 @@
   boot_event_store->AddBootEventWithValue("absolute_boot_time", absolute_total.count());
 }
 
+// Gets the boot time offset. This is useful when Android is running in a
+// container, because the boot_clock is not reset when Android reboots.
+std::chrono::nanoseconds GetBootTimeOffset() {
+  static const int64_t boottime_offset =
+      android::base::GetIntProperty<int64_t>("ro.boot.boottime_offset", 0);
+  return std::chrono::nanoseconds(boottime_offset);
+}
+
+// Returns the current uptime, accounting for any offset in the CLOCK_BOOTTIME
+// clock.
+android::base::boot_clock::duration GetUptime() {
+  return android::base::boot_clock::now().time_since_epoch() - GetBootTimeOffset();
+}
+
 // Records several metrics related to the time it takes to boot the device,
 // including disambiguating boot time on encrypted or non-encrypted devices.
 void RecordBootComplete() {
   BootEventRecordStore boot_event_store;
   BootEventRecordStore::BootEventRecord record;
 
-  auto time_since_epoch = android::base::boot_clock::now().time_since_epoch();
-  auto uptime = std::chrono::duration_cast<std::chrono::seconds>(time_since_epoch);
+  auto uptime_ns = GetUptime();
+  auto uptime_s = std::chrono::duration_cast<std::chrono::seconds>(uptime_ns);
   time_t current_time_utc = time(nullptr);
 
   if (boot_event_store.GetBootEvent("last_boot_time_utc", &record)) {
@@ -1128,19 +1143,20 @@
     // Log the amount of time elapsed until the device is decrypted, which
     // includes the variable amount of time the user takes to enter the
     // decryption password.
-    boot_event_store.AddBootEventWithValue("boot_decryption_complete", uptime.count());
+    boot_event_store.AddBootEventWithValue("boot_decryption_complete", uptime_s.count());
 
     // Subtract the decryption time to normalize the boot cycle timing.
-    std::chrono::seconds boot_complete = std::chrono::seconds(uptime.count() - record.second);
+    std::chrono::seconds boot_complete = std::chrono::seconds(uptime_s.count() - record.second);
     boot_event_store.AddBootEventWithValue(boot_complete_prefix + "_post_decrypt",
                                            boot_complete.count());
   } else {
-    boot_event_store.AddBootEventWithValue(boot_complete_prefix + "_no_encryption", uptime.count());
+    boot_event_store.AddBootEventWithValue(boot_complete_prefix + "_no_encryption",
+                                           uptime_s.count());
   }
 
   // Record the total time from device startup to boot complete, regardless of
   // encryption state.
-  boot_event_store.AddBootEventWithValue(boot_complete_prefix, uptime.count());
+  boot_event_store.AddBootEventWithValue(boot_complete_prefix, uptime_s.count());
 
   RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init");
   RecordInitBootTimeProp(&boot_event_store, "ro.boottime.init.selinux");
@@ -1149,7 +1165,7 @@
   const BootloaderTimingMap bootloader_timings = GetBootLoaderTimings();
   RecordBootloaderTimings(&boot_event_store, bootloader_timings);
 
-  auto uptime_ms = std::chrono::duration_cast<std::chrono::milliseconds>(time_since_epoch);
+  auto uptime_ms = std::chrono::duration_cast<std::chrono::milliseconds>(uptime_ns);
   RecordAbsoluteBootTime(&boot_event_store, bootloader_timings, uptime_ms);
 }
 
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 3a3503e..41a3d6b 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -410,12 +410,6 @@
         if (!g_cmdline.empty()) {
             bootimg_set_cmdline(reinterpret_cast<boot_img_hdr_v1*>(kdata), g_cmdline);
         }
-        uint32_t header_version_existing =
-                reinterpret_cast<boot_img_hdr_v1*>(kdata)->header_version;
-        if (g_boot_img_hdr.header_version != header_version_existing) {
-            die("header version mismatch, expected: %" PRIu32 " found %" PRIu32 "",
-                g_boot_img_hdr.header_version, header_version_existing);
-        }
 
         if (!ramdisk.empty()) die("cannot boot a boot.img *and* ramdisk");
 
diff --git a/init/builtins.cpp b/init/builtins.cpp
index fc74dda..acbeca2 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -82,6 +82,7 @@
 static constexpr std::chrono::nanoseconds kCommandRetryTimeout = 5s;
 
 static Result<Success> reboot_into_recovery(const std::vector<std::string>& options) {
+    LOG(ERROR) << "Rebooting into recovery";
     std::string err;
     if (!write_bootloader_message(options, &err)) {
         return Error() << "Failed to set bootloader message: " << err;
@@ -285,11 +286,8 @@
 
     if (e4crypt_is_native()) {
         if (e4crypt_set_directory_policy(args[1].c_str())) {
-            const std::vector<std::string> options = {
-                "--prompt_and_wipe_data",
-                "--reason=set_policy_failed:"s + args[1]};
-            reboot_into_recovery(options);
-            return Success();
+            return reboot_into_recovery(
+                {"--prompt_and_wipe_data", "--reason=set_policy_failed:"s + args[1]});
         }
     }
     return Success();
@@ -493,8 +491,7 @@
         /* Setup a wipe via recovery, and reboot into recovery */
         PLOG(ERROR) << "fs_mgr_mount_all suggested recovery, so wiping data via recovery.";
         const std::vector<std::string> options = {"--wipe_data", "--reason=fs_mgr_mount_all" };
-        reboot_into_recovery(options);
-        return Success();
+        return reboot_into_recovery(options);
         /* If reboot worked, there is no return. */
     } else if (code == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
         if (e4crypt_install_keyring()) {
@@ -987,6 +984,29 @@
     return android::base::GetProperty("ro.crypto.type", "") == "file";
 }
 
+static Result<Success> ExecWithRebootOnFailure(const std::string& reboot_reason,
+                                               const BuiltinArguments& args) {
+    auto service = Service::MakeTemporaryOneshotService(args.args);
+    if (!service) {
+        return Error() << "Could not create exec service";
+    }
+    service->AddReapCallback([reboot_reason](const siginfo_t& siginfo) {
+        if (siginfo.si_code != CLD_EXITED || siginfo.si_status != 0) {
+            if (e4crypt_is_native()) {
+                LOG(ERROR) << "Rebooting into recovery, reason: " << reboot_reason;
+                reboot_into_recovery({"--prompt_and_wipe_data", "--reason="s + reboot_reason});
+            } else {
+                LOG(ERROR) << "Failure (reboot suppressed): " << reboot_reason;
+            }
+        }
+    });
+    if (auto result = service->ExecStart(); !result) {
+        return Error() << "Could not start exec service: " << result.error();
+    }
+    ServiceList::GetInstance().AddService(std::move(service));
+    return Success();
+}
+
 static Result<Success> do_installkey(const BuiltinArguments& args) {
     if (!is_file_crypto()) return Success();
 
@@ -994,15 +1014,15 @@
     if (!make_dir(unencrypted_dir, 0700) && errno != EEXIST) {
         return ErrnoError() << "Failed to create " << unencrypted_dir;
     }
-    std::vector<std::string> exec_args = {"exec", "/system/bin/vdc", "--wait", "cryptfs",
-                                          "enablefilecrypto"};
-    return do_exec({std::move(exec_args), args.context});
+    return ExecWithRebootOnFailure(
+        "enablefilecrypto_failed",
+        {{"exec", "/system/bin/vdc", "--wait", "cryptfs", "enablefilecrypto"}, args.context});
 }
 
 static Result<Success> do_init_user0(const BuiltinArguments& args) {
-    std::vector<std::string> exec_args = {"exec", "/system/bin/vdc", "--wait", "cryptfs",
-                                          "init_user0"};
-    return do_exec({std::move(exec_args), args.context});
+    return ExecWithRebootOnFailure(
+        "init_user0_failed",
+        {{"exec", "/system/bin/vdc", "--wait", "cryptfs", "init_user0"}, args.context});
 }
 
 // Builtin-function-map start
diff --git a/init/service.cpp b/init/service.cpp
index 694e5e7..f9986c5 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -303,7 +303,7 @@
     }
 }
 
-void Service::Reap() {
+void Service::Reap(const siginfo_t& siginfo) {
     if (!(flags_ & SVC_ONESHOT) || (flags_ & SVC_RESTART)) {
         KillProcessGroup(SIGKILL);
     }
@@ -312,6 +312,10 @@
     std::for_each(descriptors_.begin(), descriptors_.end(),
                   std::bind(&DescriptorInfo::Clean, std::placeholders::_1));
 
+    for (const auto& f : reap_callbacks_) {
+        f(siginfo);
+    }
+
     if (flags_ & SVC_EXEC) UnSetExec();
 
     if (flags_ & SVC_TEMPORARY) return;
diff --git a/init/service.h b/init/service.h
index d46a413..bcf1943 100644
--- a/init/service.h
+++ b/init/service.h
@@ -17,6 +17,7 @@
 #ifndef _INIT_SERVICE_H
 #define _INIT_SERVICE_H
 
+#include <signal.h>
 #include <sys/resource.h>
 #include <sys/types.h>
 
@@ -81,7 +82,7 @@
     void Stop();
     void Terminate();
     void Restart();
-    void Reap();
+    void Reap(const siginfo_t& siginfo);
     void DumpState() const;
     void SetShutdownCritical() { flags_ |= SVC_SHUTDOWN_CRITICAL; }
     bool IsShutdownCritical() const { return (flags_ & SVC_SHUTDOWN_CRITICAL) != 0; }
@@ -89,6 +90,9 @@
         is_exec_service_running_ = false;
         flags_ &= ~SVC_EXEC;
     }
+    void AddReapCallback(std::function<void(const siginfo_t& siginfo)> callback) {
+        reap_callbacks_.emplace_back(std::move(callback));
+    }
 
     static bool is_exec_service_running() { return is_exec_service_running_; }
 
@@ -210,6 +214,8 @@
     std::vector<std::pair<int, rlimit>> rlimits_;
 
     std::vector<std::string> args_;
+
+    std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_;
 };
 
 class ServiceList {
diff --git a/init/sigchld_handler.cpp b/init/sigchld_handler.cpp
index 3ec76df..0b03324 100644
--- a/init/sigchld_handler.cpp
+++ b/init/sigchld_handler.cpp
@@ -81,16 +81,15 @@
         }
     }
 
-    auto status = siginfo.si_status;
-    if (WIFEXITED(status)) {
-        LOG(INFO) << name << " exited with status " << WEXITSTATUS(status) << wait_string;
-    } else if (WIFSIGNALED(status)) {
-        LOG(INFO) << name << " killed by signal " << WTERMSIG(status) << wait_string;
+    if (siginfo.si_code == CLD_EXITED) {
+        LOG(INFO) << name << " exited with status " << siginfo.si_status << wait_string;
+    } else {
+        LOG(INFO) << name << " received signal " << siginfo.si_status << wait_string;
     }
 
     if (!service) return true;
 
-    service->Reap();
+    service->Reap(siginfo);
 
     if (service->flags() & SVC_TEMPORARY) {
         ServiceList::GetInstance().RemoveService(*service);
diff --git a/libmemunreachable/Android.bp b/libmemunreachable/Android.bp
index f872d0f..619ee34 100644
--- a/libmemunreachable/Android.bp
+++ b/libmemunreachable/Android.bp
@@ -46,6 +46,12 @@
             static_libs: ["libunwind_llvm"],
         },
     },
+
+    // TODO(b/78118944), clang lld link flags do not work with special link
+    // rules for libunwind_llvm yet. Linked aosp_arm-eng image failed to
+    // boot up in the emulator.
+    use_clang_lld: false,
+
     export_include_dirs: ["include"],
     local_include_dirs: ["include"],
 }