diff --git a/firmware/lib/include/rollback_index.h b/firmware/lib/include/rollback_index.h index d3a49ba609..f8f78a185f 100644 --- a/firmware/lib/include/rollback_index.h +++ b/firmware/lib/include/rollback_index.h @@ -48,7 +48,6 @@ typedef struct RollbackSpaceFirmware { uint8_t flags; /* Flags (see FLAG_* above) */ uint32_t fw_versions; /* Firmware versions */ uint32_t reserved; /* Reserved for future expansion */ - RollbackSpaceKernel kernel_backup; /* Backup of kernel space */ } __attribute__((packed)) RollbackSpaceFirmware; __pragma(pack(pop)) /* Support packing for MSVC. */ diff --git a/firmware/lib/rollback_index.c b/firmware/lib/rollback_index.c index f368355fbe..7467bedc2f 100644 --- a/firmware/lib/rollback_index.c +++ b/firmware/lib/rollback_index.c @@ -77,16 +77,16 @@ static uint32_t WriteSpaceFirmware(const RollbackSpaceFirmware* rsf) { return SafeWrite(FIRMWARE_NV_INDEX, rsf, sizeof(RollbackSpaceFirmware)); } +#ifndef DISABLE_ROLLBACK_TPM static uint32_t ReadSpaceKernel(RollbackSpaceKernel* rsk) { return TlclRead(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel)); } +#endif static uint32_t WriteSpaceKernel(const RollbackSpaceKernel* rsk) { return SafeWrite(KERNEL_NV_INDEX, rsk, sizeof(RollbackSpaceKernel)); } - - /* Creates the NVRAM spaces, and sets their initial values as needed. */ static uint32_t InitializeSpaces(RollbackSpaceFirmware* rsf, RollbackSpaceKernel* rsk) { @@ -110,9 +110,6 @@ static uint32_t InitializeSpaces(RollbackSpaceFirmware* rsf, /* Initialize the firmware and kernel spaces */ Memcpy(rsf, &rsf_init, sizeof(RollbackSpaceFirmware)); - /* Initialize the backup copy of the kernel space to the same data - * as the kernel space */ - Memcpy(&rsf->kernel_backup, &rsk_init, sizeof(RollbackSpaceKernel)); Memcpy(rsk, &rsk_init, sizeof(RollbackSpaceKernel)); /* Define and set firmware and kernel spaces */ @@ -149,14 +146,11 @@ static uint32_t InitializeSpaces(RollbackSpaceFirmware* rsf, uint32_t SetupTPM(int recovery_mode, int developer_mode, RollbackSpaceFirmware* rsf) { - RollbackSpaceKernel rsk; int rsf_dirty = 0; uint8_t new_flags = 0; - uint8_t disable; uint8_t deactivated; uint32_t result; - uint32_t perms; VBDEBUG(("TPM: SetupTPM(r%d, d%d)\n", recovery_mode, developer_mode)); @@ -188,6 +182,8 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode, /* Read the firmware space. */ result = ReadSpaceFirmware(rsf); if (TPM_E_BADINDEX == result) { + RollbackSpaceKernel rsk; + /* This is the first time we've run, and the TPM has not been * initialized. Initialize it. */ VBDEBUG(("TPM: Not initialized yet.\n")); @@ -199,40 +195,6 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode, VBDEBUG(("TPM: Firmware space sv%d f%x v%x\n", rsf->struct_version, rsf->flags, rsf->fw_versions)); - /* Read the kernel space and verify its permissions. If the kernel - * space has the wrong permission, or it doesn't contain the right - * identifier, we give up. This will need to be fixed by the - * recovery kernel. We have to worry about this because at any time - * (even with PP turned off) the TPM owner can remove and redefine a - * PP-protected space (but not write to it). */ - RETURN_ON_FAILURE(ReadSpaceKernel(&rsk)); - RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms)); - if (TPM_NV_PER_PPWRITE != perms || ROLLBACK_SPACE_KERNEL_UID != rsk.uid) - return TPM_E_CORRUPTED_STATE; - VBDEBUG(("TPM: Kernel space sv%d v%x\n", - rsk.struct_version, rsk.kernel_versions)); - - /* If the kernel space and its backup are different, we need to copy - * one to the other. Which one we copy depends on whether the - * use-backup flag is set. */ - if (0 != Memcmp(&rsk, &rsf->kernel_backup, sizeof(RollbackSpaceKernel))) { - VBDEBUG(("TPM: kernel space and backup are different\n")); - - if (rsf->flags & FLAG_KERNEL_SPACE_USE_BACKUP) { - VBDEBUG(("TPM: use backup kernel space\n")); - Memcpy(&rsk, &rsf->kernel_backup, sizeof(RollbackSpaceKernel)); - RETURN_ON_FAILURE(WriteSpaceKernel(&rsk)); - } else if (rsk.kernel_versions < rsf->kernel_backup.kernel_versions) { - VBDEBUG(("TPM: kernel versions %x < backup versions %x\n", - rsk.kernel_versions, rsf->kernel_backup.kernel_versions)); - return TPM_E_INTERNAL_INCONSISTENCY; - } else { - VBDEBUG(("TPM: copy kernel space to backup\n")); - Memcpy(&rsf->kernel_backup, &rsk, sizeof(RollbackSpaceKernel)); - rsf_dirty = 1; - } - } - /* Clear ownership if developer flag has toggled */ if ((developer_mode ? FLAG_LAST_BOOT_DEVELOPER : 0) != (rsf->flags & FLAG_LAST_BOOT_DEVELOPER)) { @@ -243,11 +205,10 @@ uint32_t SetupTPM(int recovery_mode, int developer_mode, /* Update flags */ if (developer_mode) new_flags |= FLAG_LAST_BOOT_DEVELOPER; - if (recovery_mode) { - new_flags |= FLAG_KERNEL_SPACE_USE_BACKUP; + if (recovery_mode) g_rollback_recovery_mode = 1; /* Global variables are usable in * recovery mode */ - } + if (rsf->flags != new_flags) { rsf->flags = new_flags; rsf_dirty = 1; @@ -323,7 +284,7 @@ uint32_t RollbackFirmwareSetup(int developer_mode, uint32_t* version) { RETURN_ON_FAILURE(SetupTPM(0, developer_mode, &rsf)); *version = rsf.fw_versions; - VBDEBUG(("TPM: RollbackFirmwareSetup %x %x %x\n", (int)rsf.fw_versions)); + VBDEBUG(("TPM: RollbackFirmwareSetup %x\n", (int)rsf.fw_versions)); return TPM_SUCCESS; } @@ -361,7 +322,19 @@ uint32_t RollbackKernelRead(uint32_t* version) { *version = 0; } else { RollbackSpaceKernel rsk; + uint32_t perms; + + /* Read the kernel space and verify its permissions. If the kernel + * space has the wrong permission, or it doesn't contain the right + * identifier, we give up. This will need to be fixed by the + * recovery kernel. We have to worry about this because at any time + * (even with PP turned off) the TPM owner can remove and redefine a + * PP-protected space (but not write to it). */ RETURN_ON_FAILURE(ReadSpaceKernel(&rsk)); + RETURN_ON_FAILURE(TlclGetPermissions(KERNEL_NV_INDEX, &perms)); + if (TPM_NV_PER_PPWRITE != perms || ROLLBACK_SPACE_KERNEL_UID != rsk.uid) + return TPM_E_CORRUPTED_STATE; + *version = rsk.kernel_versions; VBDEBUG(("TPM: RollbackKernelRead %x\n", (int)rsk.kernel_versions)); } diff --git a/firmware/version.c b/firmware/version.c index a9f7669559..1ef2ebcdc5 100644 --- a/firmware/version.c +++ b/firmware/version.c @@ -1 +1 @@ -char* VbootVersion = "VBOOv=16e190d8"; +char* VbootVersion = "VBOOv=fc839c15";