From 8cc5716ef109b3e7b8926fdced0aef1bb96368d0 Mon Sep 17 00:00:00 2001 From: Daniel Rosenberg Date: Thu, 6 Jun 2019 20:38:38 -0700 Subject: [PATCH] Defer deleteKey in KeyStorage in Checkpointing mode Don't delete keys in checkpointing mode. Instead wait until the checkpoint has been committed. Bug: 134631661 Test: Flash A with a working build. Flash B with a broken build. Test that the device rolls back to A without getting sent to recovery. Change-Id: Ie5fc2d098355e2d095c53e9a95a6a8c7ab7ed051 --- KeyStorage.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/KeyStorage.cpp b/KeyStorage.cpp index d00225b..0290086 100644 --- a/KeyStorage.cpp +++ b/KeyStorage.cpp @@ -19,7 +19,9 @@ #include "Keymaster.h" #include "ScryptParameters.h" #include "Utils.h" +#include "Checkpoint.h" +#include #include #include @@ -36,6 +38,7 @@ #include #include #include +#include #include @@ -171,6 +174,28 @@ bool readSecdiscardable(const std::string& filename, std::string* hash) { return true; } +static void deferedKmDeleteKey(const std::string& kmkey) { + while (!android::base::WaitForProperty("vold.checkpoint_committed", "1")) { + LOG(ERROR) << "Wait for boot timed out"; + } + Keymaster keymaster; + if (!keymaster || !keymaster.deleteKey(kmkey)) { + LOG(ERROR) << "Defered Key deletion failed during upgrade"; + } +} + +bool kmDeleteKey(Keymaster& keymaster, const std::string& kmKey) { + bool needs_cp = cp_needsCheckpoint(); + + if (needs_cp) { + std::thread(deferedKmDeleteKey, kmKey).detach(); + LOG(INFO) << "Deferring Key deletion during upgrade"; + return true; + } else { + return keymaster.deleteKey(kmKey); + } +} + static KeymasterOperation begin(Keymaster& keymaster, const std::string& dir, km::KeyPurpose purpose, const km::AuthorizationSet& keyParams, const km::AuthorizationSet& opParams, @@ -201,7 +226,7 @@ static KeymasterOperation begin(Keymaster& keymaster, const std::string& dir, LOG(ERROR) << "Key dir sync failed: " << dir; return KeymasterOperation(); } - if (!keymaster.deleteKey(kmKey)) { + if (!kmDeleteKey(keymaster, kmKey)) { LOG(ERROR) << "Key deletion failed during upgrade, continuing anyway: " << dir; } }