1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-10-27 01:55:32 +03:00

Merge pull request #20790 from poettering/boot-fixes

various EFI/boot fixes
This commit is contained in:
Lennart Poettering 2021-09-21 11:35:04 +02:00 committed by GitHub
commit f0c6333d4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 301 additions and 280 deletions

View File

@ -912,14 +912,11 @@ static VOID config_add_entry(Config *config, ConfigEntry *entry) {
assert(entry);
if ((config->entry_count & 15) == 0) {
UINTN i;
i = config->entry_count + 16;
if (config->entry_count == 0)
config->entries = AllocatePool(sizeof(VOID *) * i);
else
config->entries = ReallocatePool(config->entries,
sizeof(VOID *) * config->entry_count, sizeof(VOID *) * i);
UINTN i = config->entry_count + 16;
config->entries = ReallocatePool(
config->entries,
sizeof(VOID *) * config->entry_count,
sizeof(VOID *) * i);
}
config->entries[config->entry_count++] = entry;
}
@ -1492,7 +1489,7 @@ static VOID config_load_entries(
EFI_FILE *root_dir,
CHAR16 *loaded_image_path) {
EFI_FILE_HANDLE entries_dir;
_cleanup_(FileHandleClosep) EFI_FILE_HANDLE entries_dir = NULL;
EFI_STATUS err;
assert(config);
@ -1501,34 +1498,34 @@ static VOID config_load_entries(
assert(loaded_image_path);
err = uefi_call_wrapper(root_dir->Open, 5, root_dir, &entries_dir, (CHAR16*) L"\\loader\\entries", EFI_FILE_MODE_READ, 0ULL);
if (!EFI_ERROR(err)) {
for (;;) {
CHAR16 buf[256];
UINTN bufsize;
EFI_FILE_INFO *f;
_cleanup_freepool_ CHAR8 *content = NULL;
if (EFI_ERROR(err))
return;
bufsize = sizeof(buf);
err = uefi_call_wrapper(entries_dir->Read, 3, entries_dir, &bufsize, buf);
if (bufsize == 0 || EFI_ERROR(err))
break;
for (;;) {
CHAR16 buf[256];
UINTN bufsize;
EFI_FILE_INFO *f;
_cleanup_freepool_ CHAR8 *content = NULL;
f = (EFI_FILE_INFO *) buf;
if (f->FileName[0] == '.')
continue;
if (f->Attribute & EFI_FILE_DIRECTORY)
continue;
bufsize = sizeof(buf);
err = uefi_call_wrapper(entries_dir->Read, 3, entries_dir, &bufsize, buf);
if (bufsize == 0 || EFI_ERROR(err))
break;
if (!endswith_no_case(f->FileName, L".conf"))
continue;
if (startswith(f->FileName, L"auto-"))
continue;
f = (EFI_FILE_INFO *) buf;
if (f->FileName[0] == '.')
continue;
if (f->Attribute & EFI_FILE_DIRECTORY)
continue;
err = file_read(entries_dir, f->FileName, 0, 0, &content, NULL);
if (!EFI_ERROR(err))
config_entry_add_from_file(config, device, root_dir, L"\\loader\\entries", f->FileName, content, loaded_image_path);
}
uefi_call_wrapper(entries_dir->Close, 1, entries_dir);
if (!endswith_no_case(f->FileName, L".conf"))
continue;
if (startswith(f->FileName, L"auto-"))
continue;
err = file_read(entries_dir, f->FileName, 0, 0, &content, NULL);
if (!EFI_ERROR(err))
config_entry_add_from_file(config, device, root_dir, L"\\loader\\entries", f->FileName, content, loaded_image_path);
}
}
@ -1980,7 +1977,7 @@ static VOID config_entry_add_linux(
EFI_HANDLE *device,
EFI_FILE *root_dir) {
EFI_FILE_HANDLE linux_dir;
_cleanup_(FileHandleClosep) EFI_FILE_HANDLE linux_dir = NULL;
EFI_STATUS err;
ConfigEntry *entry;
@ -2110,8 +2107,6 @@ static VOID config_entry_add_linux(
FreePool(os_build_id);
FreePool(content);
}
uefi_call_wrapper(linux_dir->Close, 1, linux_dir);
}
#define XBOOTLDR_GUID \

View File

@ -7,260 +7,102 @@
#include "macro-fundamental.h"
#include "measure.h"
#include "missing_efi.h"
#include "util.h"
#define EFI_TCG_GUID \
&(const EFI_GUID) { 0xf541796d, 0xa62e, 0x4954, { 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } }
static EFI_STATUS tpm1_measure_to_pcr_and_event_log(
const EFI_TCG *tcg,
UINT32 pcrindex,
EFI_PHYSICAL_ADDRESS buffer,
UINTN buffer_size,
const CHAR16 *description) {
typedef struct _TCG_VERSION {
UINT8 Major;
UINT8 Minor;
UINT8 RevMajor;
UINT8 RevMinor;
} TCG_VERSION;
typedef struct tdEFI_TCG2_VERSION {
UINT8 Major;
UINT8 Minor;
} EFI_TCG2_VERSION;
typedef struct _TCG_BOOT_SERVICE_CAPABILITY {
UINT8 Size;
struct _TCG_VERSION StructureVersion;
struct _TCG_VERSION ProtocolSpecVersion;
UINT8 HashAlgorithmBitmap;
BOOLEAN TPMPresentFlag;
BOOLEAN TPMDeactivatedFlag;
} TCG_BOOT_SERVICE_CAPABILITY;
typedef struct tdTREE_BOOT_SERVICE_CAPABILITY {
UINT8 Size;
EFI_TCG2_VERSION StructureVersion;
EFI_TCG2_VERSION ProtocolVersion;
UINT32 HashAlgorithmBitmap;
UINT32 SupportedEventLogs;
BOOLEAN TrEEPresentFlag;
UINT16 MaxCommandSize;
UINT16 MaxResponseSize;
UINT32 ManufacturerID;
} TREE_BOOT_SERVICE_CAPABILITY;
typedef UINT32 TCG_ALGORITHM_ID;
#define TCG_ALG_SHA 0x00000004 // The SHA1 algorithm
#define SHA1_DIGEST_SIZE 20
typedef struct _TCG_DIGEST {
UINT8 Digest[SHA1_DIGEST_SIZE];
} TCG_DIGEST;
#define EV_IPL 13
typedef struct _TCG_PCR_EVENT {
UINT32 PCRIndex;
UINT32 EventType;
struct _TCG_DIGEST digest;
UINT32 EventSize;
UINT8 Event[1];
} TCG_PCR_EVENT;
INTERFACE_DECL(_EFI_TCG);
typedef EFI_STATUS(EFIAPI * EFI_TCG_STATUS_CHECK) (IN struct _EFI_TCG * This,
OUT struct _TCG_BOOT_SERVICE_CAPABILITY * ProtocolCapability,
OUT UINT32 * TCGFeatureFlags,
OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_ALL) (IN struct _EFI_TCG * This,
IN UINT8 * HashData,
IN UINT64 HashDataLen,
IN TCG_ALGORITHM_ID AlgorithmId,
IN OUT UINT64 * HashedDataLen, IN OUT UINT8 ** HashedDataResult);
typedef EFI_STATUS(EFIAPI * EFI_TCG_LOG_EVENT) (IN struct _EFI_TCG * This,
IN struct _TCG_PCR_EVENT * TCGLogData,
IN OUT UINT32 * EventNumber, IN UINT32 Flags);
typedef EFI_STATUS(EFIAPI * EFI_TCG_PASS_THROUGH_TO_TPM) (IN struct _EFI_TCG * This,
IN UINT32 TpmInputParameterBlockSize,
IN UINT8 * TpmInputParameterBlock,
IN UINT32 TpmOutputParameterBlockSize,
IN UINT8 * TpmOutputParameterBlock);
typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_LOG_EXTEND_EVENT) (IN struct _EFI_TCG * This,
IN EFI_PHYSICAL_ADDRESS HashData,
IN UINT64 HashDataLen,
IN TCG_ALGORITHM_ID AlgorithmId,
IN struct _TCG_PCR_EVENT * TCGLogData,
IN OUT UINT32 * EventNumber,
OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
typedef struct _EFI_TCG {
EFI_TCG_STATUS_CHECK StatusCheck;
EFI_TCG_HASH_ALL HashAll;
EFI_TCG_LOG_EVENT LogEvent;
EFI_TCG_PASS_THROUGH_TO_TPM PassThroughToTPM;
EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
} EFI_TCG;
#define EFI_TCG2_GUID \
&(const EFI_GUID) { 0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } }
typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL;
typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP;
typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT;
typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP;
typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
UINT8 Size;
EFI_TCG2_VERSION StructureVersion;
EFI_TCG2_VERSION ProtocolVersion;
EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
BOOLEAN TPMPresentFlag;
UINT16 MaxCommandSize;
UINT16 MaxResponseSize;
UINT32 ManufacturerID;
UINT32 NumberOfPCRBanks;
EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
} EFI_TCG2_BOOT_SERVICE_CAPABILITY;
#define EFI_TCG2_EVENT_HEADER_VERSION 1
typedef struct {
UINT32 HeaderSize;
UINT16 HeaderVersion;
UINT32 PCRIndex;
UINT32 EventType;
} _packed_ EFI_TCG2_EVENT_HEADER;
typedef struct tdEFI_TCG2_EVENT {
UINT32 Size;
EFI_TCG2_EVENT_HEADER Header;
UINT8 Event[1];
} _packed_ EFI_TCG2_EVENT;
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_CAPABILITY) (IN EFI_TCG2_PROTOCOL * This,
IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY * ProtocolCapability);
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_EVENT_LOG) (IN EFI_TCG2_PROTOCOL * This,
IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry,
OUT BOOLEAN * EventLogTruncated);
typedef EFI_STATUS(EFIAPI * EFI_TCG2_HASH_LOG_EXTEND_EVENT) (IN EFI_TCG2_PROTOCOL * This,
IN UINT64 Flags,
IN EFI_PHYSICAL_ADDRESS DataToHash,
IN UINT64 DataToHashLen, IN EFI_TCG2_EVENT * EfiTcgEvent);
typedef EFI_STATUS(EFIAPI * EFI_TCG2_SUBMIT_COMMAND) (IN EFI_TCG2_PROTOCOL * This,
IN UINT32 InputParameterBlockSize,
IN UINT8 * InputParameterBlock,
IN UINT32 OutputParameterBlockSize, IN UINT8 * OutputParameterBlock);
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, OUT UINT32 * ActivePcrBanks);
typedef EFI_STATUS(EFIAPI * EFI_TCG2_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, IN UINT32 ActivePcrBanks);
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This,
OUT UINT32 * OperationPresent, OUT UINT32 * Response);
typedef struct tdEFI_TCG2_PROTOCOL {
EFI_TCG2_GET_CAPABILITY GetCapability;
EFI_TCG2_GET_EVENT_LOG GetEventLog;
EFI_TCG2_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
EFI_TCG2_SUBMIT_COMMAND SubmitCommand;
EFI_TCG2_GET_ACTIVE_PCR_BANKS GetActivePcrBanks;
EFI_TCG2_SET_ACTIVE_PCR_BANKS SetActivePcrBanks;
EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS GetResultOfSetActivePcrBanks;
} EFI_TCG2;
static EFI_STATUS tpm1_measure_to_pcr_and_event_log(const EFI_TCG *tcg, UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer,
UINTN buffer_size, const CHAR16 *description) {
EFI_STATUS status;
TCG_PCR_EVENT *tcg_event;
UINT32 event_number;
_cleanup_freepool_ TCG_PCR_EVENT *tcg_event = NULL;
EFI_PHYSICAL_ADDRESS event_log_last;
UINT32 event_number = 1;
UINTN desc_len;
assert(tcg);
assert(description);
desc_len = StrSize(description);
tcg_event = AllocateZeroPool(desc_len + sizeof(TCG_PCR_EVENT));
tcg_event = AllocateZeroPool(OFFSETOF(TCG_PCR_EVENT, Event) + desc_len);
if (!tcg_event)
return EFI_OUT_OF_RESOURCES;
tcg_event->EventSize = desc_len;
CopyMem((VOID *) & tcg_event->Event[0], (VOID *) description, desc_len);
*tcg_event = (TCG_PCR_EVENT) {
.EventSize = desc_len,
.PCRIndex = pcrindex,
.EventType = EV_IPL,
};
CopyMem(tcg_event->Event, description, desc_len);
tcg_event->PCRIndex = pcrindex;
tcg_event->EventType = EV_IPL;
event_number = 1;
status = uefi_call_wrapper(tcg->HashLogExtendEvent, 7,
(EFI_TCG *) tcg, buffer, buffer_size, TCG_ALG_SHA, tcg_event, &event_number, &event_log_last);
if (EFI_ERROR(status))
return status;
uefi_call_wrapper(BS->FreePool, 1, tcg_event);
return EFI_SUCCESS;
return uefi_call_wrapper(
tcg->HashLogExtendEvent, 7,
(EFI_TCG *) tcg,
buffer, buffer_size,
TCG_ALG_SHA,
tcg_event,
&event_number,
&event_log_last);
}
static EFI_STATUS tpm2_measure_to_pcr_and_event_log(const EFI_TCG2 *tcg, UINT32 pcrindex, const EFI_PHYSICAL_ADDRESS buffer,
UINT64 buffer_size, const CHAR16 *description) {
EFI_STATUS status;
EFI_TCG2_EVENT *tcg_event;
static EFI_STATUS tpm2_measure_to_pcr_and_event_log(
EFI_TCG2 *tcg,
UINT32 pcrindex,
EFI_PHYSICAL_ADDRESS buffer,
UINT64 buffer_size,
const CHAR16 *description) {
_cleanup_freepool_ EFI_TCG2_EVENT *tcg_event = NULL;
UINTN desc_len;
assert(tcg);
assert(description);
desc_len = StrSize(description);
tcg_event = AllocateZeroPool(sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len);
tcg_event = AllocateZeroPool(OFFSETOF(EFI_TCG2_EVENT, Event) + desc_len);
if (!tcg_event)
return EFI_OUT_OF_RESOURCES;
tcg_event->Size = sizeof(*tcg_event) - sizeof(tcg_event->Event) + desc_len;
tcg_event->Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER);
tcg_event->Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION;
tcg_event->Header.PCRIndex = pcrindex;
tcg_event->Header.EventType = EV_IPL;
*tcg_event = (EFI_TCG2_EVENT) {
.Size = OFFSETOF(EFI_TCG2_EVENT, Event) + desc_len,
.Header.HeaderSize = sizeof(EFI_TCG2_EVENT_HEADER),
.Header.HeaderVersion = EFI_TCG2_EVENT_HEADER_VERSION,
.Header.PCRIndex = pcrindex,
.Header.EventType = EV_IPL,
};
CopyMem((VOID *) tcg_event->Event, (VOID *) description, desc_len);
CopyMem(tcg_event->Event, description, desc_len);
status = uefi_call_wrapper(tcg->HashLogExtendEvent, 5, (EFI_TCG2 *) tcg, 0, buffer, (UINT64) buffer_size, tcg_event);
uefi_call_wrapper(BS->FreePool, 1, tcg_event);
if (EFI_ERROR(status))
return status;
return EFI_SUCCESS;
return uefi_call_wrapper(
tcg->HashLogExtendEvent, 5,
tcg,
0,
buffer, buffer_size,
tcg_event);
}
static EFI_TCG * tcg1_interface_check(void) {
static EFI_TCG *tcg1_interface_check(void) {
EFI_PHYSICAL_ADDRESS event_log_location, event_log_last_entry;
TCG_BOOT_SERVICE_CAPABILITY capability = {
.Size = sizeof(capability),
};
EFI_STATUS status;
EFI_TCG *tcg;
TCG_BOOT_SERVICE_CAPABILITY capability;
UINT32 features;
EFI_PHYSICAL_ADDRESS event_log_location;
EFI_PHYSICAL_ADDRESS event_log_last_entry;
EFI_TCG *tcg;
status = LibLocateProtocol((EFI_GUID*) EFI_TCG_GUID, (void **) &tcg);
if (EFI_ERROR(status))
return NULL;
capability.Size = (UINT8) sizeof(capability);
status = uefi_call_wrapper(tcg->StatusCheck, 5, tcg, &capability, &features, &event_log_location, &event_log_last_entry);
status = uefi_call_wrapper(
tcg->StatusCheck, 5,
tcg,
&capability,
&features,
&event_log_location,
&event_log_last_entry);
if (EFI_ERROR(status))
return NULL;
@ -274,25 +116,24 @@ static EFI_TCG * tcg1_interface_check(void) {
}
static EFI_TCG2 * tcg2_interface_check(void) {
EFI_TCG2_BOOT_SERVICE_CAPABILITY capability = {
.Size = sizeof(capability),
};
EFI_STATUS status;
EFI_TCG2 *tcg;
EFI_TCG2_BOOT_SERVICE_CAPABILITY capability;
status = LibLocateProtocol((EFI_GUID*) EFI_TCG2_GUID, (void **) &tcg);
if (EFI_ERROR(status))
return NULL;
capability.Size = (UINT8) sizeof(EFI_TCG2_BOOT_SERVICE_CAPABILITY);
status = uefi_call_wrapper(tcg->GetCapability, 2, tcg, &capability);
if (EFI_ERROR(status))
return NULL;
if (capability.StructureVersion.Major == 1 &&
capability.StructureVersion.Minor == 0) {
TCG_BOOT_SERVICE_CAPABILITY *caps_1_0;
caps_1_0 = (TCG_BOOT_SERVICE_CAPABILITY *)&capability;
TCG_BOOT_SERVICE_CAPABILITY *caps_1_0 =
(TCG_BOOT_SERVICE_CAPABILITY*) &capability;
if (caps_1_0->TPMPresentFlag)
return tcg;
}

View File

@ -3,6 +3,8 @@
#include <efi.h>
#include "macro-fundamental.h"
#ifndef EFI_RNG_PROTOCOL_GUID
#define EFI_RNG_PROTOCOL_GUID \
@ -159,4 +161,173 @@ struct _EFI_DT_FIXUP_PROTOCOL {
EFI_DT_FIXUP Fixup;
};
#define EFI_TCG_GUID \
&(const EFI_GUID) { 0xf541796d, 0xa62e, 0x4954, { 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd } }
typedef struct _TCG_VERSION {
UINT8 Major;
UINT8 Minor;
UINT8 RevMajor;
UINT8 RevMinor;
} TCG_VERSION;
typedef struct tdEFI_TCG2_VERSION {
UINT8 Major;
UINT8 Minor;
} EFI_TCG2_VERSION;
typedef struct _TCG_BOOT_SERVICE_CAPABILITY {
UINT8 Size;
struct _TCG_VERSION StructureVersion;
struct _TCG_VERSION ProtocolSpecVersion;
UINT8 HashAlgorithmBitmap;
BOOLEAN TPMPresentFlag;
BOOLEAN TPMDeactivatedFlag;
} TCG_BOOT_SERVICE_CAPABILITY;
typedef struct tdTREE_BOOT_SERVICE_CAPABILITY {
UINT8 Size;
EFI_TCG2_VERSION StructureVersion;
EFI_TCG2_VERSION ProtocolVersion;
UINT32 HashAlgorithmBitmap;
UINT32 SupportedEventLogs;
BOOLEAN TrEEPresentFlag;
UINT16 MaxCommandSize;
UINT16 MaxResponseSize;
UINT32 ManufacturerID;
} TREE_BOOT_SERVICE_CAPABILITY;
typedef UINT32 TCG_ALGORITHM_ID;
#define TCG_ALG_SHA 0x00000004 // The SHA1 algorithm
#define SHA1_DIGEST_SIZE 20
typedef struct _TCG_DIGEST {
UINT8 Digest[SHA1_DIGEST_SIZE];
} TCG_DIGEST;
#define EV_IPL 13
typedef struct _TCG_PCR_EVENT {
UINT32 PCRIndex;
UINT32 EventType;
struct _TCG_DIGEST digest;
UINT32 EventSize;
UINT8 Event[1];
} TCG_PCR_EVENT;
INTERFACE_DECL(_EFI_TCG);
typedef EFI_STATUS(EFIAPI * EFI_TCG_STATUS_CHECK) (IN struct _EFI_TCG * This,
OUT struct _TCG_BOOT_SERVICE_CAPABILITY * ProtocolCapability,
OUT UINT32 * TCGFeatureFlags,
OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_ALL) (IN struct _EFI_TCG * This,
IN UINT8 * HashData,
IN UINT64 HashDataLen,
IN TCG_ALGORITHM_ID AlgorithmId,
IN OUT UINT64 * HashedDataLen, IN OUT UINT8 ** HashedDataResult);
typedef EFI_STATUS(EFIAPI * EFI_TCG_LOG_EVENT) (IN struct _EFI_TCG * This,
IN struct _TCG_PCR_EVENT * TCGLogData,
IN OUT UINT32 * EventNumber, IN UINT32 Flags);
typedef EFI_STATUS(EFIAPI * EFI_TCG_PASS_THROUGH_TO_TPM) (IN struct _EFI_TCG * This,
IN UINT32 TpmInputParameterBlockSize,
IN UINT8 * TpmInputParameterBlock,
IN UINT32 TpmOutputParameterBlockSize,
IN UINT8 * TpmOutputParameterBlock);
typedef EFI_STATUS(EFIAPI * EFI_TCG_HASH_LOG_EXTEND_EVENT) (IN struct _EFI_TCG * This,
IN EFI_PHYSICAL_ADDRESS HashData,
IN UINT64 HashDataLen,
IN TCG_ALGORITHM_ID AlgorithmId,
IN struct _TCG_PCR_EVENT * TCGLogData,
IN OUT UINT32 * EventNumber,
OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry);
typedef struct _EFI_TCG {
EFI_TCG_STATUS_CHECK StatusCheck;
EFI_TCG_HASH_ALL HashAll;
EFI_TCG_LOG_EVENT LogEvent;
EFI_TCG_PASS_THROUGH_TO_TPM PassThroughToTPM;
EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
} EFI_TCG;
#define EFI_TCG2_GUID \
&(const EFI_GUID) { 0x607f766c, 0x7455, 0x42be, { 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2, 0x72, 0x0f } }
typedef struct tdEFI_TCG2_PROTOCOL EFI_TCG2_PROTOCOL;
typedef UINT32 EFI_TCG2_EVENT_LOG_BITMAP;
typedef UINT32 EFI_TCG2_EVENT_LOG_FORMAT;
typedef UINT32 EFI_TCG2_EVENT_ALGORITHM_BITMAP;
typedef struct tdEFI_TCG2_BOOT_SERVICE_CAPABILITY {
UINT8 Size;
EFI_TCG2_VERSION StructureVersion;
EFI_TCG2_VERSION ProtocolVersion;
EFI_TCG2_EVENT_ALGORITHM_BITMAP HashAlgorithmBitmap;
EFI_TCG2_EVENT_LOG_BITMAP SupportedEventLogs;
BOOLEAN TPMPresentFlag;
UINT16 MaxCommandSize;
UINT16 MaxResponseSize;
UINT32 ManufacturerID;
UINT32 NumberOfPCRBanks;
EFI_TCG2_EVENT_ALGORITHM_BITMAP ActivePcrBanks;
} EFI_TCG2_BOOT_SERVICE_CAPABILITY;
#define EFI_TCG2_EVENT_HEADER_VERSION 1
typedef struct {
UINT32 HeaderSize;
UINT16 HeaderVersion;
UINT32 PCRIndex;
UINT32 EventType;
} _packed_ EFI_TCG2_EVENT_HEADER;
typedef struct tdEFI_TCG2_EVENT {
UINT32 Size;
EFI_TCG2_EVENT_HEADER Header;
UINT8 Event[1];
} _packed_ EFI_TCG2_EVENT;
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_CAPABILITY) (IN EFI_TCG2_PROTOCOL * This,
IN OUT EFI_TCG2_BOOT_SERVICE_CAPABILITY * ProtocolCapability);
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_EVENT_LOG) (IN EFI_TCG2_PROTOCOL * This,
IN EFI_TCG2_EVENT_LOG_FORMAT EventLogFormat,
OUT EFI_PHYSICAL_ADDRESS * EventLogLocation,
OUT EFI_PHYSICAL_ADDRESS * EventLogLastEntry,
OUT BOOLEAN * EventLogTruncated);
typedef EFI_STATUS(EFIAPI * EFI_TCG2_HASH_LOG_EXTEND_EVENT) (IN EFI_TCG2_PROTOCOL * This,
IN UINT64 Flags,
IN EFI_PHYSICAL_ADDRESS DataToHash,
IN UINT64 DataToHashLen, IN EFI_TCG2_EVENT * EfiTcgEvent);
typedef EFI_STATUS(EFIAPI * EFI_TCG2_SUBMIT_COMMAND) (IN EFI_TCG2_PROTOCOL * This,
IN UINT32 InputParameterBlockSize,
IN UINT8 * InputParameterBlock,
IN UINT32 OutputParameterBlockSize, IN UINT8 * OutputParameterBlock);
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, OUT UINT32 * ActivePcrBanks);
typedef EFI_STATUS(EFIAPI * EFI_TCG2_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This, IN UINT32 ActivePcrBanks);
typedef EFI_STATUS(EFIAPI * EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS) (IN EFI_TCG2_PROTOCOL * This,
OUT UINT32 * OperationPresent, OUT UINT32 * Response);
typedef struct tdEFI_TCG2_PROTOCOL {
EFI_TCG2_GET_CAPABILITY GetCapability;
EFI_TCG2_GET_EVENT_LOG GetEventLog;
EFI_TCG2_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
EFI_TCG2_SUBMIT_COMMAND SubmitCommand;
EFI_TCG2_GET_ACTIVE_PCR_BANKS GetActivePcrBanks;
EFI_TCG2_SET_ACTIVE_PCR_BANKS SetActivePcrBanks;
EFI_TCG2_GET_RESULT_OF_SET_ACTIVE_PCR_BANKS GetResultOfSetActivePcrBanks;
} EFI_TCG2;
#endif

View File

@ -17,17 +17,28 @@ static const char __attribute__((used)) magic[] = "#### LoaderInfo: systemd-stub
EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
EFI_LOADED_IMAGE *loaded_image;
const CHAR8 *sections[] = {
(CHAR8 *)".cmdline",
(CHAR8 *)".linux",
(CHAR8 *)".initrd",
(CHAR8 *)".splash",
NULL
enum {
SECTION_CMDLINE,
SECTION_LINUX,
SECTION_INITRD,
SECTION_SPLASH,
_SECTION_MAX,
};
UINTN addrs[ELEMENTSOF(sections)-1] = {};
UINTN szs[ELEMENTSOF(sections)-1] = {};
const CHAR8* const sections[] = {
[SECTION_CMDLINE] = (const CHAR8*) ".cmdline",
[SECTION_LINUX] = (const CHAR8*) ".linux",
[SECTION_INITRD] = (const CHAR8*) ".initrd",
[SECTION_SPLASH] = (const CHAR8*) ".splash",
NULL,
};
EFI_PHYSICAL_ADDRESS linux_base, initrd_base;
UINTN cmdline_len = 0, initrd_size;
UINTN addrs[_SECTION_MAX] = {};
UINTN szs[_SECTION_MAX] = {};
CHAR8 *cmdline = NULL;
UINTN cmdline_len;
CHAR16 uuid[37];
EFI_STATUS err;
@ -38,14 +49,14 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
if (EFI_ERROR(err))
return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, szs);
err = pe_memory_locate_sections(loaded_image->ImageBase, (const CHAR8**) sections, addrs, szs);
if (EFI_ERROR(err))
return log_error_status_stall(err, L"Unable to locate embedded .linux section: %r", err);
if (szs[0] > 0)
cmdline = (CHAR8 *)(loaded_image->ImageBase) + addrs[0];
cmdline_len = szs[0];
if (szs[SECTION_CMDLINE] > 0) {
cmdline = (CHAR8*) loaded_image->ImageBase + addrs[SECTION_CMDLINE];
cmdline_len = szs[SECTION_CMDLINE];
}
/* if we are not in secure boot mode, or none was provided, accept a custom command line and replace the built-in one */
if ((!secure_boot_enabled() || cmdline_len == 0) && loaded_image->LoadOptionsSize > 0 &&
@ -109,12 +120,15 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
if (efivar_get_raw(LOADER_GUID, L"StubInfo", NULL, NULL) != EFI_SUCCESS)
efivar_set(LOADER_GUID, L"StubInfo", L"systemd-stub " GIT_VERSION, 0);
if (szs[3] > 0)
graphics_splash((UINT8 *)((UINTN)loaded_image->ImageBase + addrs[3]), szs[3], NULL);
if (szs[SECTION_SPLASH] > 0)
graphics_splash((UINT8*) (UINTN) loaded_image->ImageBase + addrs[SECTION_SPLASH], szs[SECTION_SPLASH], NULL);
err = linux_exec(image, cmdline, cmdline_len,
(UINTN)loaded_image->ImageBase + addrs[1],
(UINTN)loaded_image->ImageBase + addrs[2], szs[2]);
linux_base = (EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->ImageBase + addrs[SECTION_LINUX];
initrd_size = szs[SECTION_INITRD];
initrd_base = initrd_size != 0 ? (EFI_PHYSICAL_ADDRESS) (UINTN) loaded_image->ImageBase + addrs[SECTION_INITRD] : 0;
err = linux_exec(image, cmdline, cmdline_len, linux_base, initrd_base, initrd_size);
graphics_mode(FALSE);
return log_error_status_stall(err, L"Execution of embedded linux image failed: %r", err);