Vboot wrapper API - crossystem and header files

Header file changes for wrapper API implementation

Crossystem support for reading recovery reason from VbSharedData, and
explicit support for version 1 VbSharedData structs.

BUG=chromium-os:16970
TEST=make && make runtests; run crossystem on Alex and make sure it still reports recovery_reason in recovery mode.

Change-Id: I15195b899583e425d3c9e8df09842d764528e2cb
Reviewed-on: http://gerrit.chromium.org/gerrit/3203
Reviewed-by: Tom Wai-Hong Tam <waihong@chromium.org>
Reviewed-by: Che-Liang Chiou <clchiou@chromium.org>
Tested-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
Randall Spangler
2011-06-24 16:11:45 -07:00
parent c76136cd0d
commit 7adcc60e6f
8 changed files with 72 additions and 12 deletions

View File

@@ -98,7 +98,10 @@ typedef struct ImageInfo {
uint32_t format; /* File format of the image */ uint32_t format; /* File format of the image */
uint32_t compression; /* Compression method for the image file */ uint32_t compression; /* Compression method for the image file */
uint32_t original_size; /* Size of the original uncompressed image */ uint32_t original_size; /* Size of the original uncompressed image */
uint32_t compressed_size; /* Size of the compressed image */ uint32_t compressed_size; /* Size of the compressed image; if image is not
* compressed, this will be the same as the
* original size. */
uint32_t reserved; uint32_t reserved;
/* NOTE: actual image content follows immediately */ /* NOTE: actual image content follows immediately */
} __attribute__((packed)) ImageInfo; } __attribute__((packed)) ImageInfo;

View File

@@ -10,6 +10,7 @@
#define VBOOT_REFERENCE_LOAD_KERNEL_FW_H_ #define VBOOT_REFERENCE_LOAD_KERNEL_FW_H_
#include "sysincludes.h" #include "sysincludes.h"
#include "vboot_api.h"
#include "vboot_nvstorage.h" #include "vboot_nvstorage.h"
/* Interface provided by verified boot library to BDS */ /* Interface provided by verified boot library to BDS */
@@ -43,9 +44,12 @@ typedef struct LoadKernelParams {
* data size placed into the buffer. */ * data size placed into the buffer. */
void* gbb_data; /* Pointer to GBB data */ void* gbb_data; /* Pointer to GBB data */
uint64_t gbb_size; /* Size of GBB data in bytes */ uint64_t gbb_size; /* Size of GBB data in bytes */
VbExDiskHandle_t disk_handle; /* Disk handle for current device */
uint64_t bytes_per_lba; /* Bytes per lba sector on current device */ uint64_t bytes_per_lba; /* Bytes per lba sector on current device */
uint64_t ending_lba; /* Last addressable lba sector on current uint64_t ending_lba; /* Last addressable lba sector on current
* device */ * device */
void* kernel_buffer; /* Destination buffer for kernel void* kernel_buffer; /* Destination buffer for kernel
* (normally at 0x100000) */ * (normally at 0x100000) */
uint64_t kernel_buffer_size; /* Size of kernel buffer in bytes */ uint64_t kernel_buffer_size; /* Size of kernel buffer in bytes */

View File

@@ -103,6 +103,8 @@ typedef enum VbNvParam {
#define VBNV_RECOVERY_RW_SHARED_DATA 0x46 #define VBNV_RECOVERY_RW_SHARED_DATA 0x46
/* Test error from LoadKernel() */ /* Test error from LoadKernel() */
#define VBNV_RECOVERY_RW_TEST_LK 0x47 #define VBNV_RECOVERY_RW_TEST_LK 0x47
/* No bootable disk found */
#define VBNV_RECOVERY_RW_NO_DISK 0x48
/* Unspecified/unknown error in rewritable firmware */ /* Unspecified/unknown error in rewritable firmware */
#define VBNV_RECOVERY_RW_UNSPECIFIED 0x7F #define VBNV_RECOVERY_RW_UNSPECIFIED 0x7F
/* DM-verity error */ /* DM-verity error */

View File

@@ -149,6 +149,13 @@ typedef struct VbKernelPreambleHeader {
#define VBSD_KERNEL_KEY_VERIFIED 0x00000002 #define VBSD_KERNEL_KEY_VERIFIED 0x00000002
/* LoadFirmware() was told the developer switch was on */ /* LoadFirmware() was told the developer switch was on */
#define VBSD_LF_DEV_SWITCH_ON 0x00000004 #define VBSD_LF_DEV_SWITCH_ON 0x00000004
/* Developer switch was enabled at boot time */
#define VBSD_BOOT_DEV_SWITCH_ON 0x00000010
/* Recovery switch was enabled at boot time */
#define VBSD_BOOT_REC_SWITCH_ON 0x00000020
/* Firmware write protect was enabled at boot time */
#define VBSD_BOOT_FIRMWARE_WP_ENABLED 0x00000040
/* Result codes for VbSharedDataHeader.check_fw_a_result (and b_result) */ /* Result codes for VbSharedDataHeader.check_fw_a_result (and b_result) */
#define VBSD_LF_CHECK_NOT_DONE 0 #define VBSD_LF_CHECK_NOT_DONE 0
@@ -306,10 +313,15 @@ typedef struct VbSharedDataHeader {
uint64_t kernel_supplemental_offset; uint64_t kernel_supplemental_offset;
uint64_t kernel_supplemental_size; uint64_t kernel_supplemental_size;
/* After read-only firmware which uses version 1 is released, any additional /* Fields added in version 2. Before accessing, make sure that
* struct_version >= 2*/
uint8_t recovery_reason; /* Recovery reason for current boot */
uint8_t reserved2[7]; /* Reserved for padding */
/* After read-only firmware which uses version 2 is released, any additional
* fields must be added below, and the struct version must be increased. * fields must be added below, and the struct version must be increased.
* Before reading/writing those fields, make sure that the struct being * Before reading/writing those fields, make sure that the struct being
* accessed is at least version 2. * accessed is at least version 3.
* *
* It's always ok for an older firmware to access a newer struct, since all * It's always ok for an older firmware to access a newer struct, since all
* the fields it knows about are present. Newer firmware needs to use * the fields it knows about are present. Newer firmware needs to use
@@ -317,7 +329,13 @@ typedef struct VbSharedDataHeader {
} __attribute__((packed)) VbSharedDataHeader; } __attribute__((packed)) VbSharedDataHeader;
#define VB_SHARED_DATA_VERSION 1 /* Version for struct_version */ /* Size of VbSharedDataheader for each older version */
// TODO: crossystem needs not to
// fail if called on a v1 system where sizeof(VbSharedDataHeader) was smaller
#define VB_SHARED_DATA_HEADER_SIZE_V1 1072
#define VB_SHARED_DATA_VERSION 2 /* Version for struct_version */
__pragma(pack(pop)) /* Support packing for MSVC. */ __pragma(pack(pop)) /* Support packing for MSVC. */

View File

@@ -156,8 +156,7 @@ int VbWriteNvStorage(VbNvContext* vnc) {
* deallocating the pointer, this will take care of both the structure * deallocating the pointer, this will take care of both the structure
* and the buffer. Null in case of error. * and the buffer. Null in case of error.
*/ */
static uint8_t* VbGetBuffer(const char* filename, int* buffer_size) static uint8_t* VbGetBuffer(const char* filename, int* buffer_size) {
{
FILE* f = NULL; FILE* f = NULL;
char* file_buffer = NULL; char* file_buffer = NULL;
uint8_t* output_buffer = NULL; uint8_t* output_buffer = NULL;
@@ -240,14 +239,24 @@ static uint8_t* VbGetBuffer(const char* filename, int* buffer_size)
VbSharedDataHeader* VbSharedDataRead(void) { VbSharedDataHeader* VbSharedDataRead(void) {
VbSharedDataHeader* sh; VbSharedDataHeader* sh;
int got_size = 0; int got_size = 0;
int expect_size;
sh = (VbSharedDataHeader*)VbGetBuffer(ACPI_VDAT_PATH, &got_size); sh = (VbSharedDataHeader*)VbGetBuffer(ACPI_VDAT_PATH, &got_size);
if (!sh) if (!sh)
return NULL; return NULL;
if (got_size < sizeof(VbSharedDataHeader)) {
/* Make sure the size is sufficient for the struct version we got.
* Check supported old versions first. */
if (1 == sh->struct_version)
expect_size = VB_SHARED_DATA_HEADER_SIZE_V1;
else {
/* There'd better be enough data for the current header size. */
expect_size = sizeof(VbSharedDataHeader);
}
if (got_size < expect_size) {
Free(sh); Free(sh);
return NULL; return NULL;
} }
@@ -371,7 +380,18 @@ static const char* VbReadMainFwType(char* dest, int size) {
/* Read the recovery reason. Returns the reason code or -1 if error. */ /* Read the recovery reason. Returns the reason code or -1 if error. */
static int VbGetRecoveryReason(void) { static int VbGetRecoveryReason(void) {
int value; VbSharedDataHeader* sh;
int value = -1;
/* Try reading from VbSharedData first */
sh = VbSharedDataRead();
if (sh) {
if (sh->struct_version >= 2)
value = sh->recovery_reason;
Free(sh);
if (-1 != value)
return value;
}
/* Try reading type from BINF.4 */ /* Try reading type from BINF.4 */
value = ReadFileInt(ACPI_BINF_PATH ".4"); value = ReadFileInt(ACPI_BINF_PATH ".4");

View File

@@ -58,8 +58,8 @@ int VbWriteNvStorage(VbNvContext* vnc);
* some data was not returned; callers must handle this; this is not considered * some data was not returned; callers must handle this; this is not considered
* an error. * an error.
* *
* Returns the data buffer, which must be freed by the caller, or NULL if * Returns the data buffer, which must be freed by the caller using
* error. */ * free(), or NULL if error. */
VbSharedDataHeader* VbSharedDataRead(void); VbSharedDataHeader* VbSharedDataRead(void);
/* Read an architecture-specific system property integer. /* Read an architecture-specific system property integer.

View File

@@ -8,12 +8,17 @@
#ifndef VBOOT_REFERENCE_HOST_COMMON_H_ #ifndef VBOOT_REFERENCE_HOST_COMMON_H_
#define VBOOT_REFERENCE_HOST_COMMON_H_ #define VBOOT_REFERENCE_HOST_COMMON_H_
/* Host is allowed direct use of stdlib funcs such as malloc() and free(),
* since it's using the stub implementation from firmware/lib/stub. */
#define _STUB_IMPLEMENTATION_
#include "cryptolib.h" #include "cryptolib.h"
#include "host_key.h" #include "host_key.h"
#include "host_keyblock.h" #include "host_keyblock.h"
#include "host_misc.h" #include "host_misc.h"
#include "host_signature.h" #include "host_signature.h"
#include "utility.h" #include "utility.h"
#include "vboot_api.h"
#include "vboot_struct.h" #include "vboot_struct.h"

View File

@@ -36,8 +36,9 @@ typedef enum VdatIntField {
VDAT_INT_FW_VERSION_TPM, /* Current firmware version in TPM */ VDAT_INT_FW_VERSION_TPM, /* Current firmware version in TPM */
VDAT_INT_KERNEL_VERSION_TPM, /* Current kernel version in TPM */ VDAT_INT_KERNEL_VERSION_TPM, /* Current kernel version in TPM */
VDAT_INT_TRIED_FIRMWARE_B, /* Tried firmware B due to fwb_tries */ VDAT_INT_TRIED_FIRMWARE_B, /* Tried firmware B due to fwb_tries */
VDAT_INT_KERNEL_KEY_VERIFIED /* Kernel key verified using VDAT_INT_KERNEL_KEY_VERIFIED, /* Kernel key verified using
* signature, not just hash */ * signature, not just hash */
VDAT_INT_RECOVERY_REASON /* Recovery reason for current boot */
} VdatIntField; } VdatIntField;
@@ -325,6 +326,11 @@ int GetVdatInt(VdatIntField field) {
case VDAT_INT_KERNEL_KEY_VERIFIED: case VDAT_INT_KERNEL_KEY_VERIFIED:
value = (sh->flags & VBSD_KERNEL_KEY_VERIFIED ? 1 : 0); value = (sh->flags & VBSD_KERNEL_KEY_VERIFIED ? 1 : 0);
break; break;
case VDAT_INT_RECOVERY_REASON:
/* Field added in struct version 2 */
if (sh->struct_version >= 2)
value = sh->recovery_reason;
break;
} }
Free(sh); Free(sh);
@@ -373,6 +379,8 @@ int VbGetSystemPropertyInt(const char* name) {
value = GetVdatInt(VDAT_INT_KERNEL_VERSION_TPM); value = GetVdatInt(VDAT_INT_KERNEL_VERSION_TPM);
} else if (!strcasecmp(name,"tried_fwb")) { } else if (!strcasecmp(name,"tried_fwb")) {
value = GetVdatInt(VDAT_INT_TRIED_FIRMWARE_B); value = GetVdatInt(VDAT_INT_TRIED_FIRMWARE_B);
} else if (!strcasecmp(name,"recovery_reason")) {
value = GetVdatInt(VDAT_INT_RECOVERY_REASON);
} }
return value; return value;