Snap for 7584587 from 1688fbd24f824784e52056e8ed139bdf4b67def1 to sc-d2-release

Change-Id: I26ab91fe71f5e487b706ab000bf960e04c9325c7
diff --git a/apexd/apexd.cpp b/apexd/apexd.cpp
index fbd714b..ba76031 100644
--- a/apexd/apexd.cpp
+++ b/apexd/apexd.cpp
@@ -714,19 +714,24 @@
     return mount_status.error();
   }
   auto cleaner = [&]() {
-    if (unmount_during_cleanup) {
-      LOG(DEBUG) << "Unmounting " << temp_mount_point;
-      Result<void> result = Unmount(*mount_status, /* deferred= */ false);
-      if (!result.ok()) {
-        LOG(WARNING) << "Failed to unmount " << temp_mount_point << " : "
-                     << result.error();
-      }
-      gMountedApexes.RemoveMountedApex(apex.GetManifest().name(),
-                                       apex.GetPath(), true);
+    LOG(DEBUG) << "Unmounting " << temp_mount_point;
+    Result<void> result = Unmount(*mount_status, /* deferred= */ false);
+    if (!result.ok()) {
+      LOG(WARNING) << "Failed to unmount " << temp_mount_point << " : "
+                   << result.error();
     }
+    gMountedApexes.RemoveMountedApex(apex.GetManifest().name(), apex.GetPath(),
+                                     true);
   };
   auto scope_guard = android::base::make_scope_guard(cleaner);
-  return verify_fn(temp_mount_point);
+  auto result = verify_fn(temp_mount_point);
+  if (!result.ok()) {
+    return result.error();
+  }
+  if (!unmount_during_cleanup) {
+    scope_guard.Disable();
+  }
+  return {};
 }
 
 template <typename HookFn, typename HookCall>
@@ -2936,6 +2941,11 @@
   }
 
   std::vector<ApexFile> ret;
+  auto guard = android::base::make_scope_guard([&ret]() {
+    for (const auto& apex : ret) {
+      apexd_private::UnmountTempMount(apex);
+    }
+  });
   for (int id_to_scan : ids_to_scan) {
     auto verified = VerifySessionDir(id_to_scan);
     if (!verified.ok()) {
diff --git a/apexd/apexservice_test.cpp b/apexd/apexservice_test.cpp
index c123796..545bb38 100644
--- a/apexd/apexservice_test.cpp
+++ b/apexd/apexservice_test.cpp
@@ -73,6 +73,7 @@
 using android::apex::testing::CreateSessionInfo;
 using android::apex::testing::IsOk;
 using android::apex::testing::SessionInfoEq;
+using android::base::EndsWith;
 using android::base::ErrnoError;
 using android::base::Join;
 using android::base::ReadFully;
@@ -953,6 +954,31 @@
   ASSERT_FALSE(DirExists("/data/misc_ce/0/apexrollback/98765"));
 }
 
+TEST_F(ApexServiceTest, SubmitStagedSessionCleanupsTempMountOnFailure) {
+  // Parent session id: 23
+  // Children session ids: 37 73
+  PrepareTestApexForInstall installer(
+      GetTestFile("apex.apexd_test_different_app.apex"),
+      "/data/app-staging/session_37", "staging_data_file");
+  PrepareTestApexForInstall installer2(
+      GetTestFile("apex.apexd_test_manifest_mismatch.apex"),
+      "/data/app-staging/session_73", "staging_data_file");
+  if (!installer.Prepare() || !installer2.Prepare()) {
+    FAIL() << GetDebugStr(&installer) << GetDebugStr(&installer2);
+  }
+  ApexInfoList list;
+  ApexSessionParams params;
+  params.sessionId = 23;
+  params.childSessionIds = {37, 73};
+  ASSERT_FALSE(IsOk(service_->submitStagedSession(params, &list)))
+      << GetDebugStr(&installer);
+
+  // Check that temp mounts were cleanded up.
+  for (const auto& mount : GetApexMounts()) {
+    EXPECT_FALSE(EndsWith(mount, ".tmp")) << "Found temp mount " << mount;
+  }
+}
+
 template <typename NameProvider>
 class ApexServiceActivationTest : public ApexServiceTest {
  public:
@@ -1887,6 +1913,11 @@
   expected.isVerified = false;
   expected.isStaged = true;
   ASSERT_THAT(session, SessionInfoEq(expected));
+
+  // Check that temp mounts were cleanded up.
+  for (const auto& mount : GetApexMounts()) {
+    EXPECT_FALSE(EndsWith(mount, ".tmp")) << "Found temp mount " << mount;
+  }
 }
 
 TEST_F(ApexServiceTest, SubmitMultiSessionTestFail) {