Fix crash in mainline
Current behavior:
Assume not checkpointing
cp_startCheckpoint creates the file in metadata
cp_needsCheckpoint will now set isCheckpointing to true
cp_commitCheckpoint will now think there is a checkpoint, and try to
commit it. This will fail on ext4 and it will return false, leading to
bad things.
cp_startCheckpoint is called when staging an apex module for update.
After this point, several things could go wrong:
If a keystore key is deleted, it calls cp_needsCheckpoint to see if the
delete should be deferred until cp_commitCheckpoint. The delete will now
be deferred, meaning that this key will never be deleted, using up the
key sots in trustzone
If a trim is scheduled through idle maintenance, this also calls
cp_needsCheckpoint, so the trims will not occur.
If either of these happens before a system crash, the device will not
recover since the system calls commitCheckpoint which will now crash.
When the system then goes on to reboot, the checkpoint will not be
triggered, since the commitCheckpoint call will have deleted the
checkpoint flag file before crashing.
Bug: 138952436
Test: vdc checkpoint startCheckpoint 5
vdc checkpoint needsCheckpoint
vdc checkpoint commitChanges
stop;start
commitChanges fails, then device loops
After applying this test, commitChanges succeeds and device does
not loop
Change-Id: I135099625f77344d1f8d2e8688735871c44ef2f5
diff --git a/Checkpoint.cpp b/Checkpoint.cpp
index a2db4bd..e5ef4a2 100644
--- a/Checkpoint.cpp
+++ b/Checkpoint.cpp
@@ -263,6 +263,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();