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
This commit is contained in:
parent
422bdb7e49
commit
6bfed20c77
2 changed files with 32 additions and 13 deletions
38
cryptfs.c
38
cryptfs.c
|
@ -1524,7 +1524,8 @@ static int do_crypto_complete(char *mount_point UNUSED)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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");
|
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,
|
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 */
|
* and give the user an option to wipe the disk */
|
||||||
|
@ -2412,6 +2413,15 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
|
||||||
&& (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS)) {
|
&& (crypt_ftr.flags & CRYPT_ENCRYPTION_IN_PROGRESS)) {
|
||||||
previously_encrypted_upto = crypt_ftr.encrypted_upto;
|
previously_encrypted_upto = crypt_ftr.encrypted_upto;
|
||||||
crypt_ftr.encrypted_upto = 0;
|
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, "");
|
property_get("ro.crypto.state", encrypted_state, "");
|
||||||
|
@ -2561,7 +2571,11 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
|
||||||
} else {
|
} else {
|
||||||
crypt_ftr.fs_size = nr_sec;
|
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;
|
crypt_ftr.crypt_type = crypt_type;
|
||||||
strcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256");
|
strcpy((char *)crypt_ftr.crypto_type_name, "aes-cbc-essiv:sha256");
|
||||||
|
|
||||||
|
@ -2629,18 +2643,15 @@ int cryptfs_enable_internal(char *howarg, int crypt_type, char *passwd,
|
||||||
|
|
||||||
if (! rc) {
|
if (! rc) {
|
||||||
/* Success */
|
/* 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) {
|
||||||
if (crypt_ftr.encrypted_upto == crypt_ftr.fs_size) {
|
|
||||||
crypt_ftr.flags &= ~CRYPT_ENCRYPTION_IN_PROGRESS;
|
|
||||||
} else {
|
|
||||||
SLOGD("Encrypted up to sector %lld - will continue after reboot",
|
SLOGD("Encrypted up to sector %lld - will continue after reboot",
|
||||||
crypt_ftr.encrypted_upto);
|
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 */
|
sleep(2); /* Give the UI a chance to show 100% progress */
|
||||||
/* Partially encrypted - ensure writes are flushed to ssd */
|
/* Partially encrypted - ensure writes are flushed to ssd */
|
||||||
|
@ -2924,9 +2935,10 @@ int cryptfs_mount_default_encrypted(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @TODO make sure we factory wipe in this situation
|
/** Corrupt. Allow us to boot into framework, which will detect bad
|
||||||
* In general if we got here there is no recovery
|
crypto when it calls do_crypto_complete, then do a factory reset
|
||||||
*/
|
*/
|
||||||
|
property_set("vold.decrypt", "trigger_restart_min_framework");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2941,6 +2953,10 @@ int cryptfs_get_password_type(void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (crypt_ftr.flags & CRYPT_INCONSISTENT_STATE) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return crypt_ftr.crypt_type;
|
return crypt_ftr.crypt_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,8 +44,11 @@
|
||||||
|
|
||||||
/* definitions of flags in the structure below */
|
/* definitions of flags in the structure below */
|
||||||
#define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */
|
#define CRYPT_MNT_KEY_UNENCRYPTED 0x1 /* The key for the partition is not encrypted. */
|
||||||
#define CRYPT_ENCRYPTION_IN_PROGRESS 0x2 /* Set when starting encryption,
|
#define CRYPT_ENCRYPTION_IN_PROGRESS 0x2 /* Encryption partially completed,
|
||||||
* clear when done before rebooting */
|
encrypted_upto valid*/
|
||||||
|
#define CRYPT_INCONSISTENT_STATE 0x4 /* Set when starting encryption, clear when
|
||||||
|
exit cleanly, either through success or
|
||||||
|
correctly marked partial encryption */
|
||||||
|
|
||||||
/* Allowed values for type in the structure below */
|
/* Allowed values for type in the structure below */
|
||||||
#define CRYPT_TYPE_PASSWORD 0 /* master_key is encrypted with a password
|
#define CRYPT_TYPE_PASSWORD 0 /* master_key is encrypted with a password
|
||||||
|
|
Loading…
Reference in a new issue