Await boot_completed before allowing GC

Add a global that tracks whether `sys.boot_completed` has reached 1,
together with an accessor.

At start of day, kick off a thread that monitors for the property
getting set.  When it does get set, kick off a GC and exit the
monitoring thread.

In the garbage collection code, avoid performing GC until boot
has completed, so as to avoid doing any deleteKey() operations
that would prevent a failed OTA from being successfully rolled back.

Adapted from https://android-review.git.corp.google.com/c/platform/system/security/+/3445820/4

Bug: 388723650
Flag: EXEMPT bugfix

Test: atest keystore2_client_tests
Test: atest CtsKeystoreTestCases
Test: On a device that supports rollback-resistant Keystore keys,
      manually tested that this CL fixes the bug:
      1. Flashed udc-d1-release
      2. Completed setup wizard, but didn't set an LSKF
      3. Checked out 24Q3-release
      4. Patched system_server to crash the main thread with an
         exception after the LockSettingsService migration code has run
      5. Applied this CL (when applicable)
      6. m dist
      7. system/update_engine/scripts/update_device.py <path-to-ota-package>
      8. adb reboot
      9. Collected logcat for boot on new build
      10. Waited for rollback, then collected logcat again

      Tested without and with this CL applied in (5).  Observed that
      without this CL, boot failed after rollback, and logcat contained
      errors about the synthetic password failing to be decrypted due to
      an invalid Keymint blob.  Observed that with this CL, the rollback
      succeeds and logcat shows that the user's CE storage was unlocked.

Change-Id: Ibc5c137e8e5b2ebff762191e19095aa9bd05f749
diff --git a/keystore2/src/gc.rs b/keystore2/src/gc.rs
index f2341e3..9741671 100644
--- a/keystore2/src/gc.rs
+++ b/keystore2/src/gc.rs
@@ -22,6 +22,7 @@
 use crate::{
     async_task,
     database::{KeystoreDB, SupersededBlob, Uuid},
+    globals,
     super_key::SuperKeyManager,
 };
 use anyhow::{Context, Result};
@@ -135,6 +136,17 @@
     /// Processes one key and then schedules another attempt until it runs out of blobs to delete.
     fn step(&mut self) {
         self.notified.store(0, Ordering::Relaxed);
+        if !globals::boot_completed() {
+            // Garbage collection involves a operation (`IKeyMintDevice::deleteKey()`) that cannot
+            // be rolled back in some cases (specifically, when the key is rollback-resistant), even
+            // if the Keystore database is restored to the version of an earlier userdata filesystem
+            // checkpoint.
+            //
+            // This means that we should not perform GC until boot has fully completed, and any
+            // in-progress OTA is definitely not going to be rolled back.
+            log::info!("skip GC as boot not completed");
+            return;
+        }
         if let Err(e) = self.process_one_key() {
             log::error!("Error trying to delete blob entry. {:?}", e);
         }