Merge tag 'android-security-10.0.0_r53' into int/10/fp2

Android security 10.0.0 release 53

* tag 'android-security-10.0.0_r53':
  Revert "Revert "Revert "vold now prepares a subdirectory for face data."""

Change-Id: I934414d83db017556b7ecb32d43dea8cbc4b5d99
diff --git a/Checkpoint.cpp b/Checkpoint.cpp
index c8af08c..3f688f8 100644
--- a/Checkpoint.cpp
+++ b/Checkpoint.cpp
@@ -244,6 +244,11 @@
 }
 
 bool cp_needsCheckpoint() {
+    // Make sure we only return true during boot. See b/138952436 for discussion
+    static bool called_once = false;
+    if (called_once) return isCheckpointing;
+    called_once = true;
+
     bool ret;
     std::string content;
     sp<IBootControl> module = IBootControl::getService();
@@ -317,6 +322,8 @@
 }  // namespace
 
 Status cp_prepareCheckpoint() {
+    // Log to notify CTS - see b/137924328 for context
+    LOG(INFO) << "cp_prepareCheckpoint called";
     if (!isCheckpointing) {
         return Status::ok();
     }
diff --git a/FsCrypt.cpp b/FsCrypt.cpp
index 2a8e110..07560e0 100644
--- a/FsCrypt.cpp
+++ b/FsCrypt.cpp
@@ -84,7 +84,7 @@
 const std::string systemwide_volume_key_dir =
     std::string() + DATA_MNT_POINT + "/misc/vold/volume_keys";
 
-bool s_global_de_initialized = false;
+bool s_systemwide_keys_initialized = false;
 
 // Some users are ephemeral, don't try to wipe their keys from disk
 std::set<userid_t> s_ephemeral_users;
@@ -335,10 +335,10 @@
     return true;
 }
 
-bool fscrypt_initialize_global_de() {
-    LOG(INFO) << "fscrypt_initialize_global_de";
+bool fscrypt_initialize_systemwide_keys() {
+    LOG(INFO) << "fscrypt_initialize_systemwide_keys";
 
-    if (s_global_de_initialized) {
+    if (s_systemwide_keys_initialized) {
         LOG(INFO) << "Already initialized";
         return true;
     }
@@ -355,11 +355,18 @@
 
     std::string ref_filename = std::string("/data") + fscrypt_key_ref;
     if (!android::vold::writeStringToFile(device_ref.key_raw_ref, ref_filename)) return false;
-
     LOG(INFO) << "Wrote system DE key reference to:" << ref_filename;
 
+    KeyBuffer per_boot_key;
+    if (!android::vold::randomKey(&per_boot_key)) return false;
+    std::string per_boot_raw_ref;
+    if (!android::vold::installKey(per_boot_key, &per_boot_raw_ref)) return false;
+    std::string per_boot_ref_filename = std::string("/data") + fscrypt_key_per_boot_ref;
+    if (!android::vold::writeStringToFile(per_boot_raw_ref, per_boot_ref_filename)) return false;
+    LOG(INFO) << "Wrote per boot key reference to:" << per_boot_ref_filename;
+
     if (!android::vold::FsyncDirectory(device_key_dir)) return false;
-    s_global_de_initialized = true;
+    s_systemwide_keys_initialized = true;
     return true;
 }
 
diff --git a/FsCrypt.h b/FsCrypt.h
index 16e2f9a..03ec2e1 100644
--- a/FsCrypt.h
+++ b/FsCrypt.h
@@ -18,7 +18,7 @@
 
 #include <cutils/multiuser.h>
 
-bool fscrypt_initialize_global_de();
+bool fscrypt_initialize_systemwide_keys();
 
 bool fscrypt_init_user0();
 bool fscrypt_vold_create_user_key(userid_t user_id, int serial, bool ephemeral);
diff --git a/Loop.cpp b/Loop.cpp
index fa8f8ba..f5d2481 100644
--- a/Loop.cpp
+++ b/Loop.cpp
@@ -31,6 +31,9 @@
 
 #include <linux/kdev_t.h>
 
+#include <chrono>
+#include <thread>
+
 #include <android-base/logging.h>
 #include <android-base/stringprintf.h>
 #include <android-base/strings.h>
@@ -41,12 +44,29 @@
 #include "VoldUtil.h"
 #include "sehandle.h"
 
+using namespace std::literals;
 using android::base::StringPrintf;
 using android::base::unique_fd;
 
 static const char* kVoldPrefix = "vold:";
 static constexpr size_t kLoopDeviceRetryAttempts = 3u;
 
+static bool wait_for_file(const std::string& filename,
+                          const std::chrono::milliseconds relative_timeout) {
+    auto start_time = std::chrono::steady_clock::now();
+
+    while (true) {
+        int rv = access(filename.c_str(), F_OK);
+        if (!rv || errno != ENOENT) return true;
+
+        std::this_thread::sleep_for(50ms);
+
+        auto now = std::chrono::steady_clock::now();
+        auto time_elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time);
+        if (time_elapsed > relative_timeout) return false;
+    }
+}
+
 int Loop::create(const std::string& target, std::string& out_device) {
     unique_fd ctl_fd(open("/dev/loop-control", O_RDWR | O_CLOEXEC));
     if (ctl_fd.get() == -1) {
@@ -74,6 +94,12 @@
         PLOG(ERROR) << "Failed to open " << target;
         return -errno;
     }
+
+    if (!wait_for_file(out_device, 2s)) {
+        LOG(ERROR) << "Failed to find " << out_device;
+        return -ENOENT;
+    }
+
     unique_fd device_fd(open(out_device.c_str(), O_RDWR | O_CLOEXEC));
     if (device_fd.get() == -1) {
         PLOG(ERROR) << "Failed to open " << out_device;
diff --git a/VoldNativeService.cpp b/VoldNativeService.cpp
index 1762b70..7f7f289 100644
--- a/VoldNativeService.cpp
+++ b/VoldNativeService.cpp
@@ -691,7 +691,7 @@
     ENFORCE_UID(AID_SYSTEM);
     ACQUIRE_CRYPT_LOCK;
 
-    return translateBool(fscrypt_initialize_global_de());
+    return translateBool(fscrypt_initialize_systemwide_keys());
 }
 
 binder::Status VoldNativeService::mountDefaultEncrypted() {
diff --git a/secdiscard.cpp b/secdiscard.cpp
index 0ff05d6..4659eed 100644
--- a/secdiscard.cpp
+++ b/secdiscard.cpp
@@ -147,6 +147,10 @@
             if (!overwrite_with_zeros(fs_fd.get(), range[0], range[1])) return false;
         }
     }
+    // Should wait for overwrites completion. Otherwise after unlink(),
+    // filesystem can allocate these blocks and IO can be reordered, resulting
+    // in making zero blocks to filesystem blocks.
+    fsync(fs_fd.get());
     return true;
 }