When encryption fails, reboot into recovery
Set flag on starting encryption to say it failed, and only clear
when we get into a recoverable state (partially or fully encrypted.)
Go to recovery on seeing this flag on boot
Bug: 16552363
Change-Id: I7e452b653edf3a087ecfaba8f81f41765a1c8daf
diff --git a/cryptfs.c b/cryptfs.c
index d11c133..252be0a 100644
--- a/cryptfs.c
+++ b/cryptfs.c
@@ -1524,7 +1524,8 @@
}
}
- if (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS) {
+ if (crypt_ftr.flags
+ & (CRYPT_ENCRYPTION_IN_PROGRESS | CRYPT_INCONSISTENT_STATE)) {
SLOGE("Encryption process didn't finish successfully\n");
return -2; /* -2 is the clue to the UI that there is no usable data on the disk,
* and give the user an option to wipe the disk */
@@ -2412,6 +2413,15 @@
&& (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS)) {
previously_encrypted_upto = crypt_ftr.encrypted_upto;
crypt_ftr.encrypted_upto = 0;
+ crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS;
+
+ /* At this point, we are in an inconsistent state. Until we successfully
+ complete encryption, a reboot will leave us broken. So mark the
+ encryption failed in case that happens.
+ On successfully completing encryption, remove this flag */
+ crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
+
+ put_crypt_ftr_and_key(&crypt_ftr);
}
property_get("ro.crypto.state", encrypted_state, "");
@@ -2561,7 +2571,11 @@
} else {
crypt_ftr.fs_size = nr_sec;
}
- crypt_ftr.flags |= CRYPT_ENCRYPTION_IN_PROGRESS;
+ /* At this point, we are in an inconsistent state. Until we successfully
+ complete encryption, a reboot will leave us broken. So mark the
+ encryption failed in case that happens.
+ On successfully completing encryption, remove this flag */
+ crypt_ftr.flags |= CRYPT_INCONSISTENT_STATE;
crypt_ftr.crypt_type = crypt_type;
strcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256");
@@ -2629,18 +2643,15 @@
if (! rc) {
/* Success */
+ crypt_ftr.flags &= ~CRYPT_INCONSISTENT_STATE;
- /* Clear the encryption in progress flag in the footer */
- if (crypt_ftr.encrypted_upto == crypt_ftr.fs_size) {
- crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS;
- } else {
+ if (crypt_ftr.encrypted_upto != crypt_ftr.fs_size) {
SLOGD("Encrypted up to sector %lld - will continue after reboot",
crypt_ftr.encrypted_upto);
+ crypt_ftr.flags |= CRYPT_ENCRYPTION_IN_PROGRESS;
}
- if (crypt_ftr.encrypted_upto) {
- put_crypt_ftr_and_key(&crypt_ftr);
- }
+ put_crypt_ftr_and_key(&crypt_ftr);
sleep(2); /* Give the UI a chance to show 100% progress */
/* Partially encrypted - ensure writes are flushed to ssd */
@@ -2924,9 +2935,10 @@
}
}
- /** @TODO make sure we factory wipe in this situation
- * In general if we got here there is no recovery
+ /** Corrupt. Allow us to boot into framework, which will detect bad
+ crypto when it calls do_crypto_complete, then do a factory reset
*/
+ property_set("vold.decrypt", "trigger_restart_min_framework");
return 0;
}
@@ -2941,6 +2953,10 @@
return -1;
}
+ if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE) {
+ return -1;
+ }
+
return crypt_ftr.crypt_type;
}