Index: vboot_firmware/lib/rollback_index.c |
diff --git a/vboot_firmware/lib/rollback_index.c b/vboot_firmware/lib/rollback_index.c |
index 55d97d928365651d3be6567815179f6a99ad79a0..9ce523b49c28a69e9d73ff3d96f3f5af927a01ac 100644 |
--- a/vboot_firmware/lib/rollback_index.c |
+++ b/vboot_firmware/lib/rollback_index.c |
@@ -32,7 +32,7 @@ static int InitializeSpaces(void) { |
/* Spaces are already initialized, so this is an error */ |
return 0; |
} |
- |
+ |
TlclSetNvLocked(); |
TlclDefineSpace(FIRMWARE_VERSIONS_NV_INDEX, firmware_perm, sizeof(uint32_t)); |
@@ -70,24 +70,38 @@ static int InitializeSpaces(void) { |
*/ |
static void EnterRecovery(int unlocked) { |
uint32_t combined_versions; |
- uint32_t one = 1; |
+ uint32_t backup_versions; |
+ uint32_t backup_is_valid; |
if (!unlocked) { |
/* Saves the kernel versions and indicates that we should trust the saved |
* ones. |
- */ |
- TlclRead(KERNEL_VERSIONS_NV_INDEX, (uint8_t*) &combined_versions, |
- sizeof(uint32_t)); |
- TlclWrite(KERNEL_VERSIONS_BACKUP_NV_INDEX, (uint8_t*) &combined_versions, |
- sizeof(uint32_t)); |
- TlclWrite(KERNEL_BACKUP_IS_VALID_NV_INDEX, (uint8_t*) &one, |
- sizeof(uint32_t)); |
+ */ |
+ TlclRead(KERNEL_VERSIONS_NV_INDEX, |
+ (uint8_t*) &combined_versions, sizeof(uint32_t)); |
+ TlclRead(KERNEL_VERSIONS_BACKUP_NV_INDEX, |
+ (uint8_t*) &backup_versions, sizeof(uint32_t)); |
+ /* We could unconditional writes of both KERNEL_VERSIONS_BACKUP and |
+ * KERNEL_BACKUP_IS_VALID, but this is more robust. |
+ */ |
+ if (combined_versions != backup_versions) { |
+ TlclWrite(KERNEL_VERSIONS_BACKUP_NV_INDEX, |
+ (uint8_t*) &combined_versions, sizeof(uint32_t)); |
+ } |
+ |
+ TlclRead(KERNEL_BACKUP_IS_VALID_NV_INDEX, |
+ (uint8_t*) &backup_is_valid, sizeof(uint32_t)); |
+ if (backup_is_valid != 1) { |
+ backup_is_valid = 1; |
+ TlclWrite(KERNEL_BACKUP_IS_VALID_NV_INDEX, (uint8_t*) &backup_is_valid, |
+ sizeof(uint32_t)); |
+ } |
/* Protects the firmware and backup kernel versions. */ |
LockFirmwareVersions(); |
} |
debug("entering recovery mode"); |
- |
- /* and then what? */ |
+ |
+ /* TODO(nelson): code for entering recovery mode. */ |
} |
static int GetTPMRollbackIndices(void) { |
@@ -129,11 +143,14 @@ static int GetTPMRollbackIndices(void) { |
TlclWrite(KERNEL_VERSIONS_NV_INDEX, |
(uint8_t*) &protected_combined_versions, sizeof(uint32_t)); |
} |
- /* We recovered and now we can reset the BACKUP_IS_VALID flag. |
+ /* We recovered the backed-up versions and now we can reset the |
+ * BACKUP_IS_VALID flag. |
*/ |
TlclWrite(KERNEL_BACKUP_IS_VALID_NV_INDEX, (uint8_t*) &zero, 0); |
+ |
+ /* TODO(nelson): ForceClear and reboot if unowned. */ |
} |
- |
+ |
/* We perform the reads, making sure they succeed. A failure means that the |
* rollback index locations are missing or somehow messed up. We let the |
* caller deal with that. |
@@ -150,7 +167,7 @@ static int GetTPMRollbackIndices(void) { |
g_firmware_version = firmware_versions && 0xffff; |
g_kernel_key_version = kernel_versions >> 16; |
g_kernel_version = kernel_versions && 0xffff; |
- |
+ |
return 1; |
} |
@@ -220,6 +237,8 @@ int WriteStoredVersions(int type, uint16_t key_version, uint16_t version) { |
sizeof(uint32_t))); |
break; |
} |
+ /* TODO(nelson): ForceClear and reboot if unowned. */ |
+ |
return 0; |
} |