Merge pull request #23842 from medhefgo/boot-std
boot: Use standard types
This commit is contained in:
+68
-84
@@ -10,12 +10,6 @@
|
||||
# include "efi-string.h"
|
||||
# include "string-util-fundamental.h"
|
||||
|
||||
# define CHAR8 char
|
||||
# define CHAR16 char16_t
|
||||
# define UINT8 uint8_t
|
||||
# define UINT16 uint16_t
|
||||
# define UINT32 uint32_t
|
||||
# define UINT64 uint64_t
|
||||
# define UINTN size_t
|
||||
# define TEST_STATIC static
|
||||
#endif
|
||||
@@ -36,16 +30,16 @@ enum {
|
||||
* been squashed into _padN for our convenience. */
|
||||
|
||||
typedef struct {
|
||||
UINT32 sig;
|
||||
UINT32 primary_seqnum;
|
||||
UINT32 secondary_seqnum;
|
||||
UINT64 _pad1;
|
||||
UINT32 version_major;
|
||||
UINT32 version_minor;
|
||||
UINT32 type;
|
||||
UINT32 _pad2;
|
||||
UINT32 root_cell_offset;
|
||||
UINT64 _pad3[507];
|
||||
uint32_t sig;
|
||||
uint32_t primary_seqnum;
|
||||
uint32_t secondary_seqnum;
|
||||
uint64_t _pad1;
|
||||
uint32_t version_major;
|
||||
uint32_t version_minor;
|
||||
uint32_t type;
|
||||
uint32_t _pad2;
|
||||
uint32_t root_cell_offset;
|
||||
uint64_t _pad3[507];
|
||||
} _packed_ BaseBlock;
|
||||
assert_cc(sizeof(BaseBlock) == 4096);
|
||||
assert_cc(offsetof(BaseBlock, sig) == 0);
|
||||
@@ -58,20 +52,20 @@ assert_cc(offsetof(BaseBlock, root_cell_offset) == 36);
|
||||
|
||||
/* All offsets are relative to the base block and technically point to a hive
|
||||
* cell struct. But for our usecase we don't need to bother about that one,
|
||||
* so skip over the cell_size UINT32. */
|
||||
* so skip over the cell_size uint32_t. */
|
||||
#define HIVE_CELL_OFFSET (sizeof(BaseBlock) + 4)
|
||||
|
||||
typedef struct {
|
||||
UINT16 sig;
|
||||
UINT16 _pad1[13];
|
||||
UINT32 subkeys_offset;
|
||||
UINT32 _pad2;
|
||||
UINT32 n_key_values;
|
||||
UINT32 key_values_offset;
|
||||
UINT32 _pad3[7];
|
||||
UINT16 key_name_len;
|
||||
UINT16 _pad4;
|
||||
CHAR8 key_name[];
|
||||
uint16_t sig;
|
||||
uint16_t _pad1[13];
|
||||
uint32_t subkeys_offset;
|
||||
uint32_t _pad2;
|
||||
uint32_t n_key_values;
|
||||
uint32_t key_values_offset;
|
||||
uint32_t _pad3[7];
|
||||
uint16_t key_name_len;
|
||||
uint16_t _pad4;
|
||||
char key_name[];
|
||||
} _packed_ Key;
|
||||
assert_cc(offsetof(Key, sig) == 0);
|
||||
assert_cc(offsetof(Key, subkeys_offset) == 28);
|
||||
@@ -81,11 +75,11 @@ assert_cc(offsetof(Key, key_name_len) == 72);
|
||||
assert_cc(offsetof(Key, key_name) == 76);
|
||||
|
||||
typedef struct {
|
||||
UINT16 sig;
|
||||
UINT16 n_entries;
|
||||
uint16_t sig;
|
||||
uint16_t n_entries;
|
||||
struct SubkeyFastEntry {
|
||||
UINT32 key_offset;
|
||||
CHAR8 name_hint[4];
|
||||
uint32_t key_offset;
|
||||
char name_hint[4];
|
||||
} _packed_ entries[];
|
||||
} _packed_ SubkeyFast;
|
||||
assert_cc(offsetof(SubkeyFast, sig) == 0);
|
||||
@@ -93,13 +87,13 @@ assert_cc(offsetof(SubkeyFast, n_entries) == 2);
|
||||
assert_cc(offsetof(SubkeyFast, entries) == 4);
|
||||
|
||||
typedef struct {
|
||||
UINT16 sig;
|
||||
UINT16 name_len;
|
||||
UINT32 data_size;
|
||||
UINT32 data_offset;
|
||||
UINT32 data_type;
|
||||
UINT32 _pad;
|
||||
CHAR8 name[];
|
||||
uint16_t sig;
|
||||
uint16_t name_len;
|
||||
uint32_t data_size;
|
||||
uint32_t data_offset;
|
||||
uint32_t data_type;
|
||||
uint32_t _pad;
|
||||
char name[];
|
||||
} _packed_ KeyValue;
|
||||
assert_cc(offsetof(KeyValue, sig) == 0);
|
||||
assert_cc(offsetof(KeyValue, name_len) == 2);
|
||||
@@ -109,18 +103,18 @@ assert_cc(offsetof(KeyValue, data_type) == 12);
|
||||
assert_cc(offsetof(KeyValue, name) == 20);
|
||||
|
||||
#define BAD_OFFSET(offset, len, max) \
|
||||
((UINT64) (offset) + (len) >= (max))
|
||||
((uint64_t) (offset) + (len) >= (max))
|
||||
|
||||
#define BAD_STRUCT(type, offset, max) \
|
||||
((UINT64) (offset) + sizeof(type) >= (max))
|
||||
((uint64_t) (offset) + sizeof(type) >= (max))
|
||||
|
||||
#define BAD_ARRAY(type, array, offset, array_len, max) \
|
||||
((UINT64) (offset) + offsetof(type, array) + \
|
||||
sizeof((type){}.array[0]) * (UINT64) (array_len) >= (max))
|
||||
((uint64_t) (offset) + offsetof(type, array) + \
|
||||
sizeof((type){}.array[0]) * (uint64_t) (array_len) >= (max))
|
||||
|
||||
static const Key *get_key(const UINT8 *bcd, UINT32 bcd_len, UINT32 offset, const CHAR8 *name);
|
||||
static const Key *get_key(const uint8_t *bcd, uint32_t bcd_len, uint32_t offset, const char *name);
|
||||
|
||||
static const Key *get_subkey(const UINT8 *bcd, UINT32 bcd_len, UINT32 offset, const CHAR8 *name) {
|
||||
static const Key *get_subkey(const uint8_t *bcd, uint32_t bcd_len, uint32_t offset, const char *name) {
|
||||
assert(bcd);
|
||||
assert(name);
|
||||
|
||||
@@ -134,8 +128,8 @@ static const Key *get_subkey(const UINT8 *bcd, UINT32 bcd_len, UINT32 offset, co
|
||||
if (BAD_ARRAY(SubkeyFast, entries, offset, subkey->n_entries, bcd_len))
|
||||
return NULL;
|
||||
|
||||
for (UINT16 i = 0; i < subkey->n_entries; i++) {
|
||||
if (!strncaseeq8((char *) name, (char *) subkey->entries[i].name_hint, sizeof(subkey->entries[i].name_hint)))
|
||||
for (uint16_t i = 0; i < subkey->n_entries; i++) {
|
||||
if (!strncaseeq8(name, subkey->entries[i].name_hint, sizeof(subkey->entries[i].name_hint)))
|
||||
continue;
|
||||
|
||||
const Key *key = get_key(bcd, bcd_len, subkey->entries[i].key_offset, name);
|
||||
@@ -149,7 +143,7 @@ static const Key *get_subkey(const UINT8 *bcd, UINT32 bcd_len, UINT32 offset, co
|
||||
/* We use NUL as registry path separators for convenience. To start from the root, begin
|
||||
* name with a NUL. Name must end with two NUL. The lookup depth is not restricted, so
|
||||
* name must be properly validated before calling get_key(). */
|
||||
static const Key *get_key(const UINT8 *bcd, UINT32 bcd_len, UINT32 offset, const CHAR8 *name) {
|
||||
static const Key *get_key(const uint8_t *bcd, uint32_t bcd_len, uint32_t offset, const char *name) {
|
||||
assert(bcd);
|
||||
assert(name);
|
||||
|
||||
@@ -164,7 +158,7 @@ static const Key *get_key(const UINT8 *bcd, UINT32 bcd_len, UINT32 offset, const
|
||||
return NULL;
|
||||
|
||||
if (*name) {
|
||||
if (strncaseeq8((char *) name, (char *) key->key_name, key->key_name_len) && strlen8((const char *) name) == key->key_name_len)
|
||||
if (strncaseeq8(name, key->key_name, key->key_name_len) && strlen8(name) == key->key_name_len)
|
||||
name += key->key_name_len;
|
||||
else
|
||||
return NULL;
|
||||
@@ -174,7 +168,7 @@ static const Key *get_key(const UINT8 *bcd, UINT32 bcd_len, UINT32 offset, const
|
||||
return *name ? get_subkey(bcd, bcd_len, key->subkeys_offset, name) : key;
|
||||
}
|
||||
|
||||
static const KeyValue *get_key_value(const UINT8 *bcd, UINT32 bcd_len, const Key *key, const CHAR8 *name) {
|
||||
static const KeyValue *get_key_value(const uint8_t *bcd, uint32_t bcd_len, const Key *key, const char *name) {
|
||||
assert(bcd);
|
||||
assert(key);
|
||||
assert(name);
|
||||
@@ -182,13 +176,13 @@ static const KeyValue *get_key_value(const UINT8 *bcd, UINT32 bcd_len, const Key
|
||||
if (key->n_key_values == 0)
|
||||
return NULL;
|
||||
|
||||
if (BAD_OFFSET(key->key_values_offset, sizeof(UINT32) * (UINT64) key->n_key_values, bcd_len) ||
|
||||
(UINTN)(bcd + key->key_values_offset) % sizeof(UINT32) != 0)
|
||||
if (BAD_OFFSET(key->key_values_offset, sizeof(uint32_t) * (uint64_t) key->n_key_values, bcd_len) ||
|
||||
(UINTN)(bcd + key->key_values_offset) % sizeof(uint32_t) != 0)
|
||||
return NULL;
|
||||
|
||||
const UINT32 *key_value_list = (const UINT32 *) (bcd + key->key_values_offset);
|
||||
for (UINT32 i = 0; i < key->n_key_values; i++) {
|
||||
UINT32 offset = *(key_value_list + i);
|
||||
const uint32_t *key_value_list = (const uint32_t *) (bcd + key->key_values_offset);
|
||||
for (uint32_t i = 0; i < key->n_key_values; i++) {
|
||||
uint32_t offset = *(key_value_list + i);
|
||||
|
||||
if (BAD_STRUCT(KeyValue, offset, bcd_len))
|
||||
continue;
|
||||
@@ -209,7 +203,7 @@ static const KeyValue *get_key_value(const UINT8 *bcd, UINT32 bcd_len, const Key
|
||||
if (BAD_OFFSET(kv->data_offset, kv->data_size, bcd_len))
|
||||
continue;
|
||||
|
||||
if (strncaseeq8((char *)name, (char *) kv->name, kv->name_len) && strlen8((const char *) name) == kv->name_len)
|
||||
if (strncaseeq8(name, kv->name, kv->name_len) && strlen8(name) == kv->name_len)
|
||||
return kv;
|
||||
}
|
||||
|
||||
@@ -233,7 +227,7 @@ static const KeyValue *get_key_value(const UINT8 *bcd, UINT32 bcd_len, const Key
|
||||
* (it always has the GUID 9dea862c-5cdd-4e70-acc1-f32b344d4795). If it contains more than
|
||||
* one GUID, the BCD is multi-boot and we stop looking. Otherwise we take that GUID, look it
|
||||
* up, and return its description property. */
|
||||
TEST_STATIC CHAR16 *get_bcd_title(UINT8 *bcd, UINTN bcd_len) {
|
||||
TEST_STATIC char16_t *get_bcd_title(uint8_t *bcd, UINTN bcd_len) {
|
||||
assert(bcd);
|
||||
|
||||
if (HIVE_CELL_OFFSET >= bcd_len)
|
||||
@@ -250,38 +244,33 @@ TEST_STATIC CHAR16 *get_bcd_title(UINT8 *bcd, UINTN bcd_len) {
|
||||
bcd += HIVE_CELL_OFFSET;
|
||||
bcd_len -= HIVE_CELL_OFFSET;
|
||||
|
||||
const Key *objects_key = get_key(
|
||||
bcd, bcd_len,
|
||||
base_block->root_cell_offset,
|
||||
(const CHAR8 *) "\0Objects\0");
|
||||
const Key *objects_key = get_key(bcd, bcd_len, base_block->root_cell_offset, "\0Objects\0");
|
||||
if (!objects_key)
|
||||
return NULL;
|
||||
|
||||
const Key *displayorder_key = get_subkey(
|
||||
bcd, bcd_len,
|
||||
objects_key->subkeys_offset,
|
||||
(const CHAR8 *) "{9dea862c-5cdd-4e70-acc1-f32b344d4795}\0Elements\00024000001\0");
|
||||
bcd,
|
||||
bcd_len,
|
||||
objects_key->subkeys_offset,
|
||||
"{9dea862c-5cdd-4e70-acc1-f32b344d4795}\0Elements\00024000001\0");
|
||||
if (!displayorder_key)
|
||||
return NULL;
|
||||
|
||||
const KeyValue *displayorder_value = get_key_value(
|
||||
bcd, bcd_len,
|
||||
displayorder_key,
|
||||
(const CHAR8 *) "Element");
|
||||
const KeyValue *displayorder_value = get_key_value(bcd, bcd_len, displayorder_key, "Element");
|
||||
if (!displayorder_value)
|
||||
return NULL;
|
||||
|
||||
CHAR8 order_guid[sizeof("{00000000-0000-0000-0000-000000000000}\0")];
|
||||
char order_guid[sizeof("{00000000-0000-0000-0000-000000000000}\0")];
|
||||
if (displayorder_value->data_type != REG_MULTI_SZ ||
|
||||
displayorder_value->data_size != sizeof(CHAR16[sizeof(order_guid)]) ||
|
||||
(UINTN)(bcd + displayorder_value->data_offset) % sizeof(CHAR16) != 0)
|
||||
displayorder_value->data_size != sizeof(char16_t[sizeof(order_guid)]) ||
|
||||
(UINTN)(bcd + displayorder_value->data_offset) % sizeof(char16_t) != 0)
|
||||
/* BCD is multi-boot. */
|
||||
return NULL;
|
||||
|
||||
/* Keys are stored as ASCII in registry hives if the data fits (and GUIDS always should). */
|
||||
CHAR16 *order_guid_utf16 = (CHAR16 *) (bcd + displayorder_value->data_offset);
|
||||
char16_t *order_guid_utf16 = (char16_t *) (bcd + displayorder_value->data_offset);
|
||||
for (UINTN i = 0; i < sizeof(order_guid) - 2; i++) {
|
||||
CHAR16 c = order_guid_utf16[i];
|
||||
char16_t c = order_guid_utf16[i];
|
||||
switch (c) {
|
||||
case '-':
|
||||
case '{':
|
||||
@@ -305,27 +294,22 @@ TEST_STATIC CHAR16 *get_bcd_title(UINT8 *bcd, UINTN bcd_len) {
|
||||
return NULL;
|
||||
|
||||
const Key *description_key = get_subkey(
|
||||
bcd, bcd_len,
|
||||
default_key->subkeys_offset,
|
||||
(const CHAR8 *) "Elements\00012000004\0");
|
||||
bcd, bcd_len, default_key->subkeys_offset, "Elements\00012000004\0");
|
||||
if (!description_key)
|
||||
return NULL;
|
||||
|
||||
const KeyValue *description_value = get_key_value(
|
||||
bcd, bcd_len,
|
||||
description_key,
|
||||
(const CHAR8 *) "Element");
|
||||
const KeyValue *description_value = get_key_value(bcd, bcd_len, description_key, "Element");
|
||||
if (!description_value)
|
||||
return NULL;
|
||||
|
||||
if (description_value->data_type != REG_SZ ||
|
||||
description_value->data_size < sizeof(CHAR16) ||
|
||||
description_value->data_size % sizeof(CHAR16) != 0 ||
|
||||
(UINTN)(bcd + description_value->data_offset) % sizeof(CHAR16))
|
||||
description_value->data_size < sizeof(char16_t) ||
|
||||
description_value->data_size % sizeof(char16_t) != 0 ||
|
||||
(UINTN)(bcd + description_value->data_offset) % sizeof(char16_t))
|
||||
return NULL;
|
||||
|
||||
/* The data should already be NUL-terminated. */
|
||||
CHAR16 *title = (CHAR16 *) (bcd + description_value->data_offset);
|
||||
title[description_value->data_size / sizeof(CHAR16) - 1] = '\0';
|
||||
char16_t *title = (char16_t *) (bcd + description_value->data_offset);
|
||||
title[description_value->data_size / sizeof(char16_t) - 1] = '\0';
|
||||
return title;
|
||||
}
|
||||
|
||||
+2
-1
@@ -2,5 +2,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <efi.h>
|
||||
#include <uchar.h>
|
||||
|
||||
CHAR16 *get_bcd_title(UINT8 *bcd, UINTN bcd_len);
|
||||
char16_t *get_bcd_title(uint8_t *bcd, UINTN bcd_len);
|
||||
|
||||
+313
-312
File diff suppressed because it is too large
Load Diff
+33
-33
@@ -37,9 +37,9 @@ static inline void event_closep(EFI_EVENT *event) {
|
||||
* will replace ConInEx permanently if it ever reports a key press.
|
||||
* Lastly, a timer event allows us to provide a input timeout without having to call into
|
||||
* any input functions that can freeze on us or using a busy/stall loop. */
|
||||
EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
|
||||
EFI_STATUS console_key_read(uint64_t *key, uint64_t timeout_usec) {
|
||||
static EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *conInEx = NULL, *extraInEx = NULL;
|
||||
static BOOLEAN checked = FALSE;
|
||||
static bool checked = false;
|
||||
UINTN index;
|
||||
EFI_STATUS err;
|
||||
_cleanup_(event_closep) EFI_EVENT timer = NULL;
|
||||
@@ -49,24 +49,24 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
|
||||
if (!checked) {
|
||||
/* Get the *first* TextInputEx device.*/
|
||||
err = BS->LocateProtocol(&SimpleTextInputExProtocol, NULL, (void **) &extraInEx);
|
||||
if (EFI_ERROR(err) || BS->CheckEvent(extraInEx->WaitForKeyEx) == EFI_INVALID_PARAMETER)
|
||||
if (err != EFI_SUCCESS || BS->CheckEvent(extraInEx->WaitForKeyEx) == EFI_INVALID_PARAMETER)
|
||||
/* If WaitForKeyEx fails here, the firmware pretends it talks this
|
||||
* protocol, but it really doesn't. */
|
||||
extraInEx = NULL;
|
||||
|
||||
/* Get the TextInputEx version of ST->ConIn. */
|
||||
err = BS->HandleProtocol(ST->ConsoleInHandle, &SimpleTextInputExProtocol, (void **) &conInEx);
|
||||
if (EFI_ERROR(err) || BS->CheckEvent(conInEx->WaitForKeyEx) == EFI_INVALID_PARAMETER)
|
||||
if (err != EFI_SUCCESS || BS->CheckEvent(conInEx->WaitForKeyEx) == EFI_INVALID_PARAMETER)
|
||||
conInEx = NULL;
|
||||
|
||||
if (conInEx == extraInEx)
|
||||
extraInEx = NULL;
|
||||
|
||||
checked = TRUE;
|
||||
checked = true;
|
||||
}
|
||||
|
||||
err = BS->CreateEvent(EVT_TIMER, 0, NULL, NULL, &timer);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Error creating timer event: %r", err);
|
||||
|
||||
EFI_EVENT events[] = {
|
||||
@@ -79,7 +79,7 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
|
||||
/* Watchdog rearming loop in case the user never provides us with input or some
|
||||
* broken firmware never returns from WaitForEvent. */
|
||||
for (;;) {
|
||||
UINT64 watchdog_timeout_sec = 5 * 60,
|
||||
uint64_t watchdog_timeout_sec = 5 * 60,
|
||||
watchdog_ping_usec = watchdog_timeout_sec / 2 * 1000 * 1000;
|
||||
|
||||
/* SetTimer expects 100ns units for some reason. */
|
||||
@@ -87,14 +87,14 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
|
||||
timer,
|
||||
TimerRelative,
|
||||
MIN(timeout_usec, watchdog_ping_usec) * 10);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Error arming timer event: %r", err);
|
||||
|
||||
(void) BS->SetWatchdogTimer(watchdog_timeout_sec, 0x10000, 0, NULL);
|
||||
err = BS->WaitForEvent(n_events, events, &index);
|
||||
(void) BS->SetWatchdogTimer(watchdog_timeout_sec, 0x10000, 0, NULL);
|
||||
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Error waiting for events: %r", err);
|
||||
|
||||
/* We have keyboard input, process it after this loop. */
|
||||
@@ -115,7 +115,7 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
|
||||
|
||||
/* If the extra input device we found returns something, always use that instead
|
||||
* to work around broken firmware freezing on ConIn/ConInEx. */
|
||||
if (extraInEx && !EFI_ERROR(BS->CheckEvent(extraInEx->WaitForKeyEx))) {
|
||||
if (extraInEx && BS->CheckEvent(extraInEx->WaitForKeyEx) == EFI_SUCCESS) {
|
||||
conInEx = extraInEx;
|
||||
extraInEx = NULL;
|
||||
}
|
||||
@@ -124,10 +124,10 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
|
||||
* The two may be out of sync on some firmware, giving us double input. */
|
||||
if (conInEx) {
|
||||
EFI_KEY_DATA keydata;
|
||||
UINT32 shift = 0;
|
||||
uint32_t shift = 0;
|
||||
|
||||
err = conInEx->ReadKeyStrokeEx(conInEx, &keydata);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (FLAGS_SET(keydata.KeyState.KeyShiftState, EFI_SHIFT_STATE_VALID)) {
|
||||
@@ -145,11 +145,11 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
|
||||
/* 32 bit modifier keys + 16 bit scan code + 16 bit unicode */
|
||||
*key = KEYPRESS(shift, keydata.Key.ScanCode, keydata.Key.UnicodeChar);
|
||||
return EFI_SUCCESS;
|
||||
} else if (!EFI_ERROR(BS->CheckEvent(ST->ConIn->WaitForKey))) {
|
||||
} else if (BS->CheckEvent(ST->ConIn->WaitForKey) == EFI_SUCCESS) {
|
||||
EFI_INPUT_KEY k;
|
||||
|
||||
err = ST->ConIn->ReadKeyStroke(ST->ConIn, &k);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
*key = KEYPRESS(0, k.ScanCode, k.UnicodeChar);
|
||||
@@ -159,34 +159,34 @@ EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec) {
|
||||
return EFI_NOT_READY;
|
||||
}
|
||||
|
||||
static EFI_STATUS change_mode(INT64 mode) {
|
||||
static EFI_STATUS change_mode(int64_t mode) {
|
||||
EFI_STATUS err;
|
||||
INT32 old_mode;
|
||||
int32_t old_mode;
|
||||
|
||||
/* SetMode expects a UINTN, so make sure these values are sane. */
|
||||
mode = CLAMP(mode, CONSOLE_MODE_RANGE_MIN, CONSOLE_MODE_RANGE_MAX);
|
||||
old_mode = MAX(CONSOLE_MODE_RANGE_MIN, ST->ConOut->Mode->Mode);
|
||||
|
||||
err = ST->ConOut->SetMode(ST->ConOut, mode);
|
||||
if (!EFI_ERROR(err))
|
||||
if (err == EFI_SUCCESS)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
/* Something went wrong. Output is probably borked, so try to revert to previous mode. */
|
||||
if (!EFI_ERROR(ST->ConOut->SetMode(ST->ConOut, old_mode)))
|
||||
if (ST->ConOut->SetMode(ST->ConOut, old_mode) == EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Maybe the device is on fire? */
|
||||
ST->ConOut->Reset(ST->ConOut, TRUE);
|
||||
ST->ConOut->Reset(ST->ConOut, true);
|
||||
ST->ConOut->SetMode(ST->ConOut, CONSOLE_MODE_RANGE_MIN);
|
||||
return err;
|
||||
}
|
||||
|
||||
EFI_STATUS query_screen_resolution(UINT32 *ret_w, UINT32 *ret_h) {
|
||||
EFI_STATUS query_screen_resolution(uint32_t *ret_w, uint32_t *ret_h) {
|
||||
EFI_STATUS err;
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *go;
|
||||
|
||||
err = BS->LocateProtocol(&GraphicsOutputProtocol, NULL, (void **) &go);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (!go->Mode || !go->Mode->Info)
|
||||
@@ -197,30 +197,30 @@ EFI_STATUS query_screen_resolution(UINT32 *ret_w, UINT32 *ret_h) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static INT64 get_auto_mode(void) {
|
||||
UINT32 screen_width, screen_height;
|
||||
static int64_t get_auto_mode(void) {
|
||||
uint32_t screen_width, screen_height;
|
||||
|
||||
if (!EFI_ERROR(query_screen_resolution(&screen_width, &screen_height))) {
|
||||
BOOLEAN keep = FALSE;
|
||||
if (query_screen_resolution(&screen_width, &screen_height) == EFI_SUCCESS) {
|
||||
bool keep = false;
|
||||
|
||||
/* Start verifying if we are in a resolution larger than Full HD
|
||||
* (1920x1080). If we're not, assume we're in a good mode and do not
|
||||
* try to change it. */
|
||||
if (screen_width <= HORIZONTAL_MAX_OK && screen_height <= VERTICAL_MAX_OK)
|
||||
keep = TRUE;
|
||||
keep = true;
|
||||
/* For larger resolutions, calculate the ratio of the total screen
|
||||
* area to the text viewport area. If it's less than 10 times bigger,
|
||||
* then assume the text is readable and keep the text mode. */
|
||||
else {
|
||||
UINT64 text_area;
|
||||
uint64_t text_area;
|
||||
UINTN x_max, y_max;
|
||||
UINT64 screen_area = (UINT64)screen_width * (UINT64)screen_height;
|
||||
uint64_t screen_area = (uint64_t)screen_width * (uint64_t)screen_height;
|
||||
|
||||
console_query_mode(&x_max, &y_max);
|
||||
text_area = SYSTEM_FONT_WIDTH * SYSTEM_FONT_HEIGHT * (UINT64)x_max * (UINT64)y_max;
|
||||
text_area = SYSTEM_FONT_WIDTH * SYSTEM_FONT_HEIGHT * (uint64_t)x_max * (uint64_t)y_max;
|
||||
|
||||
if (text_area != 0 && screen_area/text_area < VIEWPORT_RATIO)
|
||||
keep = TRUE;
|
||||
keep = true;
|
||||
}
|
||||
|
||||
if (keep)
|
||||
@@ -244,7 +244,7 @@ static INT64 get_auto_mode(void) {
|
||||
return CONSOLE_MODE_80_25;
|
||||
}
|
||||
|
||||
EFI_STATUS console_set_mode(INT64 mode) {
|
||||
EFI_STATUS console_set_mode(int64_t mode) {
|
||||
switch (mode) {
|
||||
case CONSOLE_MODE_KEEP:
|
||||
/* If the firmware indicates the current mode is invalid, change it anyway. */
|
||||
@@ -259,7 +259,7 @@ EFI_STATUS console_set_mode(INT64 mode) {
|
||||
mode = MAX(CONSOLE_MODE_RANGE_MIN, ST->ConOut->Mode->Mode);
|
||||
do {
|
||||
mode = (mode + 1) % ST->ConOut->Mode->MaxMode;
|
||||
if (!EFI_ERROR(change_mode(mode)))
|
||||
if (change_mode(mode) == EFI_SUCCESS)
|
||||
break;
|
||||
/* If this mode is broken/unsupported, try the next.
|
||||
* If mode is 0, we wrapped around and should stop. */
|
||||
@@ -286,7 +286,7 @@ EFI_STATUS console_query_mode(UINTN *x_max, UINTN *y_max) {
|
||||
assert(y_max);
|
||||
|
||||
err = ST->ConOut->QueryMode(ST->ConOut, ST->ConOut->Mode->Mode, x_max, y_max);
|
||||
if (EFI_ERROR(err)) {
|
||||
if (err != EFI_SUCCESS) {
|
||||
/* Fallback values mandated by UEFI spec. */
|
||||
switch (ST->ConOut->Mode->Mode) {
|
||||
case CONSOLE_MODE_80_50:
|
||||
|
||||
@@ -10,12 +10,12 @@ enum {
|
||||
EFI_LOGO_PRESSED = EFI_RIGHT_LOGO_PRESSED|EFI_LEFT_LOGO_PRESSED,
|
||||
};
|
||||
|
||||
#define KEYPRESS(keys, scan, uni) ((((UINT64)keys) << 32) | (((UINT64)scan) << 16) | (uni))
|
||||
#define KEYCHAR(k) ((CHAR16)(k))
|
||||
#define KEYPRESS(keys, scan, uni) ((((uint64_t)keys) << 32) | (((uint64_t)scan) << 16) | (uni))
|
||||
#define KEYCHAR(k) ((char16_t)(k))
|
||||
#define CHAR_CTRL(c) ((c) - 'a' + 1)
|
||||
|
||||
enum {
|
||||
/* Console mode is a INT32 in EFI. We use INT64 to make room for our special values. */
|
||||
/* Console mode is a int32_t in EFI. We use int64_t to make room for our special values. */
|
||||
CONSOLE_MODE_RANGE_MIN = 0,
|
||||
CONSOLE_MODE_RANGE_MAX = INT32_MAX, /* This is just the theoretical limit. */
|
||||
CONSOLE_MODE_INVALID = -1, /* UEFI uses -1 if the device is not in a valid text mode. */
|
||||
@@ -31,7 +31,7 @@ enum {
|
||||
CONSOLE_MODE_FIRMWARE_MAX, /* 'max' in config. */
|
||||
};
|
||||
|
||||
EFI_STATUS console_key_read(UINT64 *key, UINT64 timeout_usec);
|
||||
EFI_STATUS console_set_mode(INT64 mode);
|
||||
EFI_STATUS console_key_read(uint64_t *key, uint64_t timeout_usec);
|
||||
EFI_STATUS console_set_mode(int64_t mode);
|
||||
EFI_STATUS console_query_mode(UINTN *x_max, UINTN *y_max);
|
||||
EFI_STATUS query_screen_resolution(UINT32 *ret_width, UINT32 *ret_height);
|
||||
EFI_STATUS query_screen_resolution(uint32_t *ret_width, uint32_t *ret_height);
|
||||
|
||||
+52
-52
@@ -4,7 +4,7 @@
|
||||
#include "measure.h"
|
||||
#include "util.h"
|
||||
|
||||
static CHAR8* write_cpio_word(CHAR8 *p, UINT32 v) {
|
||||
static char *write_cpio_word(char *p, uint32_t v) {
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
|
||||
assert(p);
|
||||
@@ -17,8 +17,8 @@ static CHAR8* write_cpio_word(CHAR8 *p, UINT32 v) {
|
||||
return p + 8;
|
||||
}
|
||||
|
||||
static CHAR8* mangle_filename(CHAR8 *p, const CHAR16 *f) {
|
||||
CHAR8* w;
|
||||
static char *mangle_filename(char *p, const char16_t *f) {
|
||||
char* w;
|
||||
|
||||
assert(p);
|
||||
assert(f);
|
||||
@@ -36,7 +36,7 @@ static CHAR8* mangle_filename(CHAR8 *p, const CHAR16 *f) {
|
||||
return w;
|
||||
}
|
||||
|
||||
static CHAR8* pad4(CHAR8 *p, const CHAR8* start) {
|
||||
static char *pad4(char *p, const char *start) {
|
||||
assert(p);
|
||||
assert(start);
|
||||
assert(p >= start);
|
||||
@@ -50,17 +50,17 @@ static CHAR8* pad4(CHAR8 *p, const CHAR8* start) {
|
||||
}
|
||||
|
||||
static EFI_STATUS pack_cpio_one(
|
||||
const CHAR16 *fname,
|
||||
const char16_t *fname,
|
||||
const void *contents,
|
||||
UINTN contents_size,
|
||||
const CHAR8 *target_dir_prefix,
|
||||
UINT32 access_mode,
|
||||
UINT32 *inode_counter,
|
||||
const char *target_dir_prefix,
|
||||
uint32_t access_mode,
|
||||
uint32_t *inode_counter,
|
||||
void **cpio_buffer,
|
||||
UINTN *cpio_buffer_size) {
|
||||
|
||||
UINTN l, target_dir_prefix_size, fname_size, q;
|
||||
CHAR8 *a;
|
||||
char *a;
|
||||
|
||||
assert(fname);
|
||||
assert(contents_size || contents_size == 0);
|
||||
@@ -81,7 +81,7 @@ static EFI_STATUS pack_cpio_one(
|
||||
|
||||
l = 6 + 13*8 + 1 + 1; /* Fixed CPIO header size, slash separator, and NUL byte after the file name*/
|
||||
|
||||
target_dir_prefix_size = strlen8((const char *) target_dir_prefix);
|
||||
target_dir_prefix_size = strlen8(target_dir_prefix);
|
||||
if (l > UINTN_MAX - target_dir_prefix_size)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
l += target_dir_prefix_size;
|
||||
@@ -114,7 +114,7 @@ static EFI_STATUS pack_cpio_one(
|
||||
a = xrealloc(*cpio_buffer, *cpio_buffer_size, *cpio_buffer_size + l);
|
||||
|
||||
*cpio_buffer = a;
|
||||
a = (CHAR8*) *cpio_buffer + *cpio_buffer_size;
|
||||
a = (char *) *cpio_buffer + *cpio_buffer_size;
|
||||
|
||||
memcpy(a, "070701", 6); /* magic ID */
|
||||
a += 6;
|
||||
@@ -153,21 +153,21 @@ static EFI_STATUS pack_cpio_one(
|
||||
/* Pad to next multiple of 4 */
|
||||
a = pad4(a, *cpio_buffer);
|
||||
|
||||
assert(a == (CHAR8*) *cpio_buffer + *cpio_buffer_size + l);
|
||||
assert(a == (char *) *cpio_buffer + *cpio_buffer_size + l);
|
||||
*cpio_buffer_size += l;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static EFI_STATUS pack_cpio_dir(
|
||||
const CHAR8 *path,
|
||||
UINT32 access_mode,
|
||||
UINT32 *inode_counter,
|
||||
const char *path,
|
||||
uint32_t access_mode,
|
||||
uint32_t *inode_counter,
|
||||
void **cpio_buffer,
|
||||
UINTN *cpio_buffer_size) {
|
||||
|
||||
UINTN l, path_size;
|
||||
CHAR8 *a;
|
||||
char *a;
|
||||
|
||||
assert(path);
|
||||
assert(inode_counter);
|
||||
@@ -182,7 +182,7 @@ static EFI_STATUS pack_cpio_dir(
|
||||
|
||||
l = 6 + 13*8 + 1; /* Fixed CPIO header size, and NUL byte after the file name*/
|
||||
|
||||
path_size = strlen8((const char *) path);
|
||||
path_size = strlen8(path);
|
||||
if (l > UINTN_MAX - path_size)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
l += path_size;
|
||||
@@ -196,7 +196,7 @@ static EFI_STATUS pack_cpio_dir(
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
*cpio_buffer = a = xrealloc(*cpio_buffer, *cpio_buffer_size, *cpio_buffer_size + l);
|
||||
a = (CHAR8*) *cpio_buffer + *cpio_buffer_size;
|
||||
a = (char *) *cpio_buffer + *cpio_buffer_size;
|
||||
|
||||
memcpy(a, "070701", 6); /* magic ID */
|
||||
a += 6;
|
||||
@@ -221,16 +221,16 @@ static EFI_STATUS pack_cpio_dir(
|
||||
/* Pad to next multiple of 4 */
|
||||
a = pad4(a, *cpio_buffer);
|
||||
|
||||
assert(a == (CHAR8*) *cpio_buffer + *cpio_buffer_size + l);
|
||||
assert(a == (char *) *cpio_buffer + *cpio_buffer_size + l);
|
||||
|
||||
*cpio_buffer_size += l;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static EFI_STATUS pack_cpio_prefix(
|
||||
const CHAR8 *path,
|
||||
UINT32 dir_mode,
|
||||
UINT32 *inode_counter,
|
||||
const char *path,
|
||||
uint32_t dir_mode,
|
||||
uint32_t *inode_counter,
|
||||
void **cpio_buffer,
|
||||
UINTN *cpio_buffer_size) {
|
||||
|
||||
@@ -245,22 +245,22 @@ static EFI_STATUS pack_cpio_prefix(
|
||||
* (similar to mkdir -p behaviour) all leading paths are created with 0555 access mode, only the
|
||||
* final dir is created with the specified directory access mode. */
|
||||
|
||||
for (const CHAR8 *p = path;;) {
|
||||
const CHAR8 *e;
|
||||
for (const char *p = path;;) {
|
||||
const char *e;
|
||||
|
||||
e = (const CHAR8 *) strchr8((const char *) p, '/');
|
||||
e = strchr8(p, '/');
|
||||
if (!e)
|
||||
break;
|
||||
|
||||
if (e > p) {
|
||||
_cleanup_freepool_ CHAR8 *t = NULL;
|
||||
_cleanup_free_ char *t = NULL;
|
||||
|
||||
t = (CHAR8 *) xstrndup8((const char *) path, e - path);
|
||||
t = xstrndup8(path, e - path);
|
||||
if (!t)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
err = pack_cpio_dir(t, 0555, inode_counter, cpio_buffer, cpio_buffer_size);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -298,7 +298,7 @@ static EFI_STATUS pack_cpio_trailer(
|
||||
assert_cc(sizeof(trailer) % 4 == 0);
|
||||
|
||||
*cpio_buffer = xrealloc(*cpio_buffer, *cpio_buffer_size, *cpio_buffer_size + sizeof(trailer));
|
||||
memcpy((UINT8*) *cpio_buffer + *cpio_buffer_size, trailer, sizeof(trailer));
|
||||
memcpy((uint8_t*) *cpio_buffer + *cpio_buffer_size, trailer, sizeof(trailer));
|
||||
*cpio_buffer_size += sizeof(trailer);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
@@ -306,24 +306,24 @@ static EFI_STATUS pack_cpio_trailer(
|
||||
|
||||
EFI_STATUS pack_cpio(
|
||||
EFI_LOADED_IMAGE *loaded_image,
|
||||
const CHAR16 *dropin_dir,
|
||||
const CHAR16 *match_suffix,
|
||||
const CHAR8 *target_dir_prefix,
|
||||
UINT32 dir_mode,
|
||||
UINT32 access_mode,
|
||||
const UINT32 tpm_pcr[],
|
||||
const char16_t *dropin_dir,
|
||||
const char16_t *match_suffix,
|
||||
const char *target_dir_prefix,
|
||||
uint32_t dir_mode,
|
||||
uint32_t access_mode,
|
||||
const uint32_t tpm_pcr[],
|
||||
UINTN n_tpm_pcr,
|
||||
const CHAR16 *tpm_description,
|
||||
const char16_t *tpm_description,
|
||||
void **ret_buffer,
|
||||
UINTN *ret_buffer_size) {
|
||||
|
||||
_cleanup_(file_closep) EFI_FILE *root = NULL, *extra_dir = NULL;
|
||||
UINTN dirent_size = 0, buffer_size = 0, n_items = 0, n_allocated = 0;
|
||||
_cleanup_freepool_ CHAR16 *rel_dropin_dir = NULL;
|
||||
_cleanup_free_ char16_t *rel_dropin_dir = NULL;
|
||||
_cleanup_freepool_ EFI_FILE_INFO *dirent = NULL;
|
||||
_cleanup_(strv_freep) CHAR16 **items = NULL;
|
||||
_cleanup_(strv_freep) char16_t **items = NULL;
|
||||
_cleanup_freepool_ void *buffer = NULL;
|
||||
UINT32 inode = 1; /* inode counter, so that each item gets a new inode */
|
||||
uint32_t inode = 1; /* inode counter, so that each item gets a new inode */
|
||||
EFI_STATUS err;
|
||||
EFI_FILE_IO_INTERFACE *volume;
|
||||
|
||||
@@ -349,12 +349,12 @@ EFI_STATUS pack_cpio(
|
||||
*ret_buffer_size = 0;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(
|
||||
err, L"Unable to load file system protocol: %r", err);
|
||||
|
||||
err = volume->OpenVolume(volume, &root);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(
|
||||
err, L"Unable to open root directory: %r", err);
|
||||
|
||||
@@ -368,14 +368,14 @@ EFI_STATUS pack_cpio(
|
||||
*ret_buffer_size = 0;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to open extra directory of loaded image: %r", err);
|
||||
|
||||
for (;;) {
|
||||
_cleanup_freepool_ CHAR16 *d = NULL;
|
||||
_cleanup_free_ char16_t *d = NULL;
|
||||
|
||||
err = readdir_harder(extra_dir, &dirent, &dirent_size);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to read extra directory of loaded image: %r", err);
|
||||
if (!dirent) /* End of directory */
|
||||
break;
|
||||
@@ -397,11 +397,11 @@ EFI_STATUS pack_cpio(
|
||||
UINTN m;
|
||||
|
||||
/* We allocate 16 entries at a time, as a matter of optimization */
|
||||
if (n_items > (UINTN_MAX / sizeof(UINT16)) - 16) /* Overflow check, just in case */
|
||||
if (n_items > (UINTN_MAX / sizeof(uint16_t)) - 16) /* Overflow check, just in case */
|
||||
return log_oom();
|
||||
|
||||
m = n_items + 16;
|
||||
items = xrealloc(items, n_allocated * sizeof(UINT16*), m * sizeof(UINT16*));
|
||||
items = xrealloc(items, n_allocated * sizeof(uint16_t *), m * sizeof(uint16_t *));
|
||||
n_allocated = m;
|
||||
}
|
||||
|
||||
@@ -423,15 +423,15 @@ EFI_STATUS pack_cpio(
|
||||
/* Generate the leading directory inodes right before adding the first files, to the
|
||||
* archive. Otherwise the cpio archive cannot be unpacked, since the leading dirs won't exist. */
|
||||
err = pack_cpio_prefix(target_dir_prefix, dir_mode, &inode, &buffer, &buffer_size);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to pack cpio prefix: %r", err);
|
||||
|
||||
for (UINTN i = 0; i < n_items; i++) {
|
||||
_cleanup_freepool_ CHAR8 *content = NULL;
|
||||
_cleanup_free_ char *content = NULL;
|
||||
UINTN contentsize;
|
||||
|
||||
err = file_read(extra_dir, items[i], 0, 0, &content, &contentsize);
|
||||
if (EFI_ERROR(err)) {
|
||||
if (err != EFI_SUCCESS) {
|
||||
log_error_status_stall(err, L"Failed to read %s, ignoring: %r", items[i], err);
|
||||
continue;
|
||||
}
|
||||
@@ -443,12 +443,12 @@ EFI_STATUS pack_cpio(
|
||||
access_mode,
|
||||
&inode,
|
||||
&buffer, &buffer_size);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to pack cpio file %s: %r", dirent->FileName, err);
|
||||
}
|
||||
|
||||
err = pack_cpio_trailer(&buffer, &buffer_size);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to pack cpio trailer: %r");
|
||||
|
||||
for (UINTN i = 0; i < n_tpm_pcr; i++) {
|
||||
@@ -457,7 +457,7 @@ EFI_STATUS pack_cpio(
|
||||
POINTER_TO_PHYSICAL_ADDRESS(buffer),
|
||||
buffer_size,
|
||||
tpm_description);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
log_error_stall(L"Unable to add initrd TPM measurement for PCR %u (%s), ignoring: %r", tpm_pcr[i], tpm_description, err);
|
||||
}
|
||||
|
||||
|
||||
+8
-7
@@ -2,16 +2,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <efi.h>
|
||||
#include <uchar.h>
|
||||
|
||||
EFI_STATUS pack_cpio(
|
||||
EFI_LOADED_IMAGE *loaded_image,
|
||||
const CHAR16 *dropin_dir,
|
||||
const CHAR16 *match_suffix,
|
||||
const CHAR8 *target_dir_prefix,
|
||||
UINT32 dir_mode,
|
||||
UINT32 access_mode,
|
||||
const UINT32 tpm_pcr[],
|
||||
const char16_t *dropin_dir,
|
||||
const char16_t *match_suffix,
|
||||
const char *target_dir_prefix,
|
||||
uint32_t dir_mode,
|
||||
uint32_t access_mode,
|
||||
const uint32_t tpm_pcr[],
|
||||
UINTN n_tpm_pcr,
|
||||
const CHAR16 *tpm_description,
|
||||
const char16_t *tpm_description,
|
||||
void **ret_buffer,
|
||||
UINTN *ret_buffer_size);
|
||||
|
||||
+13
-13
@@ -22,7 +22,7 @@ static EFI_STATUS devicetree_allocate(struct devicetree_state *state, UINTN size
|
||||
assert(state);
|
||||
|
||||
err = BS->AllocatePages(AllocateAnyPages, EfiACPIReclaimMemory, pages, &state->addr);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
state->pages = pages;
|
||||
@@ -42,7 +42,7 @@ static EFI_STATUS devicetree_fixup(struct devicetree_state *state, UINTN len) {
|
||||
assert(state);
|
||||
|
||||
err = BS->LocateProtocol(&EfiDtFixupProtocol, NULL, (void **) &fixup);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(EFI_SUCCESS,
|
||||
L"Could not locate device tree fixup protocol, skipping.");
|
||||
|
||||
@@ -55,12 +55,12 @@ static EFI_STATUS devicetree_fixup(struct devicetree_state *state, UINTN len) {
|
||||
void *oldptr = PHYSICAL_ADDRESS_TO_POINTER(state->addr);
|
||||
|
||||
err = devicetree_allocate(state, size);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
memcpy(PHYSICAL_ADDRESS_TO_POINTER(state->addr), oldptr, len);
|
||||
err = BS->FreePages(oldaddr, oldpages);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
size = devicetree_allocated(state);
|
||||
@@ -71,7 +71,7 @@ static EFI_STATUS devicetree_fixup(struct devicetree_state *state, UINTN len) {
|
||||
return err;
|
||||
}
|
||||
|
||||
EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE *root_dir, CHAR16 *name) {
|
||||
EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE *root_dir, char16_t *name) {
|
||||
_cleanup_(file_closep) EFI_FILE *handle = NULL;
|
||||
_cleanup_freepool_ EFI_FILE_INFO *info = NULL;
|
||||
UINTN len;
|
||||
@@ -86,11 +86,11 @@ EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE *root_dir
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
err = root_dir->Open(root_dir, &handle, name, EFI_FILE_MODE_READ, EFI_FILE_READ_ONLY);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = get_file_info_harder(handle, &info, NULL);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
if (info->FileSize < FDT_V1_SIZE || info->FileSize > 32 * 1024 * 1024)
|
||||
/* 32MB device tree blob doesn't seem right */
|
||||
@@ -99,15 +99,15 @@ EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE *root_dir
|
||||
len = info->FileSize;
|
||||
|
||||
err = devicetree_allocate(state, len);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = handle->Read(handle, &len, PHYSICAL_ADDRESS_TO_POINTER(state->addr));
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = devicetree_fixup(state, len);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
return BS->InstallConfigurationTable(&EfiDtbTableGuid, PHYSICAL_ADDRESS_TO_POINTER(state->addr));
|
||||
@@ -126,13 +126,13 @@ EFI_STATUS devicetree_install_from_memory(struct devicetree_state *state,
|
||||
return EFI_UNSUPPORTED;
|
||||
|
||||
err = devicetree_allocate(state, dtb_length);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
memcpy(PHYSICAL_ADDRESS_TO_POINTER(state->addr), dtb_buffer, dtb_length);
|
||||
|
||||
err = devicetree_fixup(state, dtb_length);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
return BS->InstallConfigurationTable(&EfiDtbTableGuid, PHYSICAL_ADDRESS_TO_POINTER(state->addr));
|
||||
@@ -146,7 +146,7 @@ void devicetree_cleanup(struct devicetree_state *state) {
|
||||
|
||||
err = BS->InstallConfigurationTable(&EfiDtbTableGuid, state->orig);
|
||||
/* don't free the current device tree if we can't reinstate the old one */
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return;
|
||||
|
||||
BS->FreePages(state->addr, state->pages);
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <efi.h>
|
||||
#include <uchar.h>
|
||||
|
||||
struct devicetree_state {
|
||||
EFI_PHYSICAL_ADDRESS addr;
|
||||
UINTN pages;
|
||||
void *orig;
|
||||
};
|
||||
|
||||
EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE *root_dir, CHAR16 *name);
|
||||
EFI_STATUS devicetree_install(struct devicetree_state *state, EFI_FILE *root_dir, char16_t *name);
|
||||
EFI_STATUS devicetree_install_from_memory(
|
||||
struct devicetree_state *state, const VOID *dtb_buffer, UINTN dtb_length);
|
||||
void devicetree_cleanup(struct devicetree_state *state);
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
#include "disk.h"
|
||||
#include "util.h"
|
||||
|
||||
EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, CHAR16 uuid[static 37]) {
|
||||
EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, char16_t uuid[static 37]) {
|
||||
EFI_STATUS err;
|
||||
EFI_DEVICE_PATH *dp;
|
||||
|
||||
|
||||
+2
-1
@@ -2,5 +2,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <efi.h>
|
||||
#include <uchar.h>
|
||||
|
||||
EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, CHAR16 uuid[static 37]);
|
||||
EFI_STATUS disk_get_part_uuid(EFI_HANDLE *handle, char16_t uuid[static 37]);
|
||||
|
||||
+12
-12
@@ -9,11 +9,11 @@
|
||||
static EFI_STATUS load_one_driver(
|
||||
EFI_HANDLE parent_image,
|
||||
EFI_LOADED_IMAGE *loaded_image,
|
||||
const CHAR16 *fname) {
|
||||
const char16_t *fname) {
|
||||
|
||||
_cleanup_(unload_imagep) EFI_HANDLE image = NULL;
|
||||
_cleanup_freepool_ EFI_DEVICE_PATH *path = NULL;
|
||||
_cleanup_freepool_ CHAR16 *spath = NULL;
|
||||
_cleanup_free_ char16_t *spath = NULL;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(parent_image);
|
||||
@@ -25,12 +25,12 @@ static EFI_STATUS load_one_driver(
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Error making file device path: %r", err);
|
||||
|
||||
err = BS->LoadImage(FALSE, parent_image, path, NULL, 0, &image);
|
||||
if (EFI_ERROR(err))
|
||||
err = BS->LoadImage(false, parent_image, path, NULL, 0, &image);
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to load image %s: %r", fname, err);
|
||||
|
||||
err = BS->HandleProtocol(image, &LoadedImageProtocol, (void **)&loaded_image);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to find protocol in driver image %s: %r", fname, err);
|
||||
|
||||
if (loaded_image->ImageCodeType != EfiBootServicesCode &&
|
||||
@@ -38,7 +38,7 @@ static EFI_STATUS load_one_driver(
|
||||
return log_error_status_stall(EFI_INVALID_PARAMETER, L"Image %s is not a driver, refusing.", fname);
|
||||
|
||||
err = BS->StartImage(image, NULL, NULL);
|
||||
if (EFI_ERROR(err)) {
|
||||
if (err != EFI_SUCCESS) {
|
||||
/* EFI_ABORTED signals an initializing driver. It uses this error code on success
|
||||
* so that it is unloaded after. */
|
||||
if (err != EFI_ABORTED)
|
||||
@@ -58,14 +58,14 @@ static EFI_STATUS reconnect(void) {
|
||||
/* Reconnects all handles, so that any loaded drivers can take effect. */
|
||||
|
||||
err = BS->LocateHandleBuffer(AllHandles, NULL, NULL, &n_handles, &handles);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to get list of handles: %r", err);
|
||||
|
||||
for (UINTN i = 0; i < n_handles; i++) {
|
||||
err = BS->ConnectController(handles[i], NULL, NULL, TRUE);
|
||||
err = BS->ConnectController(handles[i], NULL, NULL, true);
|
||||
if (err == EFI_NOT_FOUND) /* No drivers for this handle */
|
||||
continue;
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
log_error_status_stall(err, L"Failed to reconnect handle %" PRIuN L", ignoring: %r", i, err);
|
||||
}
|
||||
|
||||
@@ -88,12 +88,12 @@ EFI_STATUS load_drivers(
|
||||
&drivers_dir);
|
||||
if (err == EFI_NOT_FOUND)
|
||||
return EFI_SUCCESS;
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to open \\EFI\\systemd\\drivers: %r", err);
|
||||
|
||||
for (;;) {
|
||||
err = readdir_harder(drivers_dir, &dirent, &dirent_size);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to read extra directory of loaded image: %r", err);
|
||||
if (!dirent) /* End of directory */
|
||||
break;
|
||||
@@ -106,7 +106,7 @@ EFI_STATUS load_drivers(
|
||||
continue;
|
||||
|
||||
err = load_one_driver(parent_image, loaded_image, dirent->FileName);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
continue;
|
||||
|
||||
n_succeeded++;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "missing_efi.h"
|
||||
#include "util.h"
|
||||
|
||||
EFI_STATUS graphics_mode(BOOLEAN on) {
|
||||
EFI_STATUS graphics_mode(bool on) {
|
||||
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
|
||||
EFI_CONSOLE_CONTROL_SCREEN_MODE new;
|
||||
EFI_CONSOLE_CONTROL_SCREEN_MODE current;
|
||||
@@ -20,13 +20,13 @@ EFI_STATUS graphics_mode(BOOLEAN on) {
|
||||
EFI_STATUS err;
|
||||
|
||||
err = BS->LocateProtocol((EFI_GUID *) EFI_CONSOLE_CONTROL_GUID, NULL, (void **) &ConsoleControl);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
/* console control protocol is nonstandard and might not exist. */
|
||||
return err == EFI_NOT_FOUND ? EFI_SUCCESS : err;
|
||||
|
||||
/* check current mode */
|
||||
err =ConsoleControl->GetMode(ConsoleControl, ¤t, &uga_exists, &stdin_locked);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* do not touch the mode */
|
||||
@@ -37,7 +37,7 @@ EFI_STATUS graphics_mode(BOOLEAN on) {
|
||||
err =ConsoleControl->SetMode(ConsoleControl, new);
|
||||
|
||||
/* some firmware enables the cursor when switching modes */
|
||||
ST->ConOut->EnableCursor(ST->ConOut, FALSE);
|
||||
ST->ConOut->EnableCursor(ST->ConOut, false);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -6,5 +6,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <efi.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
EFI_STATUS graphics_mode(BOOLEAN on);
|
||||
EFI_STATUS graphics_mode(bool on);
|
||||
|
||||
@@ -102,7 +102,7 @@ EFI_STATUS initrd_register(
|
||||
&DevicePathProtocol, &efi_initrd_device_path,
|
||||
&EfiLoadFile2Protocol, loader,
|
||||
NULL);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
free(loader);
|
||||
|
||||
return err;
|
||||
@@ -119,7 +119,7 @@ EFI_STATUS initrd_unregister(EFI_HANDLE initrd_handle) {
|
||||
err = BS->OpenProtocol(
|
||||
initrd_handle, &EfiLoadFile2Protocol, (void **) &loader,
|
||||
NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* close the handle */
|
||||
@@ -131,7 +131,7 @@ EFI_STATUS initrd_unregister(EFI_HANDLE initrd_handle) {
|
||||
&DevicePathProtocol, &efi_initrd_device_path,
|
||||
&EfiLoadFile2Protocol, loader,
|
||||
NULL);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
initrd_handle = NULL;
|
||||
|
||||
+12
-12
@@ -24,7 +24,7 @@ static EFI_LOADED_IMAGE * loaded_image_free(EFI_LOADED_IMAGE *img) {
|
||||
}
|
||||
|
||||
static EFI_STATUS loaded_image_register(
|
||||
const CHAR8 *cmdline, UINTN cmdline_len,
|
||||
const char *cmdline, UINTN cmdline_len,
|
||||
const void *linux_buffer, UINTN linux_length,
|
||||
EFI_HANDLE *ret_image) {
|
||||
|
||||
@@ -53,7 +53,7 @@ static EFI_STATUS loaded_image_register(
|
||||
ret_image,
|
||||
&LoadedImageProtocol, loaded_image,
|
||||
NULL);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
loaded_image = loaded_image_free(loaded_image);
|
||||
|
||||
return err;
|
||||
@@ -70,7 +70,7 @@ static EFI_STATUS loaded_image_unregister(EFI_HANDLE loaded_image_handle) {
|
||||
err = BS->OpenProtocol(
|
||||
loaded_image_handle, &LoadedImageProtocol, (void **) &loaded_image,
|
||||
NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* close the handle */
|
||||
@@ -79,7 +79,7 @@ static EFI_STATUS loaded_image_unregister(EFI_HANDLE loaded_image_handle) {
|
||||
loaded_image_handle,
|
||||
&LoadedImageProtocol, loaded_image,
|
||||
NULL);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
loaded_image_handle = NULL;
|
||||
loaded_image = loaded_image_free(loaded_image);
|
||||
@@ -106,13 +106,13 @@ static inline void cleanup_pages(struct pages *p) {
|
||||
|
||||
EFI_STATUS linux_exec(
|
||||
EFI_HANDLE image,
|
||||
const CHAR8 *cmdline, UINTN cmdline_len,
|
||||
const char *cmdline, UINTN cmdline_len,
|
||||
const void *linux_buffer, UINTN linux_length,
|
||||
const void *initrd_buffer, UINTN initrd_length) {
|
||||
|
||||
_cleanup_(cleanup_initrd) EFI_HANDLE initrd_handle = NULL;
|
||||
_cleanup_(cleanup_loaded_image) EFI_HANDLE loaded_image_handle = NULL;
|
||||
UINT32 kernel_alignment, kernel_size_of_image, kernel_entry_address;
|
||||
uint32_t kernel_alignment, kernel_size_of_image, kernel_entry_address;
|
||||
EFI_IMAGE_ENTRY_POINT kernel_entry;
|
||||
_cleanup_(cleanup_pages) struct pages kernel = {};
|
||||
void *new_buffer;
|
||||
@@ -125,7 +125,7 @@ EFI_STATUS linux_exec(
|
||||
|
||||
/* get the necessary fields from the PE header */
|
||||
err = pe_alignment_info(linux_buffer, &kernel_entry_address, &kernel_size_of_image, &kernel_alignment);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
/* sanity check */
|
||||
assert(kernel_size_of_image >= linux_length);
|
||||
@@ -142,24 +142,24 @@ EFI_STATUS linux_exec(
|
||||
/* allocate SizeOfImage + SectionAlignment because the new_buffer can move up to Alignment-1 bytes */
|
||||
kernel.num = EFI_SIZE_TO_PAGES(ALIGN_TO(kernel_size_of_image, kernel_alignment) + kernel_alignment);
|
||||
err = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, kernel.num, &kernel.addr);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
new_buffer = PHYSICAL_ADDRESS_TO_POINTER(ALIGN_TO(kernel.addr, kernel_alignment));
|
||||
memcpy(new_buffer, linux_buffer, linux_length);
|
||||
/* zero out rest of memory (probably not needed, but BSS section should be 0) */
|
||||
memset((UINT8 *)new_buffer + linux_length, 0, kernel_size_of_image - linux_length);
|
||||
memset((uint8_t *)new_buffer + linux_length, 0, kernel_size_of_image - linux_length);
|
||||
|
||||
/* get the entry point inside the relocated kernel */
|
||||
kernel_entry = (EFI_IMAGE_ENTRY_POINT) ((const UINT8 *)new_buffer + kernel_entry_address);
|
||||
kernel_entry = (EFI_IMAGE_ENTRY_POINT) ((const uint8_t *)new_buffer + kernel_entry_address);
|
||||
|
||||
/* register a LoadedImage Protocol in order to pass on the commandline */
|
||||
err = loaded_image_register(cmdline, cmdline_len, new_buffer, linux_length, &loaded_image_handle);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* register a LINUX_INITRD_MEDIA DevicePath to serve the initrd */
|
||||
err = initrd_register(initrd_buffer, initrd_length, &initrd_handle);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* call the kernel */
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
|
||||
EFI_STATUS linux_exec(
|
||||
EFI_HANDLE image,
|
||||
const CHAR8 *cmdline, UINTN cmdline_len,
|
||||
const char *cmdline, UINTN cmdline_len,
|
||||
const void *linux_buffer, UINTN linux_length,
|
||||
const void *initrd_buffer, UINTN initrd_length);
|
||||
|
||||
+80
-80
@@ -21,81 +21,81 @@
|
||||
#define SETUP_MAGIC 0x53726448 /* "HdrS" */
|
||||
|
||||
struct setup_header {
|
||||
UINT8 setup_sects;
|
||||
UINT16 root_flags;
|
||||
UINT32 syssize;
|
||||
UINT16 ram_size;
|
||||
UINT16 vid_mode;
|
||||
UINT16 root_dev;
|
||||
UINT16 boot_flag;
|
||||
UINT16 jump;
|
||||
UINT32 header;
|
||||
UINT16 version;
|
||||
UINT32 realmode_swtch;
|
||||
UINT16 start_sys_seg;
|
||||
UINT16 kernel_version;
|
||||
UINT8 type_of_loader;
|
||||
UINT8 loadflags;
|
||||
UINT16 setup_move_size;
|
||||
UINT32 code32_start;
|
||||
UINT32 ramdisk_image;
|
||||
UINT32 ramdisk_size;
|
||||
UINT32 bootsect_kludge;
|
||||
UINT16 heap_end_ptr;
|
||||
UINT8 ext_loader_ver;
|
||||
UINT8 ext_loader_type;
|
||||
UINT32 cmd_line_ptr;
|
||||
UINT32 initrd_addr_max;
|
||||
UINT32 kernel_alignment;
|
||||
UINT8 relocatable_kernel;
|
||||
UINT8 min_alignment;
|
||||
UINT16 xloadflags;
|
||||
UINT32 cmdline_size;
|
||||
UINT32 hardware_subarch;
|
||||
UINT64 hardware_subarch_data;
|
||||
UINT32 payload_offset;
|
||||
UINT32 payload_length;
|
||||
UINT64 setup_data;
|
||||
UINT64 pref_address;
|
||||
UINT32 init_size;
|
||||
UINT32 handover_offset;
|
||||
uint8_t setup_sects;
|
||||
uint16_t root_flags;
|
||||
uint32_t syssize;
|
||||
uint16_t ram_size;
|
||||
uint16_t vid_mode;
|
||||
uint16_t root_dev;
|
||||
uint16_t boot_flag;
|
||||
uint16_t jump;
|
||||
uint32_t header;
|
||||
uint16_t version;
|
||||
uint32_t realmode_swtch;
|
||||
uint16_t start_sys_seg;
|
||||
uint16_t kernel_version;
|
||||
uint8_t type_of_loader;
|
||||
uint8_t loadflags;
|
||||
uint16_t setup_move_size;
|
||||
uint32_t code32_start;
|
||||
uint32_t ramdisk_image;
|
||||
uint32_t ramdisk_size;
|
||||
uint32_t bootsect_kludge;
|
||||
uint16_t heap_end_ptr;
|
||||
uint8_t ext_loader_ver;
|
||||
uint8_t ext_loader_type;
|
||||
uint32_t cmd_line_ptr;
|
||||
uint32_t initrd_addr_max;
|
||||
uint32_t kernel_alignment;
|
||||
uint8_t relocatable_kernel;
|
||||
uint8_t min_alignment;
|
||||
uint16_t xloadflags;
|
||||
uint32_t cmdline_size;
|
||||
uint32_t hardware_subarch;
|
||||
uint64_t hardware_subarch_data;
|
||||
uint32_t payload_offset;
|
||||
uint32_t payload_length;
|
||||
uint64_t setup_data;
|
||||
uint64_t pref_address;
|
||||
uint32_t init_size;
|
||||
uint32_t handover_offset;
|
||||
} _packed_;
|
||||
|
||||
/* adapted from linux' bootparam.h */
|
||||
struct boot_params {
|
||||
UINT8 screen_info[64]; // was: struct screen_info
|
||||
UINT8 apm_bios_info[20]; // was: struct apm_bios_info
|
||||
UINT8 _pad2[4];
|
||||
UINT64 tboot_addr;
|
||||
UINT8 ist_info[16]; // was: struct ist_info
|
||||
UINT8 _pad3[16];
|
||||
UINT8 hd0_info[16];
|
||||
UINT8 hd1_info[16];
|
||||
UINT8 sys_desc_table[16]; // was: struct sys_desc_table
|
||||
UINT8 olpc_ofw_header[16]; // was: struct olpc_ofw_header
|
||||
UINT32 ext_ramdisk_image;
|
||||
UINT32 ext_ramdisk_size;
|
||||
UINT32 ext_cmd_line_ptr;
|
||||
UINT8 _pad4[116];
|
||||
UINT8 edid_info[128]; // was: struct edid_info
|
||||
UINT8 efi_info[32]; // was: struct efi_info
|
||||
UINT32 alt_mem_k;
|
||||
UINT32 scratch;
|
||||
UINT8 e820_entries;
|
||||
UINT8 eddbuf_entries;
|
||||
UINT8 edd_mbr_sig_buf_entries;
|
||||
UINT8 kbd_status;
|
||||
UINT8 secure_boot;
|
||||
UINT8 _pad5[2];
|
||||
UINT8 sentinel;
|
||||
UINT8 _pad6[1];
|
||||
uint8_t screen_info[64]; // was: struct screen_info
|
||||
uint8_t apm_bios_info[20]; // was: struct apm_bios_info
|
||||
uint8_t _pad2[4];
|
||||
uint64_t tboot_addr;
|
||||
uint8_t ist_info[16]; // was: struct ist_info
|
||||
uint8_t _pad3[16];
|
||||
uint8_t hd0_info[16];
|
||||
uint8_t hd1_info[16];
|
||||
uint8_t sys_desc_table[16]; // was: struct sys_desc_table
|
||||
uint8_t olpc_ofw_header[16]; // was: struct olpc_ofw_header
|
||||
uint32_t ext_ramdisk_image;
|
||||
uint32_t ext_ramdisk_size;
|
||||
uint32_t ext_cmd_line_ptr;
|
||||
uint8_t _pad4[116];
|
||||
uint8_t edid_info[128]; // was: struct edid_info
|
||||
uint8_t efi_info[32]; // was: struct efi_info
|
||||
uint32_t alt_mem_k;
|
||||
uint32_t scratch;
|
||||
uint8_t e820_entries;
|
||||
uint8_t eddbuf_entries;
|
||||
uint8_t edd_mbr_sig_buf_entries;
|
||||
uint8_t kbd_status;
|
||||
uint8_t secure_boot;
|
||||
uint8_t _pad5[2];
|
||||
uint8_t sentinel;
|
||||
uint8_t _pad6[1];
|
||||
struct setup_header hdr;
|
||||
UINT8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
|
||||
UINT32 edd_mbr_sig_buffer[16]; // was: edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]
|
||||
UINT8 e820_table[20*128]; // was: struct boot_e820_entry e820_table[E820_MAX_ENTRIES_ZEROPAGE]
|
||||
UINT8 _pad8[48];
|
||||
UINT8 eddbuf[6*82]; // was: struct edd_info eddbuf[EDDMAXNR]
|
||||
UINT8 _pad9[276];
|
||||
uint8_t _pad7[0x290-0x1f1-sizeof(struct setup_header)];
|
||||
uint32_t edd_mbr_sig_buffer[16]; // was: edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]
|
||||
uint8_t e820_table[20*128]; // was: struct boot_e820_entry e820_table[E820_MAX_ENTRIES_ZEROPAGE]
|
||||
uint8_t _pad8[48];
|
||||
uint8_t eddbuf[6*82]; // was: struct edd_info eddbuf[EDDMAXNR]
|
||||
uint8_t _pad9[276];
|
||||
} _packed_;
|
||||
|
||||
#ifdef __i386__
|
||||
@@ -122,7 +122,7 @@ static void linux_efi_handover(EFI_HANDLE image, struct boot_params *params) {
|
||||
|
||||
EFI_STATUS linux_exec(
|
||||
EFI_HANDLE image,
|
||||
const CHAR8 *cmdline, UINTN cmdline_len,
|
||||
const char *cmdline, UINTN cmdline_len,
|
||||
const void *linux_buffer, UINTN linux_length,
|
||||
const void *initrd_buffer, UINTN initrd_length) {
|
||||
|
||||
@@ -130,7 +130,7 @@ EFI_STATUS linux_exec(
|
||||
struct boot_params *boot_params;
|
||||
EFI_HANDLE initrd_handle = NULL;
|
||||
EFI_PHYSICAL_ADDRESS addr;
|
||||
UINT8 setup_sectors;
|
||||
uint8_t setup_sectors;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(image);
|
||||
@@ -155,7 +155,7 @@ EFI_STATUS linux_exec(
|
||||
EfiLoaderData,
|
||||
EFI_SIZE_TO_PAGES(0x4000),
|
||||
&addr);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
boot_params = (struct boot_params *) PHYSICAL_ADDRESS_TO_POINTER(addr);
|
||||
@@ -163,7 +163,7 @@ EFI_STATUS linux_exec(
|
||||
boot_params->hdr = image_params->hdr;
|
||||
boot_params->hdr.type_of_loader = 0xff;
|
||||
setup_sectors = image_params->hdr.setup_sects > 0 ? image_params->hdr.setup_sects : 4;
|
||||
boot_params->hdr.code32_start = (UINT32) POINTER_TO_PHYSICAL_ADDRESS(linux_buffer) + (setup_sectors + 1) * 512;
|
||||
boot_params->hdr.code32_start = (uint32_t) POINTER_TO_PHYSICAL_ADDRESS(linux_buffer) + (setup_sectors + 1) * 512;
|
||||
|
||||
if (cmdline) {
|
||||
addr = 0xA0000;
|
||||
@@ -173,12 +173,12 @@ EFI_STATUS linux_exec(
|
||||
EfiLoaderData,
|
||||
EFI_SIZE_TO_PAGES(cmdline_len + 1),
|
||||
&addr);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
memcpy(PHYSICAL_ADDRESS_TO_POINTER(addr), cmdline, cmdline_len);
|
||||
((CHAR8 *) PHYSICAL_ADDRESS_TO_POINTER(addr))[cmdline_len] = 0;
|
||||
boot_params->hdr.cmd_line_ptr = (UINT32) addr;
|
||||
((char *) PHYSICAL_ADDRESS_TO_POINTER(addr))[cmdline_len] = 0;
|
||||
boot_params->hdr.cmd_line_ptr = (uint32_t) addr;
|
||||
}
|
||||
|
||||
/* Providing the initrd via LINUX_INITRD_MEDIA_GUID is only supported by Linux 5.8+ (5.7+ on ARM64).
|
||||
@@ -187,12 +187,12 @@ EFI_STATUS linux_exec(
|
||||
If you need to know which protocol was used by the kernel, pass "efi=debug" to the kernel,
|
||||
this will print a line when InitrdMediaGuid was successfully used to load the initrd.
|
||||
*/
|
||||
boot_params->hdr.ramdisk_image = (UINT32) POINTER_TO_PHYSICAL_ADDRESS(initrd_buffer);
|
||||
boot_params->hdr.ramdisk_size = (UINT32) initrd_length;
|
||||
boot_params->hdr.ramdisk_image = (uint32_t) POINTER_TO_PHYSICAL_ADDRESS(initrd_buffer);
|
||||
boot_params->hdr.ramdisk_size = (uint32_t) initrd_length;
|
||||
|
||||
/* register LINUX_INITRD_MEDIA_GUID */
|
||||
err = initrd_register(initrd_buffer, initrd_length, &initrd_handle);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
linux_efi_handover(image, boot_params);
|
||||
(void) initrd_unregister(initrd_handle);
|
||||
|
||||
+22
-22
@@ -12,14 +12,14 @@
|
||||
|
||||
static EFI_STATUS tpm1_measure_to_pcr_and_event_log(
|
||||
const EFI_TCG *tcg,
|
||||
UINT32 pcrindex,
|
||||
uint32_t pcrindex,
|
||||
EFI_PHYSICAL_ADDRESS buffer,
|
||||
UINTN buffer_size,
|
||||
const CHAR16 *description) {
|
||||
const char16_t *description) {
|
||||
|
||||
_cleanup_freepool_ TCG_PCR_EVENT *tcg_event = NULL;
|
||||
EFI_PHYSICAL_ADDRESS event_log_last;
|
||||
UINT32 event_number = 1;
|
||||
uint32_t event_number = 1;
|
||||
UINTN desc_len;
|
||||
|
||||
assert(tcg);
|
||||
@@ -46,10 +46,10 @@ static EFI_STATUS tpm1_measure_to_pcr_and_event_log(
|
||||
|
||||
static EFI_STATUS tpm2_measure_to_pcr_and_event_log(
|
||||
EFI_TCG2 *tcg,
|
||||
UINT32 pcrindex,
|
||||
uint32_t pcrindex,
|
||||
EFI_PHYSICAL_ADDRESS buffer,
|
||||
UINT64 buffer_size,
|
||||
const CHAR16 *description) {
|
||||
uint64_t buffer_size,
|
||||
const char16_t *description) {
|
||||
|
||||
_cleanup_freepool_ EFI_TCG2_EVENT *tcg_event = NULL;
|
||||
UINTN desc_len;
|
||||
@@ -82,21 +82,21 @@ static EFI_TCG *tcg1_interface_check(void) {
|
||||
TCG_BOOT_SERVICE_CAPABILITY capability = {
|
||||
.Size = sizeof(capability),
|
||||
};
|
||||
EFI_STATUS status;
|
||||
UINT32 features;
|
||||
EFI_STATUS err;
|
||||
uint32_t features;
|
||||
EFI_TCG *tcg;
|
||||
|
||||
status = BS->LocateProtocol((EFI_GUID *) EFI_TCG_GUID, NULL, (void **) &tcg);
|
||||
if (EFI_ERROR(status))
|
||||
err = BS->LocateProtocol((EFI_GUID *) EFI_TCG_GUID, NULL, (void **) &tcg);
|
||||
if (err != EFI_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
status = tcg->StatusCheck(
|
||||
err = tcg->StatusCheck(
|
||||
tcg,
|
||||
&capability,
|
||||
&features,
|
||||
&event_log_location,
|
||||
&event_log_last_entry);
|
||||
if (EFI_ERROR(status))
|
||||
if (err != EFI_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
if (capability.TPMDeactivatedFlag)
|
||||
@@ -112,15 +112,15 @@ static EFI_TCG2 * tcg2_interface_check(void) {
|
||||
EFI_TCG2_BOOT_SERVICE_CAPABILITY capability = {
|
||||
.Size = sizeof(capability),
|
||||
};
|
||||
EFI_STATUS status;
|
||||
EFI_STATUS err;
|
||||
EFI_TCG2 *tcg;
|
||||
|
||||
status = BS->LocateProtocol((EFI_GUID *) EFI_TCG2_GUID, NULL, (void **) &tcg);
|
||||
if (EFI_ERROR(status))
|
||||
err = BS->LocateProtocol((EFI_GUID *) EFI_TCG2_GUID, NULL, (void **) &tcg);
|
||||
if (err != EFI_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
status = tcg->GetCapability(tcg, &capability);
|
||||
if (EFI_ERROR(status))
|
||||
err = tcg->GetCapability(tcg, &capability);
|
||||
if (err != EFI_SUCCESS)
|
||||
return NULL;
|
||||
|
||||
if (capability.StructureVersion.Major == 1 &&
|
||||
@@ -137,11 +137,11 @@ static EFI_TCG2 * tcg2_interface_check(void) {
|
||||
return tcg;
|
||||
}
|
||||
|
||||
BOOLEAN tpm_present(void) {
|
||||
bool tpm_present(void) {
|
||||
return tcg2_interface_check() || tcg1_interface_check();
|
||||
}
|
||||
|
||||
EFI_STATUS tpm_log_event(UINT32 pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const CHAR16 *description) {
|
||||
EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const char16_t *description) {
|
||||
EFI_TCG *tpm1;
|
||||
EFI_TCG2 *tpm2;
|
||||
|
||||
@@ -163,18 +163,18 @@ EFI_STATUS tpm_log_event(UINT32 pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buf
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS tpm_log_load_options(const CHAR16 *load_options) {
|
||||
EFI_STATUS tpm_log_load_options(const char16_t *load_options) {
|
||||
EFI_STATUS err;
|
||||
|
||||
/* Measures a load options string into the TPM2, i.e. the kernel command line */
|
||||
|
||||
for (UINTN i = 0; i < 2; i++) {
|
||||
UINT32 pcr = i == 0 ? TPM_PCR_INDEX_KERNEL_PARAMETERS : TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT;
|
||||
uint32_t pcr = i == 0 ? TPM_PCR_INDEX_KERNEL_PARAMETERS : TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT;
|
||||
|
||||
err = tpm_log_event(pcr,
|
||||
POINTER_TO_PHYSICAL_ADDRESS(load_options),
|
||||
strsize16(load_options), load_options);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Unable to add load options (i.e. kernel command) line measurement to PCR %u: %r", pcr, err);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <efi.h>
|
||||
#include <stdbool.h>
|
||||
#include <uchar.h>
|
||||
|
||||
/* This TPM PCR is where we extend the kernel command line and any passed credentials here. */
|
||||
#define TPM_PCR_INDEX_KERNEL_PARAMETERS 12U
|
||||
@@ -19,21 +21,21 @@
|
||||
|
||||
#if ENABLE_TPM
|
||||
|
||||
BOOLEAN tpm_present(void);
|
||||
EFI_STATUS tpm_log_event(UINT32 pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const CHAR16 *description);
|
||||
EFI_STATUS tpm_log_load_options(const CHAR16 *cmdline);
|
||||
bool tpm_present(void);
|
||||
EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const char16_t *description);
|
||||
EFI_STATUS tpm_log_load_options(const char16_t *cmdline);
|
||||
|
||||
#else
|
||||
|
||||
static inline BOOLEAN tpm_present(void) {
|
||||
return FALSE;
|
||||
static inline bool tpm_present(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline EFI_STATUS tpm_log_event(UINT32 pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const CHAR16 *description) {
|
||||
static inline EFI_STATUS tpm_log_event(uint32_t pcrindex, EFI_PHYSICAL_ADDRESS buffer, UINTN buffer_size, const char16_t *description) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static inline EFI_STATUS tpm_log_load_options(const CHAR16 *cmdline) {
|
||||
static inline EFI_STATUS tpm_log_load_options(const char16_t *cmdline) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
+93
-93
@@ -31,98 +31,98 @@
|
||||
#endif
|
||||
|
||||
struct DosFileHeader {
|
||||
UINT8 Magic[2];
|
||||
UINT16 LastSize;
|
||||
UINT16 nBlocks;
|
||||
UINT16 nReloc;
|
||||
UINT16 HdrSize;
|
||||
UINT16 MinAlloc;
|
||||
UINT16 MaxAlloc;
|
||||
UINT16 ss;
|
||||
UINT16 sp;
|
||||
UINT16 Checksum;
|
||||
UINT16 ip;
|
||||
UINT16 cs;
|
||||
UINT16 RelocPos;
|
||||
UINT16 nOverlay;
|
||||
UINT16 reserved[4];
|
||||
UINT16 OEMId;
|
||||
UINT16 OEMInfo;
|
||||
UINT16 reserved2[10];
|
||||
UINT32 ExeHeader;
|
||||
uint8_t Magic[2];
|
||||
uint16_t LastSize;
|
||||
uint16_t nBlocks;
|
||||
uint16_t nReloc;
|
||||
uint16_t HdrSize;
|
||||
uint16_t MinAlloc;
|
||||
uint16_t MaxAlloc;
|
||||
uint16_t ss;
|
||||
uint16_t sp;
|
||||
uint16_t Checksum;
|
||||
uint16_t ip;
|
||||
uint16_t cs;
|
||||
uint16_t RelocPos;
|
||||
uint16_t nOverlay;
|
||||
uint16_t reserved[4];
|
||||
uint16_t OEMId;
|
||||
uint16_t OEMInfo;
|
||||
uint16_t reserved2[10];
|
||||
uint32_t ExeHeader;
|
||||
} _packed_;
|
||||
|
||||
struct CoffFileHeader {
|
||||
UINT16 Machine;
|
||||
UINT16 NumberOfSections;
|
||||
UINT32 TimeDateStamp;
|
||||
UINT32 PointerToSymbolTable;
|
||||
UINT32 NumberOfSymbols;
|
||||
UINT16 SizeOfOptionalHeader;
|
||||
UINT16 Characteristics;
|
||||
uint16_t Machine;
|
||||
uint16_t NumberOfSections;
|
||||
uint32_t TimeDateStamp;
|
||||
uint32_t PointerToSymbolTable;
|
||||
uint32_t NumberOfSymbols;
|
||||
uint16_t SizeOfOptionalHeader;
|
||||
uint16_t Characteristics;
|
||||
} _packed_;
|
||||
|
||||
#define OPTHDR32_MAGIC 0x10B /* PE32 OptionalHeader */
|
||||
#define OPTHDR64_MAGIC 0x20B /* PE32+ OptionalHeader */
|
||||
|
||||
struct PeOptionalHeader {
|
||||
UINT16 Magic;
|
||||
UINT8 LinkerMajor;
|
||||
UINT8 LinkerMinor;
|
||||
UINT32 SizeOfCode;
|
||||
UINT32 SizeOfInitializedData;
|
||||
UINT32 SizeOfUninitializeData;
|
||||
UINT32 AddressOfEntryPoint;
|
||||
UINT32 BaseOfCode;
|
||||
uint16_t Magic;
|
||||
uint8_t LinkerMajor;
|
||||
uint8_t LinkerMinor;
|
||||
uint32_t SizeOfCode;
|
||||
uint32_t SizeOfInitializedData;
|
||||
uint32_t SizeOfUninitializeData;
|
||||
uint32_t AddressOfEntryPoint;
|
||||
uint32_t BaseOfCode;
|
||||
union {
|
||||
struct { /* PE32 */
|
||||
UINT32 BaseOfData;
|
||||
UINT32 ImageBase32;
|
||||
uint32_t BaseOfData;
|
||||
uint32_t ImageBase32;
|
||||
};
|
||||
UINT64 ImageBase64; /* PE32+ */
|
||||
uint64_t ImageBase64; /* PE32+ */
|
||||
};
|
||||
UINT32 SectionAlignment;
|
||||
UINT32 FileAlignment;
|
||||
UINT16 MajorOperatingSystemVersion;
|
||||
UINT16 MinorOperatingSystemVersion;
|
||||
UINT16 MajorImageVersion;
|
||||
UINT16 MinorImageVersion;
|
||||
UINT16 MajorSubsystemVersion;
|
||||
UINT16 MinorSubsystemVersion;
|
||||
UINT32 Win32VersionValue;
|
||||
UINT32 SizeOfImage;
|
||||
UINT32 SizeOfHeaders;
|
||||
UINT32 CheckSum;
|
||||
UINT16 Subsystem;
|
||||
UINT16 DllCharacteristics;
|
||||
uint32_t SectionAlignment;
|
||||
uint32_t FileAlignment;
|
||||
uint16_t MajorOperatingSystemVersion;
|
||||
uint16_t MinorOperatingSystemVersion;
|
||||
uint16_t MajorImageVersion;
|
||||
uint16_t MinorImageVersion;
|
||||
uint16_t MajorSubsystemVersion;
|
||||
uint16_t MinorSubsystemVersion;
|
||||
uint32_t Win32VersionValue;
|
||||
uint32_t SizeOfImage;
|
||||
uint32_t SizeOfHeaders;
|
||||
uint32_t CheckSum;
|
||||
uint16_t Subsystem;
|
||||
uint16_t DllCharacteristics;
|
||||
/* fields with different sizes for 32/64 omitted */
|
||||
} _packed_;
|
||||
|
||||
struct PeFileHeader {
|
||||
UINT8 Magic[4];
|
||||
uint8_t Magic[4];
|
||||
struct CoffFileHeader FileHeader;
|
||||
struct PeOptionalHeader OptionalHeader;
|
||||
} _packed_;
|
||||
|
||||
struct PeSectionHeader {
|
||||
UINT8 Name[8];
|
||||
UINT32 VirtualSize;
|
||||
UINT32 VirtualAddress;
|
||||
UINT32 SizeOfRawData;
|
||||
UINT32 PointerToRawData;
|
||||
UINT32 PointerToRelocations;
|
||||
UINT32 PointerToLinenumbers;
|
||||
UINT16 NumberOfRelocations;
|
||||
UINT16 NumberOfLinenumbers;
|
||||
UINT32 Characteristics;
|
||||
uint8_t Name[8];
|
||||
uint32_t VirtualSize;
|
||||
uint32_t VirtualAddress;
|
||||
uint32_t SizeOfRawData;
|
||||
uint32_t PointerToRawData;
|
||||
uint32_t PointerToRelocations;
|
||||
uint32_t PointerToLinenumbers;
|
||||
uint16_t NumberOfRelocations;
|
||||
uint16_t NumberOfLinenumbers;
|
||||
uint32_t Characteristics;
|
||||
} _packed_;
|
||||
|
||||
static inline BOOLEAN verify_dos(const struct DosFileHeader *dos) {
|
||||
static inline bool verify_dos(const struct DosFileHeader *dos) {
|
||||
assert(dos);
|
||||
return memcmp(dos->Magic, DOS_FILE_MAGIC, STRLEN(DOS_FILE_MAGIC)) == 0;
|
||||
}
|
||||
|
||||
static inline BOOLEAN verify_pe(const struct PeFileHeader *pe, BOOLEAN allow_compatibility) {
|
||||
static inline bool verify_pe(const struct PeFileHeader *pe, bool allow_compatibility) {
|
||||
assert(pe);
|
||||
return memcmp(pe->Magic, PE_FILE_MAGIC, STRLEN(PE_FILE_MAGIC)) == 0 &&
|
||||
(pe->FileHeader.Machine == TARGET_MACHINE_TYPE ||
|
||||
@@ -141,7 +141,7 @@ static inline UINTN section_table_offset(const struct DosFileHeader *dos, const
|
||||
static void locate_sections(
|
||||
const struct PeSectionHeader section_table[],
|
||||
UINTN n_table,
|
||||
const CHAR8 **sections,
|
||||
const char **sections,
|
||||
UINTN *addrs,
|
||||
UINTN *offsets,
|
||||
UINTN *sizes) {
|
||||
@@ -154,7 +154,7 @@ static void locate_sections(
|
||||
const struct PeSectionHeader *sect = section_table + i;
|
||||
|
||||
for (UINTN j = 0; sections[j]; j++) {
|
||||
if (memcmp(sect->Name, sections[j], strlen8((const char *) sections[j])) != 0)
|
||||
if (memcmp(sect->Name, sections[j], strlen8(sections[j])) != 0)
|
||||
continue;
|
||||
|
||||
if (addrs)
|
||||
@@ -166,15 +166,15 @@ static void locate_sections(
|
||||
}
|
||||
}
|
||||
|
||||
static UINT32 get_compatibility_entry_address(const struct DosFileHeader *dos, const struct PeFileHeader *pe) {
|
||||
static uint32_t get_compatibility_entry_address(const struct DosFileHeader *dos, const struct PeFileHeader *pe) {
|
||||
UINTN addr = 0, size = 0;
|
||||
static const CHAR8 *sections[] = { (CHAR8 *) ".compat", NULL };
|
||||
static const char *sections[] = { ".compat", NULL };
|
||||
|
||||
/* The kernel may provide alternative PE entry points for different PE architectures. This allows
|
||||
* booting a 64bit kernel on 32bit EFI that is otherwise running on a 64bit CPU. The locations of any
|
||||
* such compat entry points are located in a special PE section. */
|
||||
|
||||
locate_sections((const struct PeSectionHeader *) ((const UINT8 *) dos + section_table_offset(dos, pe)),
|
||||
locate_sections((const struct PeSectionHeader *) ((const uint8_t *) dos + section_table_offset(dos, pe)),
|
||||
pe->FileHeader.NumberOfSections,
|
||||
sections,
|
||||
&addr,
|
||||
@@ -185,14 +185,14 @@ static UINT32 get_compatibility_entry_address(const struct DosFileHeader *dos, c
|
||||
return 0;
|
||||
|
||||
typedef struct {
|
||||
UINT8 type;
|
||||
UINT8 size;
|
||||
UINT16 machine_type;
|
||||
UINT32 entry_point;
|
||||
uint8_t type;
|
||||
uint8_t size;
|
||||
uint16_t machine_type;
|
||||
uint32_t entry_point;
|
||||
} _packed_ LinuxPeCompat1;
|
||||
|
||||
while (size >= sizeof(LinuxPeCompat1) && addr % __alignof__(LinuxPeCompat1) == 0) {
|
||||
LinuxPeCompat1 *compat = (LinuxPeCompat1 *) ((UINT8 *) dos + addr);
|
||||
LinuxPeCompat1 *compat = (LinuxPeCompat1 *) ((uint8_t *) dos + addr);
|
||||
|
||||
if (compat->type == 0 || compat->size == 0 || compat->size > size)
|
||||
break;
|
||||
@@ -211,9 +211,9 @@ static UINT32 get_compatibility_entry_address(const struct DosFileHeader *dos, c
|
||||
|
||||
EFI_STATUS pe_alignment_info(
|
||||
const void *base,
|
||||
UINT32 *ret_entry_point_address,
|
||||
UINT32 *ret_size_of_image,
|
||||
UINT32 *ret_section_alignment) {
|
||||
uint32_t *ret_entry_point_address,
|
||||
uint32_t *ret_size_of_image,
|
||||
uint32_t *ret_section_alignment) {
|
||||
|
||||
const struct DosFileHeader *dos;
|
||||
const struct PeFileHeader *pe;
|
||||
@@ -225,11 +225,11 @@ EFI_STATUS pe_alignment_info(
|
||||
if (!verify_dos(dos))
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
pe = (const struct PeFileHeader*) ((const UINT8 *)base + dos->ExeHeader);
|
||||
if (!verify_pe(pe, /* allow_compatibility= */ TRUE))
|
||||
pe = (const struct PeFileHeader*) ((const uint8_t *)base + dos->ExeHeader);
|
||||
if (!verify_pe(pe, /* allow_compatibility= */ true))
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
UINT32 entry_address = pe->OptionalHeader.AddressOfEntryPoint;
|
||||
uint32_t entry_address = pe->OptionalHeader.AddressOfEntryPoint;
|
||||
|
||||
/* Look for a compat entry point. */
|
||||
if (pe->FileHeader.Machine != TARGET_MACHINE_TYPE) {
|
||||
@@ -248,8 +248,8 @@ EFI_STATUS pe_alignment_info(
|
||||
}
|
||||
|
||||
EFI_STATUS pe_memory_locate_sections(
|
||||
const CHAR8 *base,
|
||||
const CHAR8 **sections,
|
||||
const char *base,
|
||||
const char **sections,
|
||||
UINTN *addrs,
|
||||
UINTN *sizes) {
|
||||
const struct DosFileHeader *dos;
|
||||
@@ -266,7 +266,7 @@ EFI_STATUS pe_memory_locate_sections(
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
pe = (const struct PeFileHeader*)&base[dos->ExeHeader];
|
||||
if (!verify_pe(pe, /* allow_compatibility= */ FALSE))
|
||||
if (!verify_pe(pe, /* allow_compatibility= */ false))
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
offset = section_table_offset(dos, pe);
|
||||
@@ -278,8 +278,8 @@ EFI_STATUS pe_memory_locate_sections(
|
||||
|
||||
EFI_STATUS pe_file_locate_sections(
|
||||
EFI_FILE *dir,
|
||||
const CHAR16 *path,
|
||||
const CHAR8 **sections,
|
||||
const char16_t *path,
|
||||
const char **sections,
|
||||
UINTN *offsets,
|
||||
UINTN *sizes) {
|
||||
_cleanup_freepool_ struct PeSectionHeader *section_table = NULL;
|
||||
@@ -295,26 +295,26 @@ EFI_STATUS pe_file_locate_sections(
|
||||
assert(offsets);
|
||||
assert(sizes);
|
||||
|
||||
err = dir->Open(dir, &handle, (CHAR16*)path, EFI_FILE_MODE_READ, 0ULL);
|
||||
if (EFI_ERROR(err))
|
||||
err = dir->Open(dir, &handle, (char16_t *) path, EFI_FILE_MODE_READ, 0ULL);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
len = sizeof(dos);
|
||||
err = handle->Read(handle, &len, &dos);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
if (len != sizeof(dos) || !verify_dos(&dos))
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
err = handle->SetPosition(handle, dos.ExeHeader);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
len = sizeof(pe);
|
||||
err = handle->Read(handle, &len, &pe);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
if (len != sizeof(pe) || !verify_pe(&pe, /* allow_compatibility= */ FALSE))
|
||||
if (len != sizeof(pe) || !verify_pe(&pe, /* allow_compatibility= */ false))
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
section_table_len = pe.FileHeader.NumberOfSections * sizeof(struct PeSectionHeader);
|
||||
@@ -323,12 +323,12 @@ EFI_STATUS pe_file_locate_sections(
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
err = handle->SetPosition(handle, section_table_offset(&dos, &pe));
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
len = section_table_len;
|
||||
err = handle->Read(handle, &len, section_table);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
if (len != section_table_len)
|
||||
return EFI_LOAD_ERROR;
|
||||
|
||||
+8
-7
@@ -2,22 +2,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <efidef.h>
|
||||
#include <uchar.h>
|
||||
|
||||
EFI_STATUS pe_memory_locate_sections(
|
||||
const CHAR8 *base,
|
||||
const CHAR8 **sections,
|
||||
const char *base,
|
||||
const char **sections,
|
||||
UINTN *addrs,
|
||||
UINTN *sizes);
|
||||
|
||||
EFI_STATUS pe_file_locate_sections(
|
||||
EFI_FILE *dir,
|
||||
const CHAR16 *path,
|
||||
const CHAR8 **sections,
|
||||
const char16_t *path,
|
||||
const char **sections,
|
||||
UINTN *offsets,
|
||||
UINTN *sizes);
|
||||
|
||||
EFI_STATUS pe_alignment_info(
|
||||
const void *base,
|
||||
UINT32 *ret_entry_point_address,
|
||||
UINT32 *ret_size_of_image,
|
||||
UINT32 *ret_section_alignment);
|
||||
uint32_t *ret_entry_point_address,
|
||||
uint32_t *ret_size_of_image,
|
||||
uint32_t *ret_section_alignment);
|
||||
|
||||
+28
-23
@@ -27,7 +27,7 @@ static EFI_STATUS acquire_rng(UINTN size, void **ret) {
|
||||
/* Try to acquire the specified number of bytes from the UEFI RNG */
|
||||
|
||||
err = BS->LocateProtocol((EFI_GUID *) EFI_RNG_GUID, NULL, (void **) &rng);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
if (!rng)
|
||||
return EFI_UNSUPPORTED;
|
||||
@@ -35,7 +35,7 @@ static EFI_STATUS acquire_rng(UINTN size, void **ret) {
|
||||
data = xmalloc(size);
|
||||
|
||||
err = rng->GetRNG(rng, NULL, size, data);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to acquire RNG data: %r", err);
|
||||
|
||||
*ret = TAKE_PTR(data);
|
||||
@@ -48,9 +48,9 @@ static void hash_once(
|
||||
UINTN size,
|
||||
const void *system_token,
|
||||
UINTN system_token_size,
|
||||
UINT64 uefi_monotonic_counter,
|
||||
uint64_t uefi_monotonic_counter,
|
||||
UINTN counter,
|
||||
UINT8 ret[static HASH_VALUE_SIZE]) {
|
||||
uint8_t ret[static HASH_VALUE_SIZE]) {
|
||||
|
||||
/* This hashes together:
|
||||
*
|
||||
@@ -85,7 +85,7 @@ static EFI_STATUS hash_many(
|
||||
UINTN size,
|
||||
const void *system_token,
|
||||
UINTN system_token_size,
|
||||
UINT64 uefi_monotonic_counter,
|
||||
uint64_t uefi_monotonic_counter,
|
||||
UINTN counter_start,
|
||||
UINTN n,
|
||||
void **ret) {
|
||||
@@ -106,7 +106,7 @@ static EFI_STATUS hash_many(
|
||||
system_token, system_token_size,
|
||||
uefi_monotonic_counter,
|
||||
counter_start + i,
|
||||
(UINT8*) output + (i * HASH_VALUE_SIZE));
|
||||
(uint8_t*) output + (i * HASH_VALUE_SIZE));
|
||||
|
||||
*ret = TAKE_PTR(output);
|
||||
return EFI_SUCCESS;
|
||||
@@ -118,7 +118,7 @@ static EFI_STATUS mangle_random_seed(
|
||||
UINTN size,
|
||||
const void *system_token,
|
||||
UINTN system_token_size,
|
||||
UINT64 uefi_monotonic_counter,
|
||||
uint64_t uefi_monotonic_counter,
|
||||
void **ret_new_seed,
|
||||
void **ret_for_kernel) {
|
||||
|
||||
@@ -141,12 +141,12 @@ static EFI_STATUS mangle_random_seed(
|
||||
|
||||
/* Begin hashing in counter mode at counter 0 for the new seed for the disk */
|
||||
err = hash_many(old_seed, rng, size, system_token, system_token_size, uefi_monotonic_counter, 0, n, &new_seed);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Continue counting at 'n' for the seed for the kernel */
|
||||
err = hash_many(old_seed, rng, size, system_token, system_token_size, uefi_monotonic_counter, n, n, &for_kernel);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
*ret_new_seed = TAKE_PTR(new_seed);
|
||||
@@ -156,7 +156,7 @@ static EFI_STATUS mangle_random_seed(
|
||||
}
|
||||
|
||||
static EFI_STATUS acquire_system_token(void **ret, UINTN *ret_size) {
|
||||
_cleanup_freepool_ CHAR8 *data = NULL;
|
||||
_cleanup_free_ char *data = NULL;
|
||||
EFI_STATUS err;
|
||||
UINTN size;
|
||||
|
||||
@@ -164,7 +164,7 @@ static EFI_STATUS acquire_system_token(void **ret, UINTN *ret_size) {
|
||||
assert(ret_size);
|
||||
|
||||
err = efivar_get_raw(LOADER_GUID, L"LoaderSystemToken", &data, &size);
|
||||
if (EFI_ERROR(err)) {
|
||||
if (err != EFI_SUCCESS) {
|
||||
if (err != EFI_NOT_FOUND)
|
||||
log_error_stall(L"Failed to read LoaderSystemToken EFI variable: %r", err);
|
||||
return err;
|
||||
@@ -234,7 +234,7 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
_cleanup_(file_closep) EFI_FILE *handle = NULL;
|
||||
UINTN size, rsize, wsize, system_token_size = 0;
|
||||
_cleanup_freepool_ EFI_FILE_INFO *info = NULL;
|
||||
UINT64 uefi_monotonic_counter = 0;
|
||||
uint64_t uefi_monotonic_counter = 0;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(root_dir);
|
||||
@@ -253,18 +253,23 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
* it in our hash. This is protection against golden master image sloppiness, and it remains on the
|
||||
* system, even when disk images are duplicated or swapped out. */
|
||||
err = acquire_system_token(&system_token, &system_token_size);
|
||||
if (mode != RANDOM_SEED_ALWAYS && EFI_ERROR(err))
|
||||
if (mode != RANDOM_SEED_ALWAYS && err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = root_dir->Open(root_dir, &handle, (CHAR16*) L"\\loader\\random-seed", EFI_FILE_MODE_READ|EFI_FILE_MODE_WRITE, 0ULL);
|
||||
if (EFI_ERROR(err)) {
|
||||
err = root_dir->Open(
|
||||
root_dir,
|
||||
&handle,
|
||||
(char16_t *) L"\\loader\\random-seed",
|
||||
EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
|
||||
0);
|
||||
if (err != EFI_SUCCESS) {
|
||||
if (err != EFI_NOT_FOUND && err != EFI_WRITE_PROTECTED)
|
||||
log_error_stall(L"Failed to open random seed file: %r", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = get_file_info_harder(handle, &info, NULL);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to get file info for random seed: %r");
|
||||
|
||||
size = info->FileSize;
|
||||
@@ -278,13 +283,13 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
|
||||
rsize = size;
|
||||
err = handle->Read(handle, &rsize, seed);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to read random seed file: %r", err);
|
||||
if (rsize != size)
|
||||
return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short read on random seed file.");
|
||||
|
||||
err = handle->SetPosition(handle, 0);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to seek to beginning of random seed file: %r", err);
|
||||
|
||||
/* Request some random data from the UEFI RNG. We don't need this to work safely, but it's a good
|
||||
@@ -296,29 +301,29 @@ EFI_STATUS process_random_seed(EFI_FILE *root_dir, RandomSeedMode mode) {
|
||||
* boot) in the hash, so that even if the changes to the ESP for some reason should not be
|
||||
* persistent, the random seed we generate will still be different on every single boot. */
|
||||
err = BS->GetNextMonotonicCount(&uefi_monotonic_counter);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to acquire UEFI monotonic counter: %r", err);
|
||||
|
||||
/* Calculate new random seed for the disk and what to pass to the kernel */
|
||||
err = mangle_random_seed(seed, rng, size, system_token, system_token_size, uefi_monotonic_counter, &new_seed, &for_kernel);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Update the random seed on disk before we use it */
|
||||
wsize = size;
|
||||
err = handle->Write(handle, &wsize, new_seed);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to write random seed file: %r", err);
|
||||
if (wsize != size)
|
||||
return log_error_status_stall(EFI_PROTOCOL_ERROR, L"Short write on random seed file.");
|
||||
|
||||
err = handle->Flush(handle);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to flush random seed file: %r", err);
|
||||
|
||||
/* We are good to go */
|
||||
err = efivar_set_raw(LOADER_GUID, L"LoaderRandomSeed", for_kernel, size, 0);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to write random seed to EFI variable: %r", err);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <efi.h>
|
||||
#include <errno.h>
|
||||
#include <uchar.h>
|
||||
|
||||
typedef enum RandomSeedMode {
|
||||
RANDOM_SEED_OFF,
|
||||
@@ -12,7 +13,7 @@ typedef enum RandomSeedMode {
|
||||
_RANDOM_SEED_MODE_INVALID = -EINVAL,
|
||||
} RandomSeedMode;
|
||||
|
||||
static const CHAR16 * const random_seed_modes_table[_RANDOM_SEED_MODE_MAX] = {
|
||||
static const char16_t * const random_seed_modes_table[_RANDOM_SEED_MODE_MAX] = {
|
||||
[RANDOM_SEED_OFF] = L"off",
|
||||
[RANDOM_SEED_WITH_SYSTEM_TOKEN] = L"with-system-token",
|
||||
[RANDOM_SEED_ALWAYS] = L"always",
|
||||
|
||||
@@ -4,24 +4,24 @@
|
||||
#include "secure-boot.h"
|
||||
#include "util.h"
|
||||
|
||||
BOOLEAN secure_boot_enabled(void) {
|
||||
BOOLEAN secure;
|
||||
bool secure_boot_enabled(void) {
|
||||
bool secure;
|
||||
EFI_STATUS err;
|
||||
|
||||
err = efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SecureBoot", &secure);
|
||||
|
||||
return !EFI_ERROR(err) && secure;
|
||||
return err == EFI_SUCCESS && secure;
|
||||
}
|
||||
|
||||
SecureBootMode secure_boot_mode(void) {
|
||||
BOOLEAN secure, audit = FALSE, deployed = FALSE, setup = FALSE;
|
||||
bool secure, audit = false, deployed = false, setup = false;
|
||||
EFI_STATUS err;
|
||||
|
||||
err = efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"SecureBoot", &secure);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return SECURE_BOOT_UNSUPPORTED;
|
||||
|
||||
/* We can assume FALSE for all these if they are abscent (AuditMode and
|
||||
/* We can assume false for all these if they are abscent (AuditMode and
|
||||
* DeployedMode may not exist on older firmware). */
|
||||
(void) efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"AuditMode", &audit);
|
||||
(void) efivar_get_boolean_u8(EFI_GLOBAL_GUID, L"DeployedMode", &deployed);
|
||||
|
||||
@@ -4,5 +4,5 @@
|
||||
#include <efi.h>
|
||||
#include "efivars-fundamental.h"
|
||||
|
||||
BOOLEAN secure_boot_enabled(void);
|
||||
bool secure_boot_enabled(void);
|
||||
SecureBootMode secure_boot_mode(void);
|
||||
|
||||
+33
-33
@@ -22,37 +22,37 @@
|
||||
#endif
|
||||
|
||||
struct ShimLock {
|
||||
EFI_STATUS __sysv_abi__ (*shim_verify) (void *buffer, UINT32 size);
|
||||
EFI_STATUS __sysv_abi__ (*shim_verify) (void *buffer, uint32_t size);
|
||||
|
||||
/* context is actually a struct for the PE header, but it isn't needed so void is sufficient just do define the interface
|
||||
* see shim.c/shim.h and PeHeader.h in the github shim repo */
|
||||
EFI_STATUS __sysv_abi__ (*generate_hash) (void *data, UINT32 datasize, void *context, UINT8 *sha256hash, UINT8 *sha1hash);
|
||||
EFI_STATUS __sysv_abi__ (*generate_hash) (void *data, uint32_t datasize, void *context, uint8_t *sha256hash, uint8_t *sha1hash);
|
||||
|
||||
EFI_STATUS __sysv_abi__ (*read_header) (void *data, UINT32 datasize, void *context);
|
||||
EFI_STATUS __sysv_abi__ (*read_header) (void *data, uint32_t datasize, void *context);
|
||||
};
|
||||
|
||||
#define SHIM_LOCK_GUID \
|
||||
&(const EFI_GUID) { 0x605dab50, 0xe046, 0x4300, { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } }
|
||||
|
||||
BOOLEAN shim_loaded(void) {
|
||||
bool shim_loaded(void) {
|
||||
struct ShimLock *shim_lock;
|
||||
|
||||
return !EFI_ERROR(BS->LocateProtocol((EFI_GUID*) SHIM_LOCK_GUID, NULL, (void**) &shim_lock));
|
||||
return BS->LocateProtocol((EFI_GUID*) SHIM_LOCK_GUID, NULL, (void**) &shim_lock) == EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static BOOLEAN shim_validate(void *data, UINT32 size) {
|
||||
static bool shim_validate(void *data, uint32_t size) {
|
||||
struct ShimLock *shim_lock;
|
||||
|
||||
if (!data)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
if (EFI_ERROR(BS->LocateProtocol((EFI_GUID*) SHIM_LOCK_GUID, NULL, (void**) &shim_lock)))
|
||||
return FALSE;
|
||||
if (BS->LocateProtocol((EFI_GUID*) SHIM_LOCK_GUID, NULL, (void**) &shim_lock) != EFI_SUCCESS)
|
||||
return false;
|
||||
|
||||
if (!shim_lock)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
return !EFI_ERROR(shim_lock->shim_verify(data, size));
|
||||
return shim_lock->shim_verify(data, size) == EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Handle to the original authenticator for security1 protocol */
|
||||
@@ -72,22 +72,22 @@ static EFI_SECURITY2_FILE_AUTHENTICATION es2fa = NULL;
|
||||
static EFIAPI EFI_STATUS security2_policy_authentication (const EFI_SECURITY2_PROTOCOL *this,
|
||||
const EFI_DEVICE_PATH_PROTOCOL *device_path,
|
||||
void *file_buffer, UINTN file_size, BOOLEAN boot_policy) {
|
||||
EFI_STATUS status;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(this);
|
||||
/* device_path and file_buffer may be NULL */
|
||||
|
||||
/* Chain original security policy */
|
||||
status = es2fa(this, device_path, file_buffer, file_size, boot_policy);
|
||||
err = es2fa(this, device_path, file_buffer, file_size, boot_policy);
|
||||
|
||||
/* if OK, don't bother with MOK check */
|
||||
if (!EFI_ERROR(status))
|
||||
return status;
|
||||
if (err == EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (shim_validate(file_buffer, file_size))
|
||||
return EFI_SUCCESS;
|
||||
|
||||
return status;
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -99,12 +99,12 @@ static EFIAPI EFI_STATUS security2_policy_authentication (const EFI_SECURITY2_PR
|
||||
* authentication failure, be it EFI_ACCESS_DENIED, EFI_SECURITY_VIOLATION, or something
|
||||
* else. (This seems to vary between implementations.)
|
||||
*/
|
||||
static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROTOCOL *this, UINT32 authentication_status,
|
||||
static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROTOCOL *this, uint32_t authentication_status,
|
||||
const EFI_DEVICE_PATH_PROTOCOL *device_path_const) {
|
||||
EFI_STATUS status;
|
||||
_cleanup_freepool_ CHAR16 *dev_path_str = NULL;
|
||||
EFI_STATUS err;
|
||||
_cleanup_free_ char16_t *dev_path_str = NULL;
|
||||
EFI_HANDLE h;
|
||||
_cleanup_freepool_ CHAR8 *file_buffer = NULL;
|
||||
_cleanup_free_ char *file_buffer = NULL;
|
||||
UINTN file_size;
|
||||
|
||||
assert(this);
|
||||
@@ -113,22 +113,22 @@ static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROT
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
EFI_DEVICE_PATH *dp = (EFI_DEVICE_PATH *) device_path_const;
|
||||
status = BS->LocateDevicePath(&FileSystemProtocol, &dp, &h);
|
||||
if (EFI_ERROR(status))
|
||||
return status;
|
||||
err = BS->LocateDevicePath(&FileSystemProtocol, &dp, &h);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
_cleanup_(file_closep) EFI_FILE *root = NULL;
|
||||
status = open_volume(h, &root);
|
||||
if (status != EFI_SUCCESS)
|
||||
return status;
|
||||
err = open_volume(h, &root);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
dev_path_str = DevicePathToStr(dp);
|
||||
if (!dev_path_str)
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
|
||||
status = file_read(root, dev_path_str, 0, 0, &file_buffer, &file_size);
|
||||
if (EFI_ERROR(status))
|
||||
return status;
|
||||
err = file_read(root, dev_path_str, 0, 0, &file_buffer, &file_size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (shim_validate(file_buffer, file_size))
|
||||
return EFI_SUCCESS;
|
||||
@@ -140,7 +140,7 @@ static EFIAPI EFI_STATUS security_policy_authentication (const EFI_SECURITY_PROT
|
||||
EFI_STATUS security_policy_install(void) {
|
||||
EFI_SECURITY_PROTOCOL *security_protocol;
|
||||
EFI_SECURITY2_PROTOCOL *security2_protocol = NULL;
|
||||
EFI_STATUS status;
|
||||
EFI_STATUS err;
|
||||
|
||||
/* Already Installed */
|
||||
if (esfas)
|
||||
@@ -153,10 +153,10 @@ EFI_STATUS security_policy_install(void) {
|
||||
*/
|
||||
BS->LocateProtocol((EFI_GUID*) SECURITY_PROTOCOL2_GUID, NULL, (void**) &security2_protocol);
|
||||
|
||||
status = BS->LocateProtocol((EFI_GUID*) SECURITY_PROTOCOL_GUID, NULL, (void**) &security_protocol);
|
||||
err = BS->LocateProtocol((EFI_GUID*) SECURITY_PROTOCOL_GUID, NULL, (void**) &security_protocol);
|
||||
/* This one is mandatory, so there's a serious problem */
|
||||
if (EFI_ERROR(status))
|
||||
return status;
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
esfas = security_protocol->FileAuthenticationState;
|
||||
security_protocol->FileAuthenticationState = security_policy_authentication;
|
||||
|
||||
+1
-1
@@ -11,6 +11,6 @@
|
||||
|
||||
#include <efi.h>
|
||||
|
||||
BOOLEAN shim_loaded(void);
|
||||
bool shim_loaded(void);
|
||||
|
||||
EFI_STATUS security_policy_install(void);
|
||||
|
||||
+38
-38
@@ -8,41 +8,41 @@
|
||||
#include "util.h"
|
||||
|
||||
struct bmp_file {
|
||||
CHAR8 signature[2];
|
||||
UINT32 size;
|
||||
UINT16 reserved[2];
|
||||
UINT32 offset;
|
||||
char signature[2];
|
||||
uint32_t size;
|
||||
uint16_t reserved[2];
|
||||
uint32_t offset;
|
||||
} _packed_;
|
||||
|
||||
/* we require at least BITMAPINFOHEADER, later versions are
|
||||
accepted, but their features ignored */
|
||||
struct bmp_dib {
|
||||
UINT32 size;
|
||||
UINT32 x;
|
||||
UINT32 y;
|
||||
UINT16 planes;
|
||||
UINT16 depth;
|
||||
UINT32 compression;
|
||||
UINT32 image_size;
|
||||
INT32 x_pixel_meter;
|
||||
INT32 y_pixel_meter;
|
||||
UINT32 colors_used;
|
||||
UINT32 colors_important;
|
||||
uint32_t size;
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint16_t planes;
|
||||
uint16_t depth;
|
||||
uint32_t compression;
|
||||
uint32_t image_size;
|
||||
int32_t x_pixel_meter;
|
||||
int32_t y_pixel_meter;
|
||||
uint32_t colors_used;
|
||||
uint32_t colors_important;
|
||||
} _packed_;
|
||||
|
||||
struct bmp_map {
|
||||
UINT8 blue;
|
||||
UINT8 green;
|
||||
UINT8 red;
|
||||
UINT8 reserved;
|
||||
uint8_t blue;
|
||||
uint8_t green;
|
||||
uint8_t red;
|
||||
uint8_t reserved;
|
||||
} _packed_;
|
||||
|
||||
static EFI_STATUS bmp_parse_header(
|
||||
const UINT8 *bmp,
|
||||
const uint8_t *bmp,
|
||||
UINTN size,
|
||||
struct bmp_dib **ret_dib,
|
||||
struct bmp_map **ret_map,
|
||||
const UINT8 **pixmap) {
|
||||
const uint8_t **pixmap) {
|
||||
|
||||
struct bmp_file *file;
|
||||
struct bmp_dib *dib;
|
||||
@@ -104,7 +104,7 @@ static EFI_STATUS bmp_parse_header(
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
if (file->offset > sizeof(struct bmp_file) + dib->size) {
|
||||
UINT32 map_count;
|
||||
uint32_t map_count;
|
||||
UINTN map_size;
|
||||
|
||||
if (dib->colors_used)
|
||||
@@ -135,8 +135,8 @@ static EFI_STATUS bmp_parse_header(
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
static void pixel_blend(UINT32 *dst, const UINT32 source) {
|
||||
UINT32 alpha, src, src_rb, src_g, dst_rb, dst_g, rb, g;
|
||||
static void pixel_blend(uint32_t *dst, const uint32_t source) {
|
||||
uint32_t alpha, src, src_rb, src_g, dst_rb, dst_g, rb, g;
|
||||
|
||||
assert(dst);
|
||||
|
||||
@@ -163,9 +163,9 @@ static EFI_STATUS bmp_to_blt(
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buf,
|
||||
struct bmp_dib *dib,
|
||||
struct bmp_map *map,
|
||||
const UINT8 *pixmap) {
|
||||
const uint8_t *pixmap) {
|
||||
|
||||
const UINT8 *in;
|
||||
const uint8_t *in;
|
||||
|
||||
assert(buf);
|
||||
assert(dib);
|
||||
@@ -219,7 +219,7 @@ static EFI_STATUS bmp_to_blt(
|
||||
break;
|
||||
|
||||
case 16: {
|
||||
UINT16 i = *(UINT16 *) in;
|
||||
uint16_t i = *(uint16_t *) in;
|
||||
|
||||
out->Red = (i & 0x7c00) >> 7;
|
||||
out->Green = (i & 0x3e0) >> 2;
|
||||
@@ -236,9 +236,9 @@ static EFI_STATUS bmp_to_blt(
|
||||
break;
|
||||
|
||||
case 32: {
|
||||
UINT32 i = *(UINT32 *) in;
|
||||
uint32_t i = *(uint32_t *) in;
|
||||
|
||||
pixel_blend((UINT32 *)out, i);
|
||||
pixel_blend((uint32_t *)out, i);
|
||||
|
||||
in += 3;
|
||||
break;
|
||||
@@ -254,12 +254,12 @@ static EFI_STATUS bmp_to_blt(
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS graphics_splash(const UINT8 *content, UINTN len, const EFI_GRAPHICS_OUTPUT_BLT_PIXEL *background) {
|
||||
EFI_STATUS graphics_splash(const uint8_t *content, UINTN len, const EFI_GRAPHICS_OUTPUT_BLT_PIXEL *background) {
|
||||
EFI_GRAPHICS_OUTPUT_BLT_PIXEL pixel = {};
|
||||
EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL;
|
||||
struct bmp_dib *dib;
|
||||
struct bmp_map *map;
|
||||
const UINT8 *pixmap;
|
||||
const uint8_t *pixmap;
|
||||
_cleanup_freepool_ void *blt = NULL;
|
||||
UINTN x_pos = 0;
|
||||
UINTN y_pos = 0;
|
||||
@@ -280,11 +280,11 @@ EFI_STATUS graphics_splash(const UINT8 *content, UINTN len, const EFI_GRAPHICS_O
|
||||
}
|
||||
|
||||
err = BS->LocateProtocol(&GraphicsOutputProtocol, NULL, (void **) &GraphicsOutput);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = bmp_parse_header(content, len, &dib, &map, &pixmap);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (dib->x < GraphicsOutput->Mode->Info->HorizontalResolution)
|
||||
@@ -297,7 +297,7 @@ EFI_STATUS graphics_splash(const UINT8 *content, UINTN len, const EFI_GRAPHICS_O
|
||||
EfiBltVideoFill, 0, 0, 0, 0,
|
||||
GraphicsOutput->Mode->Info->HorizontalResolution,
|
||||
GraphicsOutput->Mode->Info->VerticalResolution, 0);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* EFI buffer */
|
||||
@@ -307,15 +307,15 @@ EFI_STATUS graphics_splash(const UINT8 *content, UINTN len, const EFI_GRAPHICS_O
|
||||
GraphicsOutput, blt,
|
||||
EfiBltVideoToBltBuffer, x_pos, y_pos, 0, 0,
|
||||
dib->x, dib->y, 0);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = bmp_to_blt(blt, dib, map, pixmap);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = graphics_mode(TRUE);
|
||||
if (EFI_ERROR(err))
|
||||
err = graphics_mode(true);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
return GraphicsOutput->Blt(
|
||||
|
||||
@@ -3,4 +3,4 @@
|
||||
|
||||
#include <efi.h>
|
||||
|
||||
EFI_STATUS graphics_splash(const UINT8 *content, UINTN len, const EFI_GRAPHICS_OUTPUT_BLT_PIXEL *background);
|
||||
EFI_STATUS graphics_splash(const uint8_t *content, UINTN len, const EFI_GRAPHICS_OUTPUT_BLT_PIXEL *background);
|
||||
|
||||
+33
-33
@@ -26,7 +26,7 @@ static EFI_STATUS combine_initrd(
|
||||
|
||||
EFI_PHYSICAL_ADDRESS base = UINT32_MAX; /* allocate an area below the 32bit boundary for this */
|
||||
EFI_STATUS err;
|
||||
UINT8 *p;
|
||||
uint8_t *p;
|
||||
UINTN n;
|
||||
|
||||
assert(ret_initrd_base);
|
||||
@@ -59,7 +59,7 @@ static EFI_STATUS combine_initrd(
|
||||
EfiLoaderData,
|
||||
EFI_SIZE_TO_PAGES(n),
|
||||
&base);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Failed to allocate space for combined initrd: %r", err);
|
||||
|
||||
p = PHYSICAL_ADDRESS_TO_POINTER(base);
|
||||
@@ -93,7 +93,7 @@ static EFI_STATUS combine_initrd(
|
||||
p += sysext_initrd_size;
|
||||
}
|
||||
|
||||
assert((UINT8*) PHYSICAL_ADDRESS_TO_POINTER(base) + n == p);
|
||||
assert((uint8_t*) PHYSICAL_ADDRESS_TO_POINTER(base) + n == p);
|
||||
|
||||
*ret_initrd_base = base;
|
||||
*ret_initrd_size = n;
|
||||
@@ -102,7 +102,7 @@ static EFI_STATUS combine_initrd(
|
||||
}
|
||||
|
||||
static void export_variables(EFI_LOADED_IMAGE *loaded_image) {
|
||||
CHAR16 uuid[37];
|
||||
char16_t uuid[37];
|
||||
|
||||
assert(loaded_image);
|
||||
|
||||
@@ -119,7 +119,7 @@ static void export_variables(EFI_LOADED_IMAGE *loaded_image) {
|
||||
* is non-NULL explicitly.) */
|
||||
if (efivar_get_raw(LOADER_GUID, L"LoaderImageIdentifier", NULL, NULL) != EFI_SUCCESS &&
|
||||
loaded_image->FilePath) {
|
||||
_cleanup_freepool_ CHAR16 *s = NULL;
|
||||
_cleanup_free_ char16_t *s = NULL;
|
||||
|
||||
s = DevicePathToStr(loaded_image->FilePath);
|
||||
if (s)
|
||||
@@ -130,14 +130,14 @@ static void export_variables(EFI_LOADED_IMAGE *loaded_image) {
|
||||
|
||||
/* if LoaderFirmwareInfo is not set, let's set it */
|
||||
if (efivar_get_raw(LOADER_GUID, L"LoaderFirmwareInfo", NULL, NULL) != EFI_SUCCESS) {
|
||||
_cleanup_freepool_ CHAR16 *s = NULL;
|
||||
_cleanup_free_ char16_t *s = NULL;
|
||||
s = xpool_print(L"%s %u.%02u", ST->FirmwareVendor, ST->FirmwareRevision >> 16, ST->FirmwareRevision & 0xffff);
|
||||
efivar_set(LOADER_GUID, L"LoaderFirmwareInfo", s, 0);
|
||||
}
|
||||
|
||||
/* ditto for LoaderFirmwareType */
|
||||
if (efivar_get_raw(LOADER_GUID, L"LoaderFirmwareType", NULL, NULL) != EFI_SUCCESS) {
|
||||
_cleanup_freepool_ CHAR16 *s = NULL;
|
||||
_cleanup_free_ char16_t *s = NULL;
|
||||
s = xpool_print(L"UEFI %u.%02u", ST->Hdr.Revision >> 16, ST->Hdr.Revision & 0xffff);
|
||||
efivar_set(LOADER_GUID, L"LoaderFirmwareType", s, 0);
|
||||
}
|
||||
@@ -158,12 +158,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
_SECTION_MAX,
|
||||
};
|
||||
|
||||
static const CHAR8* const sections[_SECTION_MAX + 1] = {
|
||||
[SECTION_CMDLINE] = (const CHAR8*) ".cmdline",
|
||||
[SECTION_LINUX] = (const CHAR8*) ".linux",
|
||||
[SECTION_INITRD] = (const CHAR8*) ".initrd",
|
||||
[SECTION_SPLASH] = (const CHAR8*) ".splash",
|
||||
[SECTION_DTB] = (const CHAR8*) ".dtb",
|
||||
static const char * const sections[_SECTION_MAX + 1] = {
|
||||
[SECTION_CMDLINE] = ".cmdline",
|
||||
[SECTION_LINUX] = ".linux",
|
||||
[SECTION_INITRD] = ".initrd",
|
||||
[SECTION_SPLASH] = ".splash",
|
||||
[SECTION_DTB] = ".dtb",
|
||||
NULL,
|
||||
};
|
||||
|
||||
@@ -176,8 +176,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
EFI_LOADED_IMAGE *loaded_image;
|
||||
UINTN addrs[_SECTION_MAX] = {};
|
||||
UINTN szs[_SECTION_MAX] = {};
|
||||
CHAR8 *cmdline = NULL;
|
||||
_cleanup_freepool_ CHAR8 *cmdline_owned = NULL;
|
||||
char *cmdline = NULL;
|
||||
_cleanup_free_ char *cmdline_owned = NULL;
|
||||
EFI_STATUS err;
|
||||
|
||||
InitializeLib(image, sys_table);
|
||||
@@ -192,32 +192,32 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
image,
|
||||
NULL,
|
||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
|
||||
|
||||
err = pe_memory_locate_sections(loaded_image->ImageBase, (const CHAR8**) sections, addrs, szs);
|
||||
if (EFI_ERROR(err) || szs[SECTION_LINUX] == 0) {
|
||||
if (!EFI_ERROR(err))
|
||||
err = pe_memory_locate_sections(loaded_image->ImageBase, (const char **) sections, addrs, szs);
|
||||
if (err != EFI_SUCCESS || szs[SECTION_LINUX] == 0) {
|
||||
if (err == EFI_SUCCESS)
|
||||
err = EFI_NOT_FOUND;
|
||||
return log_error_status_stall(err, L"Unable to locate embedded .linux section: %r", err);
|
||||
}
|
||||
|
||||
/* Show splash screen as early as possible */
|
||||
graphics_splash((const UINT8*) loaded_image->ImageBase + addrs[SECTION_SPLASH], szs[SECTION_SPLASH], NULL);
|
||||
graphics_splash((const uint8_t*) loaded_image->ImageBase + addrs[SECTION_SPLASH], szs[SECTION_SPLASH], NULL);
|
||||
|
||||
if (szs[SECTION_CMDLINE] > 0) {
|
||||
cmdline = (CHAR8*) loaded_image->ImageBase + addrs[SECTION_CMDLINE];
|
||||
cmdline = (char *) 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 &&
|
||||
*(CHAR16 *) loaded_image->LoadOptions > 0x1F) {
|
||||
cmdline_len = (loaded_image->LoadOptionsSize / sizeof(CHAR16)) * sizeof(CHAR8);
|
||||
*(char16_t *) loaded_image->LoadOptions > 0x1F) {
|
||||
cmdline_len = (loaded_image->LoadOptionsSize / sizeof(char16_t)) * sizeof(char);
|
||||
cmdline = cmdline_owned = xmalloc(cmdline_len);
|
||||
|
||||
for (UINTN i = 0; i < cmdline_len; i++)
|
||||
cmdline[i] = ((CHAR16 *) loaded_image->LoadOptions)[i];
|
||||
cmdline[i] = ((char16_t *) loaded_image->LoadOptions)[i];
|
||||
|
||||
/* Let's measure the passed kernel command line into the TPM. Note that this possibly
|
||||
* duplicates what we already did in the boot menu, if that was already used. However, since
|
||||
@@ -231,10 +231,10 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
(void) pack_cpio(loaded_image,
|
||||
NULL,
|
||||
L".cred",
|
||||
(const CHAR8*) ".extra/credentials",
|
||||
".extra/credentials",
|
||||
/* dir_mode= */ 0500,
|
||||
/* access_mode= */ 0400,
|
||||
/* tpm_pcr= */ (UINT32[]) { TPM_PCR_INDEX_KERNEL_PARAMETERS, TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT },
|
||||
/* tpm_pcr= */ (uint32_t[]) { TPM_PCR_INDEX_KERNEL_PARAMETERS, TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT },
|
||||
/* n_tpm_pcr= */ 2,
|
||||
L"Credentials initrd",
|
||||
&credential_initrd,
|
||||
@@ -243,10 +243,10 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
(void) pack_cpio(loaded_image,
|
||||
L"\\loader\\credentials",
|
||||
L".cred",
|
||||
(const CHAR8*) ".extra/global_credentials",
|
||||
".extra/global_credentials",
|
||||
/* dir_mode= */ 0500,
|
||||
/* access_mode= */ 0400,
|
||||
/* tpm_pcr= */ (UINT32[]) { TPM_PCR_INDEX_KERNEL_PARAMETERS, TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT },
|
||||
/* tpm_pcr= */ (uint32_t[]) { TPM_PCR_INDEX_KERNEL_PARAMETERS, TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT },
|
||||
/* n_tpm_pcr= */ 2,
|
||||
L"Global credentials initrd",
|
||||
&global_credential_initrd,
|
||||
@@ -255,10 +255,10 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
(void) pack_cpio(loaded_image,
|
||||
NULL,
|
||||
L".raw",
|
||||
(const CHAR8*) ".extra/sysext",
|
||||
".extra/sysext",
|
||||
/* dir_mode= */ 0555,
|
||||
/* access_mode= */ 0444,
|
||||
/* tpm_pcr= */ (UINT32[]) { TPM_PCR_INDEX_INITRD },
|
||||
/* tpm_pcr= */ (uint32_t[]) { TPM_PCR_INDEX_INITRD },
|
||||
/* n_tpm_pcr= */ 1,
|
||||
L"System extension initrd",
|
||||
&sysext_initrd,
|
||||
@@ -281,7 +281,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
global_credential_initrd, global_credential_initrd_size,
|
||||
sysext_initrd, sysext_initrd_size,
|
||||
&initrd_base, &initrd_size);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Given these might be large let's free them explicitly, quickly. */
|
||||
@@ -293,13 +293,13 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
|
||||
if (dt_size > 0) {
|
||||
err = devicetree_install_from_memory(
|
||||
&dt_state, PHYSICAL_ADDRESS_TO_POINTER(dt_base), dt_size);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
log_error_stall(L"Error loading embedded devicetree: %r", err);
|
||||
}
|
||||
|
||||
err = linux_exec(image, cmdline, cmdline_len,
|
||||
PHYSICAL_ADDRESS_TO_POINTER(linux_base), linux_size,
|
||||
PHYSICAL_ADDRESS_TO_POINTER(initrd_base), initrd_size);
|
||||
graphics_mode(FALSE);
|
||||
graphics_mode(false);
|
||||
return log_error_status_stall(err, L"Execution of embedded linux image failed: %r", err);
|
||||
}
|
||||
|
||||
+17
-16
@@ -5,11 +5,12 @@
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "ticks.h"
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
static BOOLEAN in_hypervisor(void) {
|
||||
static bool in_hypervisor(void) {
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
||||
/* The TSC might or might not be virtualized in VMs (and thus might not be accurate or start at zero
|
||||
@@ -20,15 +21,15 @@ static BOOLEAN in_hypervisor(void) {
|
||||
* environment. */
|
||||
|
||||
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) == 0)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
return !!(ecx & 0x80000000U);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __x86_64__
|
||||
static UINT64 ticks_read(void) {
|
||||
UINT64 a, d;
|
||||
static uint64_t ticks_read(void) {
|
||||
uint64_t a, d;
|
||||
|
||||
if (in_hypervisor())
|
||||
return 0;
|
||||
@@ -37,8 +38,8 @@ static UINT64 ticks_read(void) {
|
||||
return (d << 32) | a;
|
||||
}
|
||||
#elif defined(__i386__)
|
||||
static UINT64 ticks_read(void) {
|
||||
UINT64 val;
|
||||
static uint64_t ticks_read(void) {
|
||||
uint64_t val;
|
||||
|
||||
if (in_hypervisor())
|
||||
return 0;
|
||||
@@ -47,28 +48,28 @@ static UINT64 ticks_read(void) {
|
||||
return val;
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
static UINT64 ticks_read(void) {
|
||||
UINT64 val;
|
||||
static uint64_t ticks_read(void) {
|
||||
uint64_t val;
|
||||
__asm__ volatile ("mrs %0, cntpct_el0" : "=r" (val));
|
||||
return val;
|
||||
}
|
||||
#else
|
||||
static UINT64 ticks_read(void) {
|
||||
static uint64_t ticks_read(void) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__aarch64__)
|
||||
static UINT64 ticks_freq(void) {
|
||||
UINT64 freq;
|
||||
static uint64_t ticks_freq(void) {
|
||||
uint64_t freq;
|
||||
__asm__ volatile ("mrs %0, cntfrq_el0": "=r" (freq));
|
||||
return freq;
|
||||
}
|
||||
#else
|
||||
/* count TSC ticks during a millisecond delay */
|
||||
static UINT64 ticks_freq(void) {
|
||||
UINT64 ticks_start, ticks_end;
|
||||
static UINT64 cache = 0;
|
||||
static uint64_t ticks_freq(void) {
|
||||
uint64_t ticks_start, ticks_end;
|
||||
static uint64_t cache = 0;
|
||||
|
||||
if (cache != 0)
|
||||
return cache;
|
||||
@@ -86,8 +87,8 @@ static UINT64 ticks_freq(void) {
|
||||
}
|
||||
#endif
|
||||
|
||||
UINT64 time_usec(void) {
|
||||
UINT64 ticks, freq;
|
||||
uint64_t time_usec(void) {
|
||||
uint64_t ticks, freq;
|
||||
|
||||
ticks = ticks_read();
|
||||
if (ticks == 0)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
UINT64 time_usec(void);
|
||||
uint64_t time_usec(void);
|
||||
|
||||
+109
-109
@@ -6,45 +6,45 @@
|
||||
#include "ticks.h"
|
||||
#include "util.h"
|
||||
|
||||
EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b) {
|
||||
EFI_STATUS parse_boolean(const char *v, bool *b) {
|
||||
assert(b);
|
||||
|
||||
if (!v)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
if (streq8((char *) v, "1") || streq8((char *) v, "yes") || streq8((char *) v, "y") ||
|
||||
streq8((char *) v, "true") || streq8((char *) v, "t") || streq8((char *) v, "on")) {
|
||||
*b = TRUE;
|
||||
if (streq8(v, "1") || streq8(v, "yes") || streq8(v, "y") || streq8(v, "true") || streq8(v, "t") ||
|
||||
streq8(v, "on")) {
|
||||
*b = true;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
if (streq8((char *) v, "0") || streq8((char *) v, "no") || streq8((char *) v, "n") ||
|
||||
streq8((char *) v, "false") || streq8((char *) v, "f") || streq8((char *) v, "off")) {
|
||||
*b = FALSE;
|
||||
if (streq8(v, "0") || streq8(v, "no") || streq8(v, "n") || streq8(v, "false") || streq8(v, "f") ||
|
||||
streq8(v, "off")) {
|
||||
*b = false;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const void *buf, UINTN size, UINT32 flags) {
|
||||
EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const char16_t *name, const void *buf, UINTN size, uint32_t flags) {
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
assert(buf || size == 0);
|
||||
|
||||
flags |= EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
|
||||
return RT->SetVariable((CHAR16 *) name, (EFI_GUID *) vendor, flags, size, (void *) buf);
|
||||
return RT->SetVariable((char16_t *) name, (EFI_GUID *) vendor, flags, size, (void *) buf);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, UINT32 flags) {
|
||||
EFI_STATUS efivar_set(const EFI_GUID *vendor, const char16_t *name, const char16_t *value, uint32_t flags) {
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
return efivar_set_raw(vendor, name, value, value ? strsize16(value) : 0, flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN i, UINT32 flags) {
|
||||
CHAR16 str[32];
|
||||
EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const char16_t *name, UINTN i, uint32_t flags) {
|
||||
char16_t str[32];
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
@@ -52,80 +52,80 @@ EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UI
|
||||
/* Note that SPrint has no native sized length specifier and will always use ValueToString()
|
||||
* regardless of what sign we tell it to use. Therefore, UINTN_MAX will come out as -1 on
|
||||
* 64bit machines. */
|
||||
ValueToString(str, FALSE, i);
|
||||
ValueToString(str, false, i);
|
||||
return efivar_set(vendor, name, str, flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT32 value, UINT32 flags) {
|
||||
UINT8 buf[4];
|
||||
EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t value, uint32_t flags) {
|
||||
uint8_t buf[4];
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
buf[0] = (UINT8)(value >> 0U & 0xFF);
|
||||
buf[1] = (UINT8)(value >> 8U & 0xFF);
|
||||
buf[2] = (UINT8)(value >> 16U & 0xFF);
|
||||
buf[3] = (UINT8)(value >> 24U & 0xFF);
|
||||
buf[0] = (uint8_t)(value >> 0U & 0xFF);
|
||||
buf[1] = (uint8_t)(value >> 8U & 0xFF);
|
||||
buf[2] = (uint8_t)(value >> 16U & 0xFF);
|
||||
buf[3] = (uint8_t)(value >> 24U & 0xFF);
|
||||
|
||||
return efivar_set_raw(vendor, name, buf, sizeof(buf), flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 value, UINT32 flags) {
|
||||
UINT8 buf[8];
|
||||
EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t value, uint32_t flags) {
|
||||
uint8_t buf[8];
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
buf[0] = (UINT8)(value >> 0U & 0xFF);
|
||||
buf[1] = (UINT8)(value >> 8U & 0xFF);
|
||||
buf[2] = (UINT8)(value >> 16U & 0xFF);
|
||||
buf[3] = (UINT8)(value >> 24U & 0xFF);
|
||||
buf[4] = (UINT8)(value >> 32U & 0xFF);
|
||||
buf[5] = (UINT8)(value >> 40U & 0xFF);
|
||||
buf[6] = (UINT8)(value >> 48U & 0xFF);
|
||||
buf[7] = (UINT8)(value >> 56U & 0xFF);
|
||||
buf[0] = (uint8_t)(value >> 0U & 0xFF);
|
||||
buf[1] = (uint8_t)(value >> 8U & 0xFF);
|
||||
buf[2] = (uint8_t)(value >> 16U & 0xFF);
|
||||
buf[3] = (uint8_t)(value >> 24U & 0xFF);
|
||||
buf[4] = (uint8_t)(value >> 32U & 0xFF);
|
||||
buf[5] = (uint8_t)(value >> 40U & 0xFF);
|
||||
buf[6] = (uint8_t)(value >> 48U & 0xFF);
|
||||
buf[7] = (uint8_t)(value >> 56U & 0xFF);
|
||||
|
||||
return efivar_set_raw(vendor, name, buf, sizeof(buf), flags);
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value) {
|
||||
_cleanup_freepool_ CHAR16 *buf = NULL;
|
||||
EFI_STATUS efivar_get(const EFI_GUID *vendor, const char16_t *name, char16_t **value) {
|
||||
_cleanup_free_ char16_t *buf = NULL;
|
||||
EFI_STATUS err;
|
||||
CHAR16 *val;
|
||||
char16_t *val;
|
||||
UINTN size;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, (CHAR8**)&buf, &size);
|
||||
if (EFI_ERROR(err))
|
||||
err = efivar_get_raw(vendor, name, (char **) &buf, &size);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Make sure there are no incomplete characters in the buffer */
|
||||
if ((size % sizeof(CHAR16)) != 0)
|
||||
if ((size % sizeof(char16_t)) != 0)
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
if (!value)
|
||||
return EFI_SUCCESS;
|
||||
|
||||
/* Return buffer directly if it happens to be NUL terminated already */
|
||||
if (size >= sizeof(CHAR16) && buf[size / sizeof(CHAR16) - 1] == 0) {
|
||||
if (size >= sizeof(char16_t) && buf[size / sizeof(char16_t) - 1] == 0) {
|
||||
*value = TAKE_PTR(buf);
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* Make sure a terminating NUL is available at the end */
|
||||
val = xmalloc(size + sizeof(CHAR16));
|
||||
val = xmalloc(size + sizeof(char16_t));
|
||||
|
||||
memcpy(val, buf, size);
|
||||
val[size / sizeof(CHAR16) - 1] = 0; /* NUL terminate */
|
||||
val[size / sizeof(char16_t) - 1] = 0; /* NUL terminate */
|
||||
|
||||
*value = val;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i) {
|
||||
_cleanup_freepool_ CHAR16 *val = NULL;
|
||||
EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const char16_t *name, UINTN *i) {
|
||||
_cleanup_free_ char16_t *val = NULL;
|
||||
EFI_STATUS err;
|
||||
uint64_t u;
|
||||
|
||||
@@ -144,8 +144,8 @@ EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UI
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT32 *ret) {
|
||||
_cleanup_freepool_ CHAR8 *buf = NULL;
|
||||
EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t *ret) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
UINTN size;
|
||||
EFI_STATUS err;
|
||||
|
||||
@@ -153,19 +153,19 @@ EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, &buf, &size);
|
||||
if (!EFI_ERROR(err) && ret) {
|
||||
if (size != sizeof(UINT32))
|
||||
if (err == EFI_SUCCESS && ret) {
|
||||
if (size != sizeof(uint32_t))
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
|
||||
*ret = (UINT32) buf[0] << 0U | (UINT32) buf[1] << 8U | (UINT32) buf[2] << 16U |
|
||||
(UINT32) buf[3] << 24U;
|
||||
*ret = (uint32_t) buf[0] << 0U | (uint32_t) buf[1] << 8U | (uint32_t) buf[2] << 16U |
|
||||
(uint32_t) buf[3] << 24U;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 *ret) {
|
||||
_cleanup_freepool_ CHAR8 *buf = NULL;
|
||||
EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
UINTN size;
|
||||
EFI_STATUS err;
|
||||
|
||||
@@ -173,31 +173,31 @@ EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT
|
||||
assert(name);
|
||||
|
||||
err = efivar_get_raw(vendor, name, &buf, &size);
|
||||
if (!EFI_ERROR(err) && ret) {
|
||||
if (size != sizeof(UINT64))
|
||||
if (err == EFI_SUCCESS && ret) {
|
||||
if (size != sizeof(uint64_t))
|
||||
return EFI_BUFFER_TOO_SMALL;
|
||||
|
||||
*ret = (UINT64) buf[0] << 0U | (UINT64) buf[1] << 8U | (UINT64) buf[2] << 16U |
|
||||
(UINT64) buf[3] << 24U | (UINT64) buf[4] << 32U | (UINT64) buf[5] << 40U |
|
||||
(UINT64) buf[6] << 48U | (UINT64) buf[7] << 56U;
|
||||
*ret = (uint64_t) buf[0] << 0U | (uint64_t) buf[1] << 8U | (uint64_t) buf[2] << 16U |
|
||||
(uint64_t) buf[3] << 24U | (uint64_t) buf[4] << 32U | (uint64_t) buf[5] << 40U |
|
||||
(uint64_t) buf[6] << 48U | (uint64_t) buf[7] << 56U;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size) {
|
||||
_cleanup_freepool_ CHAR8 *buf = NULL;
|
||||
EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const char16_t *name, char **buffer, UINTN *size) {
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
UINTN l;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
|
||||
l = sizeof(CHAR16 *) * EFI_MAXIMUM_VARIABLE_SIZE;
|
||||
l = sizeof(char16_t *) * EFI_MAXIMUM_VARIABLE_SIZE;
|
||||
buf = xmalloc(l);
|
||||
|
||||
err = RT->GetVariable((CHAR16 *) name, (EFI_GUID *) vendor, NULL, &l, buf);
|
||||
if (!EFI_ERROR(err)) {
|
||||
err = RT->GetVariable((char16_t *) name, (EFI_GUID *) vendor, NULL, &l, buf);
|
||||
if (err == EFI_SUCCESS) {
|
||||
|
||||
if (buffer)
|
||||
*buffer = TAKE_PTR(buf);
|
||||
@@ -209,8 +209,8 @@ EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **bu
|
||||
return err;
|
||||
}
|
||||
|
||||
EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret) {
|
||||
_cleanup_freepool_ CHAR8 *b = NULL;
|
||||
EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const char16_t *name, bool *ret) {
|
||||
_cleanup_free_ char *b = NULL;
|
||||
UINTN size;
|
||||
EFI_STATUS err;
|
||||
|
||||
@@ -219,14 +219,14 @@ EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOO
|
||||
assert(ret);
|
||||
|
||||
err = efivar_get_raw(vendor, name, &b, &size);
|
||||
if (!EFI_ERROR(err))
|
||||
if (err == EFI_SUCCESS)
|
||||
*ret = *b > 0;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void efivar_set_time_usec(const EFI_GUID *vendor, const CHAR16 *name, UINT64 usec) {
|
||||
CHAR16 str[32];
|
||||
void efivar_set_time_usec(const EFI_GUID *vendor, const char16_t *name, uint64_t usec) {
|
||||
char16_t str[32];
|
||||
|
||||
assert(vendor);
|
||||
assert(name);
|
||||
@@ -237,12 +237,12 @@ void efivar_set_time_usec(const EFI_GUID *vendor, const CHAR16 *name, UINT64 use
|
||||
return;
|
||||
|
||||
/* See comment on ValueToString in efivar_set_uint_string(). */
|
||||
ValueToString(str, FALSE, usec);
|
||||
ValueToString(str, false, usec);
|
||||
efivar_set(vendor, name, str, 0);
|
||||
}
|
||||
|
||||
static INTN utf8_to_16(const CHAR8 *stra, CHAR16 *c) {
|
||||
CHAR16 unichar;
|
||||
static INTN utf8_to_16(const char *stra, char16_t *c) {
|
||||
char16_t unichar;
|
||||
UINTN len;
|
||||
|
||||
assert(stra);
|
||||
@@ -295,16 +295,16 @@ static INTN utf8_to_16(const CHAR8 *stra, CHAR16 *c) {
|
||||
return len;
|
||||
}
|
||||
|
||||
CHAR16 *xstra_to_str(const CHAR8 *stra) {
|
||||
char16_t *xstra_to_str(const char *stra) {
|
||||
UINTN strlen;
|
||||
UINTN len;
|
||||
UINTN i;
|
||||
CHAR16 *str;
|
||||
char16_t *str;
|
||||
|
||||
assert(stra);
|
||||
|
||||
len = strlen8((const char *) stra);
|
||||
str = xnew(CHAR16, len + 1);
|
||||
len = strlen8(stra);
|
||||
str = xnew(char16_t, len + 1);
|
||||
|
||||
strlen = 0;
|
||||
i = 0;
|
||||
@@ -325,16 +325,16 @@ CHAR16 *xstra_to_str(const CHAR8 *stra) {
|
||||
return str;
|
||||
}
|
||||
|
||||
CHAR16 *xstra_to_path(const CHAR8 *stra) {
|
||||
CHAR16 *str;
|
||||
char16_t *xstra_to_path(const char *stra) {
|
||||
char16_t *str;
|
||||
UINTN strlen;
|
||||
UINTN len;
|
||||
UINTN i;
|
||||
|
||||
assert(stra);
|
||||
|
||||
len = strlen8((const char *) stra);
|
||||
str = xnew(CHAR16, len + 2);
|
||||
len = strlen8(stra);
|
||||
str = xnew(char16_t, len + 2);
|
||||
|
||||
str[0] = '\\';
|
||||
strlen = 1;
|
||||
@@ -364,24 +364,24 @@ CHAR16 *xstra_to_path(const CHAR8 *stra) {
|
||||
return str;
|
||||
}
|
||||
|
||||
EFI_STATUS file_read(EFI_FILE *dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **ret, UINTN *ret_size) {
|
||||
EFI_STATUS file_read(EFI_FILE *dir, const char16_t *name, UINTN off, UINTN size, char **ret, UINTN *ret_size) {
|
||||
_cleanup_(file_closep) EFI_FILE *handle = NULL;
|
||||
_cleanup_freepool_ CHAR8 *buf = NULL;
|
||||
_cleanup_free_ char *buf = NULL;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(dir);
|
||||
assert(name);
|
||||
assert(ret);
|
||||
|
||||
err = dir->Open(dir, &handle, (CHAR16*) name, EFI_FILE_MODE_READ, 0ULL);
|
||||
if (EFI_ERROR(err))
|
||||
err = dir->Open(dir, &handle, (char16_t*) name, EFI_FILE_MODE_READ, 0ULL);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (size == 0) {
|
||||
_cleanup_freepool_ EFI_FILE_INFO *info = NULL;
|
||||
|
||||
err = get_file_info_harder(handle, &info, NULL);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
size = info->FileSize;
|
||||
@@ -389,16 +389,16 @@ EFI_STATUS file_read(EFI_FILE *dir, const CHAR16 *name, UINTN off, UINTN size, C
|
||||
|
||||
if (off > 0) {
|
||||
err = handle->SetPosition(handle, off);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Allocate some extra bytes to guarantee the result is NUL-terminated for CHAR8 and CHAR16 strings. */
|
||||
UINTN extra = size % sizeof(CHAR16) + sizeof(CHAR16);
|
||||
/* Allocate some extra bytes to guarantee the result is NUL-terminated for char and char16_t strings. */
|
||||
UINTN extra = size % sizeof(char16_t) + sizeof(char16_t);
|
||||
|
||||
buf = xmalloc(size + extra);
|
||||
err = handle->Read(handle, &size, buf);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Note that handle->Read() changes size to reflect the actually bytes read. */
|
||||
@@ -411,12 +411,12 @@ EFI_STATUS file_read(EFI_FILE *dir, const CHAR16 *name, UINTN off, UINTN size, C
|
||||
return err;
|
||||
}
|
||||
|
||||
void log_error_stall(const CHAR16 *fmt, ...) {
|
||||
void log_error_stall(const char16_t *fmt, ...) {
|
||||
va_list args;
|
||||
|
||||
assert(fmt);
|
||||
|
||||
INT32 attr = ST->ConOut->Mode->Attribute;
|
||||
int32_t attr = ST->ConOut->Mode->Attribute;
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_LIGHTRED|EFI_BACKGROUND_BLACK);
|
||||
|
||||
if (ST->ConOut->Mode->CursorColumn > 0)
|
||||
@@ -439,11 +439,11 @@ EFI_STATUS log_oom(void) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
void print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str) {
|
||||
void print_at(UINTN x, UINTN y, UINTN attr, const char16_t *str) {
|
||||
assert(str);
|
||||
ST->ConOut->SetCursorPosition(ST->ConOut, x, y);
|
||||
ST->ConOut->SetAttribute(ST->ConOut, attr);
|
||||
ST->ConOut->OutputString(ST->ConOut, (CHAR16*)str);
|
||||
ST->ConOut->OutputString(ST->ConOut, (char16_t *) str);
|
||||
}
|
||||
|
||||
void clear_screen(UINTN attr) {
|
||||
@@ -499,7 +499,7 @@ EFI_STATUS get_file_info_harder(
|
||||
err = handle->GetInfo(handle, &GenericFileInfo, &size, fi);
|
||||
}
|
||||
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
*ret = TAKE_PTR(fi);
|
||||
@@ -531,7 +531,7 @@ EFI_STATUS readdir_harder(
|
||||
* the buffer was too small. Therefore, start with a buffer that should handle FAT32 max
|
||||
* file name length.
|
||||
* As a side effect, most readdir_harder() calls will now be slightly faster. */
|
||||
sz = sizeof(EFI_FILE_INFO) + 256 * sizeof(CHAR16);
|
||||
sz = sizeof(EFI_FILE_INFO) + 256 * sizeof(char16_t);
|
||||
*buffer = xmalloc(sz);
|
||||
*buffer_size = sz;
|
||||
} else
|
||||
@@ -544,7 +544,7 @@ EFI_STATUS readdir_harder(
|
||||
*buffer_size = sz;
|
||||
err = handle->Read(handle, &sz, *buffer);
|
||||
}
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
if (sz == 0) {
|
||||
@@ -557,22 +557,22 @@ EFI_STATUS readdir_harder(
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
BOOLEAN is_ascii(const CHAR16 *f) {
|
||||
bool is_ascii(const char16_t *f) {
|
||||
if (!f)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
for (; *f != 0; f++)
|
||||
if (*f > 127)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
CHAR16 **strv_free(CHAR16 **v) {
|
||||
char16_t **strv_free(char16_t **v) {
|
||||
if (!v)
|
||||
return NULL;
|
||||
|
||||
for (CHAR16 **i = v; *i; i++)
|
||||
for (char16_t **i = v; *i; i++)
|
||||
free(*i);
|
||||
|
||||
free(v);
|
||||
@@ -581,7 +581,7 @@ CHAR16 **strv_free(CHAR16 **v) {
|
||||
|
||||
EFI_STATUS open_directory(
|
||||
EFI_FILE *root,
|
||||
const CHAR16 *path,
|
||||
const char16_t *path,
|
||||
EFI_FILE **ret) {
|
||||
|
||||
_cleanup_(file_closep) EFI_FILE *dir = NULL;
|
||||
@@ -592,12 +592,12 @@ EFI_STATUS open_directory(
|
||||
|
||||
/* Opens a file, and then verifies it is actually a directory */
|
||||
|
||||
err = root->Open(root, &dir, (CHAR16*) path, EFI_FILE_MODE_READ, 0ULL);
|
||||
if (EFI_ERROR(err))
|
||||
err = root->Open(root, &dir, (char16_t *) path, EFI_FILE_MODE_READ, 0);
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = get_file_info_harder(dir, &file_info, NULL);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
if (!FLAGS_SET(file_info->Attribute, EFI_FILE_DIRECTORY))
|
||||
return EFI_LOAD_ERROR;
|
||||
@@ -606,15 +606,15 @@ EFI_STATUS open_directory(
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
UINT64 get_os_indications_supported(void) {
|
||||
UINT64 osind;
|
||||
uint64_t get_os_indications_supported(void) {
|
||||
uint64_t osind;
|
||||
EFI_STATUS err;
|
||||
|
||||
/* Returns the supported OS indications. If we can't acquire it, returns a zeroed out mask, i.e. no
|
||||
* supported features. */
|
||||
|
||||
err = efivar_get_uint64_le(EFI_GLOBAL_GUID, L"OsIndicationsSupported", &osind);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return 0;
|
||||
|
||||
return osind;
|
||||
@@ -624,7 +624,7 @@ UINT64 get_os_indications_supported(void) {
|
||||
__attribute__((noinline)) void debug_break(void) {
|
||||
/* This is a poor programmer's breakpoint to wait until a debugger
|
||||
* has attached to us. Just "set variable wait = 0" or "return" to continue. */
|
||||
volatile BOOLEAN wait = TRUE;
|
||||
volatile bool wait = true;
|
||||
while (wait)
|
||||
/* Prefer asm based stalling so that gdb has a source location to present. */
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
@@ -638,13 +638,13 @@ __attribute__((noinline)) void debug_break(void) {
|
||||
#endif
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
static inline UINT8 inb(UINT16 port) {
|
||||
UINT8 value;
|
||||
static inline uint8_t inb(uint16_t port) {
|
||||
uint8_t value;
|
||||
asm volatile("inb %1, %0" : "=a"(value) : "Nd"(port));
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline void outb(UINT16 port, UINT8 value) {
|
||||
static inline void outb(uint16_t port, uint8_t value) {
|
||||
asm volatile("outb %0, %1" : : "a"(value), "Nd"(port));
|
||||
}
|
||||
|
||||
@@ -663,12 +663,12 @@ void beep(UINTN beep_count) {
|
||||
};
|
||||
|
||||
/* Set frequency. */
|
||||
UINT32 counter = PIT_FREQUENCY / PITCH;
|
||||
uint32_t counter = PIT_FREQUENCY / PITCH;
|
||||
outb(TIMER_CONTROL_PORT, TIMER_PORT_MAGIC);
|
||||
outb(TIMER_CONTROL2_PORT, counter & 0xFF);
|
||||
outb(TIMER_CONTROL2_PORT, (counter >> 8) & 0xFF);
|
||||
|
||||
UINT8 value = inb(SPEAKER_CONTROL_PORT);
|
||||
uint8_t value = inb(SPEAKER_CONTROL_PORT);
|
||||
|
||||
while (beep_count > 0) {
|
||||
/* Turn speaker on. */
|
||||
|
||||
+26
-32
@@ -9,17 +9,11 @@
|
||||
|
||||
#define UINTN_MAX (~(UINTN)0)
|
||||
#define INTN_MAX ((INTN)(UINTN_MAX>>1))
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX ((UINT32) -1)
|
||||
#endif
|
||||
#ifndef UINT64_MAX
|
||||
#define UINT64_MAX ((UINT64) -1)
|
||||
#endif
|
||||
|
||||
/* gnu-efi format specifiers for integers are fixed to either 64bit with 'l' and 32bit without a size prefix.
|
||||
* We rely on %u/%d/%x to format regular ints, so ensure the size is what we expect. At the same time, we also
|
||||
* need specifiers for (U)INTN which are native (pointer) sized. */
|
||||
assert_cc(sizeof(int) == sizeof(UINT32));
|
||||
assert_cc(sizeof(int) == sizeof(uint32_t));
|
||||
#if __SIZEOF_POINTER__ == 4
|
||||
# define PRIuN L"u"
|
||||
# define PRIiN L"d"
|
||||
@@ -72,29 +66,29 @@ static inline void *xrealloc(void *p, size_t old_size, size_t new_size) {
|
||||
return r;
|
||||
}
|
||||
|
||||
#define xpool_print(fmt, ...) ((CHAR16 *) ASSERT_SE_PTR(PoolPrint((fmt), ##__VA_ARGS__)))
|
||||
#define xpool_print(fmt, ...) ((char16_t *) ASSERT_SE_PTR(PoolPrint((fmt), ##__VA_ARGS__)))
|
||||
#define xnew(type, n) ((type *) xmalloc_multiply(sizeof(type), (n)))
|
||||
|
||||
EFI_STATUS parse_boolean(const CHAR8 *v, BOOLEAN *b);
|
||||
EFI_STATUS parse_boolean(const char *v, bool *b);
|
||||
|
||||
EFI_STATUS efivar_set(const EFI_GUID *vendor, const CHAR16 *name, const CHAR16 *value, UINT32 flags);
|
||||
EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const CHAR16 *name, const void *buf, UINTN size, UINT32 flags);
|
||||
EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN i, UINT32 flags);
|
||||
EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const CHAR16 *NAME, UINT32 value, UINT32 flags);
|
||||
EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 value, UINT32 flags);
|
||||
void efivar_set_time_usec(const EFI_GUID *vendor, const CHAR16 *name, UINT64 usec);
|
||||
EFI_STATUS efivar_set(const EFI_GUID *vendor, const char16_t *name, const char16_t *value, uint32_t flags);
|
||||
EFI_STATUS efivar_set_raw(const EFI_GUID *vendor, const char16_t *name, const void *buf, UINTN size, uint32_t flags);
|
||||
EFI_STATUS efivar_set_uint_string(const EFI_GUID *vendor, const char16_t *name, UINTN i, uint32_t flags);
|
||||
EFI_STATUS efivar_set_uint32_le(const EFI_GUID *vendor, const char16_t *NAME, uint32_t value, uint32_t flags);
|
||||
EFI_STATUS efivar_set_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t value, uint32_t flags);
|
||||
void efivar_set_time_usec(const EFI_GUID *vendor, const char16_t *name, uint64_t usec);
|
||||
|
||||
EFI_STATUS efivar_get(const EFI_GUID *vendor, const CHAR16 *name, CHAR16 **value);
|
||||
EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const CHAR16 *name, CHAR8 **buffer, UINTN *size);
|
||||
EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const CHAR16 *name, UINTN *i);
|
||||
EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const CHAR16 *name, UINT32 *ret);
|
||||
EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const CHAR16 *name, UINT64 *ret);
|
||||
EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const CHAR16 *name, BOOLEAN *ret);
|
||||
EFI_STATUS efivar_get(const EFI_GUID *vendor, const char16_t *name, char16_t **value);
|
||||
EFI_STATUS efivar_get_raw(const EFI_GUID *vendor, const char16_t *name, char **buffer, UINTN *size);
|
||||
EFI_STATUS efivar_get_uint_string(const EFI_GUID *vendor, const char16_t *name, UINTN *i);
|
||||
EFI_STATUS efivar_get_uint32_le(const EFI_GUID *vendor, const char16_t *name, uint32_t *ret);
|
||||
EFI_STATUS efivar_get_uint64_le(const EFI_GUID *vendor, const char16_t *name, uint64_t *ret);
|
||||
EFI_STATUS efivar_get_boolean_u8(const EFI_GUID *vendor, const char16_t *name, bool *ret);
|
||||
|
||||
CHAR16 *xstra_to_path(const CHAR8 *stra);
|
||||
CHAR16 *xstra_to_str(const CHAR8 *stra);
|
||||
char16_t *xstra_to_path(const char *stra);
|
||||
char16_t *xstra_to_str(const char *stra);
|
||||
|
||||
EFI_STATUS file_read(EFI_FILE *dir, const CHAR16 *name, UINTN off, UINTN size, CHAR8 **content, UINTN *content_size);
|
||||
EFI_STATUS file_read(EFI_FILE *dir, const char16_t *name, UINTN off, UINTN size, char **content, UINTN *content_size);
|
||||
|
||||
static inline void file_closep(EFI_FILE **handle) {
|
||||
if (!*handle)
|
||||
@@ -117,7 +111,7 @@ static inline void unload_imagep(EFI_HANDLE *image) {
|
||||
&(const EFI_GUID) { 0x4a67b082, 0x0a4c, 0x41cf, { 0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } }
|
||||
#define EFI_GLOBAL_GUID &(const EFI_GUID) EFI_GLOBAL_VARIABLE
|
||||
|
||||
void log_error_stall(const CHAR16 *fmt, ...);
|
||||
void log_error_stall(const char16_t *fmt, ...);
|
||||
EFI_STATUS log_oom(void);
|
||||
|
||||
/* This works just like log_error_errno() from userspace, but requires you
|
||||
@@ -128,7 +122,7 @@ EFI_STATUS log_oom(void);
|
||||
err; \
|
||||
})
|
||||
|
||||
void print_at(UINTN x, UINTN y, UINTN attr, const CHAR16 *str);
|
||||
void print_at(UINTN x, UINTN y, UINTN attr, const char16_t *str);
|
||||
void clear_screen(UINTN attr);
|
||||
|
||||
typedef int (*compare_pointer_func_t)(const void *a, const void *b);
|
||||
@@ -138,15 +132,15 @@ EFI_STATUS get_file_info_harder(EFI_FILE *handle, EFI_FILE_INFO **ret, UINTN *re
|
||||
|
||||
EFI_STATUS readdir_harder(EFI_FILE *handle, EFI_FILE_INFO **buffer, UINTN *buffer_size);
|
||||
|
||||
BOOLEAN is_ascii(const CHAR16 *f);
|
||||
bool is_ascii(const char16_t *f);
|
||||
|
||||
CHAR16 **strv_free(CHAR16 **l);
|
||||
char16_t **strv_free(char16_t **l);
|
||||
|
||||
static inline void strv_freep(CHAR16 ***p) {
|
||||
static inline void strv_freep(char16_t ***p) {
|
||||
strv_free(*p);
|
||||
}
|
||||
|
||||
EFI_STATUS open_directory(EFI_FILE *root_dir, const CHAR16 *path, EFI_FILE **ret);
|
||||
EFI_STATUS open_directory(EFI_FILE *root_dir, const char16_t *path, EFI_FILE **ret);
|
||||
|
||||
/* Conversion between EFI_PHYSICAL_ADDRESS and pointers is not obvious. The former is always 64bit, even on
|
||||
* 32bit archs. And gcc complains if we cast a pointer to an integer of a different size. Hence let's do the
|
||||
@@ -168,11 +162,11 @@ static inline void *PHYSICAL_ADDRESS_TO_POINTER(EFI_PHYSICAL_ADDRESS addr) {
|
||||
return (void*) (UINTN) addr;
|
||||
}
|
||||
|
||||
UINT64 get_os_indications_supported(void);
|
||||
uint64_t get_os_indications_supported(void);
|
||||
|
||||
#ifdef EFI_DEBUG
|
||||
void debug_break(void);
|
||||
extern UINT8 _text, _data;
|
||||
extern uint8_t _text, _data;
|
||||
/* Report the relocated position of text and data sections so that a debugger
|
||||
* can attach to us. See debug-sd-boot.sh for how this can be done. */
|
||||
# define debug_hook(identity) Print(identity L"@0x%lx,0x%lx\n", POINTER_TO_PHYSICAL_ADDRESS(&_text), POINTER_TO_PHYSICAL_ADDRESS(&_data))
|
||||
|
||||
+23
-23
@@ -16,11 +16,11 @@ static EFI_DEVICE_PATH *path_chop(EFI_DEVICE_PATH *path, EFI_DEVICE_PATH *node)
|
||||
assert(path);
|
||||
assert(node);
|
||||
|
||||
UINTN len = (UINT8 *) node - (UINT8 *) path;
|
||||
UINTN len = (uint8_t *) node - (uint8_t *) path;
|
||||
EFI_DEVICE_PATH *chopped = xmalloc(len + END_DEVICE_PATH_LENGTH);
|
||||
|
||||
memcpy(chopped, path, len);
|
||||
SetDevicePathEndNode((EFI_DEVICE_PATH *) ((UINT8 *) chopped + len));
|
||||
SetDevicePathEndNode((EFI_DEVICE_PATH *) ((uint8_t *) chopped + len));
|
||||
|
||||
return chopped;
|
||||
}
|
||||
@@ -41,9 +41,9 @@ static EFI_DEVICE_PATH *path_dup(const EFI_DEVICE_PATH *dp) {
|
||||
return dup;
|
||||
}
|
||||
|
||||
static BOOLEAN verify_gpt(union GptHeaderBuffer *gpt_header_buffer, EFI_LBA lba_expected) {
|
||||
static bool verify_gpt(union GptHeaderBuffer *gpt_header_buffer, EFI_LBA lba_expected) {
|
||||
EFI_PARTITION_TABLE_HEADER *h;
|
||||
UINT32 crc32, crc32_saved;
|
||||
uint32_t crc32, crc32_saved;
|
||||
EFI_STATUS err;
|
||||
|
||||
assert(gpt_header_buffer);
|
||||
@@ -52,36 +52,36 @@ static BOOLEAN verify_gpt(union GptHeaderBuffer *gpt_header_buffer, EFI_LBA lba_
|
||||
|
||||
/* Some superficial validation of the GPT header */
|
||||
if (memcmp(&h->Header.Signature, "EFI PART", sizeof(h->Header.Signature)) != 0)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
if (h->Header.HeaderSize < 92 || h->Header.HeaderSize > 512)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
if (h->Header.Revision != 0x00010000U)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
/* Calculate CRC check */
|
||||
crc32_saved = h->Header.CRC32;
|
||||
h->Header.CRC32 = 0;
|
||||
err = BS->CalculateCrc32(gpt_header_buffer, h->Header.HeaderSize, &crc32);
|
||||
h->Header.CRC32 = crc32_saved;
|
||||
if (EFI_ERROR(err) || crc32 != crc32_saved)
|
||||
return FALSE;
|
||||
if (err != EFI_SUCCESS || crc32 != crc32_saved)
|
||||
return false;
|
||||
|
||||
if (h->MyLBA != lba_expected)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
if (h->SizeOfPartitionEntry < sizeof(EFI_PARTITION_ENTRY))
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
if (h->NumberOfPartitionEntries <= 0 || h->NumberOfPartitionEntries > 1024)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
/* overflow check */
|
||||
if (h->SizeOfPartitionEntry > UINTN_MAX / h->NumberOfPartitionEntries)
|
||||
return FALSE;
|
||||
return false;
|
||||
|
||||
return TRUE;
|
||||
return true;
|
||||
}
|
||||
|
||||
static EFI_STATUS try_gpt(
|
||||
@@ -93,7 +93,7 @@ static EFI_STATUS try_gpt(
|
||||
_cleanup_freepool_ EFI_PARTITION_ENTRY *entries = NULL;
|
||||
union GptHeaderBuffer gpt;
|
||||
EFI_STATUS err;
|
||||
UINT32 crc32;
|
||||
uint32_t crc32;
|
||||
UINTN size;
|
||||
|
||||
assert(block_io);
|
||||
@@ -105,7 +105,7 @@ static EFI_STATUS try_gpt(
|
||||
block_io->Media->MediaId,
|
||||
lba,
|
||||
sizeof(gpt), &gpt);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Indicate the location of backup LBA even if the rest of the header is corrupt. */
|
||||
@@ -124,12 +124,12 @@ static EFI_STATUS try_gpt(
|
||||
block_io->Media->MediaId,
|
||||
gpt.gpt_header.PartitionEntryLBA,
|
||||
size, entries);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Calculate CRC of entries array, too */
|
||||
err = BS->CalculateCrc32(entries, size, &crc32);
|
||||
if (EFI_ERROR(err) || crc32 != gpt.gpt_header.PartitionEntryArrayCRC32)
|
||||
if (err != EFI_SUCCESS || crc32 != gpt.gpt_header.PartitionEntryArrayCRC32)
|
||||
return EFI_CRC_ERROR;
|
||||
|
||||
/* Now we can finally look for xbootloader partitions. */
|
||||
@@ -137,7 +137,7 @@ static EFI_STATUS try_gpt(
|
||||
EFI_PARTITION_ENTRY *entry;
|
||||
EFI_LBA start, end;
|
||||
|
||||
entry = (EFI_PARTITION_ENTRY*) ((UINT8*) entries + gpt.gpt_header.SizeOfPartitionEntry * i);
|
||||
entry = (EFI_PARTITION_ENTRY*) ((uint8_t*) entries + gpt.gpt_header.SizeOfPartitionEntry * i);
|
||||
|
||||
if (memcmp(&entry->PartitionTypeGUID, XBOOTLDR_GUID, sizeof(entry->PartitionTypeGUID)) != 0)
|
||||
continue;
|
||||
@@ -197,11 +197,11 @@ static EFI_STATUS find_device(EFI_HANDLE *device, EFI_DEVICE_PATH **ret_device_p
|
||||
EFI_HANDLE disk_handle;
|
||||
EFI_BLOCK_IO *block_io;
|
||||
err = BS->LocateDevicePath(&BlockIoProtocol, &p, &disk_handle);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = BS->HandleProtocol(disk_handle, &BlockIoProtocol, (void **)&block_io);
|
||||
if (EFI_ERROR(err))
|
||||
if (err != EFI_SUCCESS)
|
||||
return err;
|
||||
|
||||
/* Filter out some block devices early. (We only care about block devices that aren't
|
||||
@@ -234,7 +234,7 @@ static EFI_STATUS find_device(EFI_HANDLE *device, EFI_DEVICE_PATH **ret_device_p
|
||||
block_io, lba,
|
||||
nr == 0 ? &backup_lba : NULL, /* Only get backup LBA location from first GPT header. */
|
||||
&hd);
|
||||
if (EFI_ERROR(err)) {
|
||||
if (err != EFI_SUCCESS) {
|
||||
/* GPT was valid but no XBOOT loader partition found. */
|
||||
if (err == EFI_NOT_FOUND)
|
||||
break;
|
||||
@@ -244,7 +244,7 @@ static EFI_STATUS find_device(EFI_HANDLE *device, EFI_DEVICE_PATH **ret_device_p
|
||||
|
||||
/* Patch in the data we found */
|
||||
EFI_DEVICE_PATH *xboot_path = path_dup(partition_path);
|
||||
memcpy((UINT8 *) xboot_path + ((UINT8 *) part_node - (UINT8 *) partition_path), &hd, sizeof(hd));
|
||||
memcpy((uint8_t *) xboot_path + ((uint8_t *) part_node - (uint8_t *) partition_path), &hd, sizeof(hd));
|
||||
*ret_device_path = xboot_path;
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "bootspec-fundamental.h"
|
||||
|
||||
sd_bool bootspec_pick_name_version_sort_key(
|
||||
bool bootspec_pick_name_version_sort_key(
|
||||
const sd_char *os_pretty_name,
|
||||
const sd_char *os_image_id,
|
||||
const sd_char *os_name,
|
||||
@@ -47,7 +47,7 @@ sd_bool bootspec_pick_name_version_sort_key(
|
||||
good_sort_key = os_image_id ?: os_id;
|
||||
|
||||
if (!good_name)
|
||||
return sd_false;
|
||||
return false;
|
||||
|
||||
if (ret_name)
|
||||
*ret_name = good_name;
|
||||
@@ -58,5 +58,5 @@ sd_bool bootspec_pick_name_version_sort_key(
|
||||
if (ret_sort_key)
|
||||
*ret_sort_key = good_sort_key;
|
||||
|
||||
return sd_true;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "types-fundamental.h"
|
||||
#include "string-util-fundamental.h"
|
||||
|
||||
sd_bool bootspec_pick_name_version_sort_key(
|
||||
bool bootspec_pick_name_version_sort_key(
|
||||
const sd_char *os_pretty_name,
|
||||
const sd_char *os_image_id,
|
||||
const sd_char *os_name,
|
||||
|
||||
@@ -16,12 +16,7 @@ const sd_char *secure_boot_mode_to_string(SecureBootMode m) {
|
||||
return (m >= 0 && m < _SECURE_BOOT_MAX) ? table[m] : NULL;
|
||||
}
|
||||
|
||||
SecureBootMode decode_secure_boot_mode(
|
||||
sd_bool secure,
|
||||
sd_bool audit,
|
||||
sd_bool deployed,
|
||||
sd_bool setup) {
|
||||
|
||||
SecureBootMode decode_secure_boot_mode(bool secure, bool audit, bool deployed, bool setup) {
|
||||
/* See figure 32-4 Secure Boot Modes from UEFI Specification 2.9 */
|
||||
if (secure && deployed && !audit && !setup)
|
||||
return SECURE_BOOT_DEPLOYED;
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
#include <errno.h>
|
||||
#include "string-util-fundamental.h"
|
||||
|
||||
#ifndef UINT64_C
|
||||
# define UINT64_C(c) (c ## ULL)
|
||||
#endif
|
||||
|
||||
#define EFI_LOADER_FEATURE_CONFIG_TIMEOUT (UINT64_C(1) << 0)
|
||||
#define EFI_LOADER_FEATURE_CONFIG_TIMEOUT_ONE_SHOT (UINT64_C(1) << 1)
|
||||
#define EFI_LOADER_FEATURE_ENTRY_DEFAULT (UINT64_C(1) << 2)
|
||||
@@ -30,8 +26,4 @@ typedef enum SecureBootMode {
|
||||
} SecureBootMode;
|
||||
|
||||
const sd_char *secure_boot_mode_to_string(SecureBootMode m);
|
||||
SecureBootMode decode_secure_boot_mode(
|
||||
sd_bool secure,
|
||||
sd_bool audit,
|
||||
sd_bool deployed,
|
||||
sd_bool setup);
|
||||
SecureBootMode decode_secure_boot_mode(bool secure, bool audit, bool deployed, bool setup);
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
|
||||
#ifndef SD_BOOT
|
||||
# include <assert.h>
|
||||
# include <stddef.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
#include "types-fundamental.h"
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define _align_(x) __attribute__((__aligned__(x)))
|
||||
#define _alignas_(x) __attribute__((__aligned__(__alignof__(x))))
|
||||
@@ -105,10 +106,10 @@
|
||||
* on this macro will run concurrently to all other code conditionalized
|
||||
* the same way, there's no ordering or completion enforced. */
|
||||
#define ONCE __ONCE(UNIQ_T(_once_, UNIQ))
|
||||
#define __ONCE(o) \
|
||||
({ \
|
||||
static sd_bool (o) = sd_false; \
|
||||
__sync_bool_compare_and_swap(&(o), sd_false, sd_true); \
|
||||
#define __ONCE(o) \
|
||||
({ \
|
||||
static bool (o) = false; \
|
||||
__sync_bool_compare_and_swap(&(o), false, true); \
|
||||
})
|
||||
|
||||
#undef MAX
|
||||
@@ -258,7 +259,7 @@
|
||||
|
||||
#define IN_SET(x, ...) \
|
||||
({ \
|
||||
sd_bool _found = sd_false; \
|
||||
bool _found = false; \
|
||||
/* If the build breaks in the line below, you need to extend the case macros. (We use "long double" as \
|
||||
* type for the array, in the hope that checkers such as ubsan don't complain that the initializers for \
|
||||
* the array are not representable by the base type. Ideally we'd use typeof(x) as base type, but that \
|
||||
@@ -267,7 +268,7 @@
|
||||
assert_cc(ELEMENTSOF(__assert_in_set) <= 20); \
|
||||
switch (x) { \
|
||||
FOR_EACH_MAKE_CASE(__VA_ARGS__) \
|
||||
_found = sd_true; \
|
||||
_found = true; \
|
||||
break; \
|
||||
default: \
|
||||
break; \
|
||||
@@ -299,9 +300,6 @@
|
||||
})
|
||||
|
||||
static inline size_t ALIGN_TO(size_t l, size_t ali) {
|
||||
/* sd-boot uses UINTN for size_t, let's make sure SIZE_MAX is correct. */
|
||||
assert_cc(SIZE_MAX == ~(size_t)0);
|
||||
|
||||
/* Check that alignment is exponent of 2 */
|
||||
#if SIZE_MAX == UINT_MAX
|
||||
assert(__builtin_popcount(ali) == 1);
|
||||
|
||||
@@ -8,7 +8,6 @@ fundamental_headers = files(
|
||||
'macro-fundamental.h',
|
||||
'sha256.h',
|
||||
'string-util-fundamental.h',
|
||||
'types-fundamental.h',
|
||||
)
|
||||
|
||||
# for sd-boot
|
||||
|
||||
@@ -77,21 +77,21 @@ sd_char* endswith_no_case(const sd_char *s, const sd_char *postfix) {
|
||||
return (sd_char*) s + sl - pl;
|
||||
}
|
||||
|
||||
static sd_bool is_digit(sd_char a) {
|
||||
static bool is_digit(sd_char a) {
|
||||
/* Locale-independent version of isdigit(). */
|
||||
return a >= '0' && a <= '9';
|
||||
}
|
||||
|
||||
static sd_bool is_alpha(sd_char a) {
|
||||
static bool is_alpha(sd_char a) {
|
||||
/* Locale-independent version of isalpha(). */
|
||||
return (a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z');
|
||||
}
|
||||
|
||||
static sd_bool is_valid_version_char(sd_char a) {
|
||||
static bool is_valid_version_char(sd_char a) {
|
||||
return is_digit(a) || is_alpha(a) || IN_SET(a, '~', '-', '^', '.');
|
||||
}
|
||||
|
||||
sd_int strverscmp_improved(const sd_char *a, const sd_char *b) {
|
||||
int strverscmp_improved(const sd_char *a, const sd_char *b) {
|
||||
/* This function is similar to strverscmp(3), but it treats '-' and '.' as separators.
|
||||
*
|
||||
* The logic is based on rpm's rpmvercmp(), but unlike rpmvercmp(), it distiguishes e.g.
|
||||
@@ -129,7 +129,7 @@ sd_int strverscmp_improved(const sd_char *a, const sd_char *b) {
|
||||
|
||||
for (;;) {
|
||||
const sd_char *aa, *bb;
|
||||
sd_int r;
|
||||
int r;
|
||||
|
||||
/* Drop leading invalid characters. */
|
||||
while (*a != '\0' && !is_valid_version_char(*a))
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
# define strcasecmp strcasecmp16
|
||||
# define strncasecmp strncasecmp16
|
||||
# define STR_C(str) (L ## str)
|
||||
typedef char16_t sd_char;
|
||||
#else
|
||||
# define STR_C(str) (str)
|
||||
typedef char sd_char;
|
||||
#endif
|
||||
|
||||
#define streq(a,b) (strcmp((a),(b)) == 0)
|
||||
@@ -27,25 +29,25 @@
|
||||
#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
|
||||
#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
|
||||
|
||||
static inline sd_int strcmp_ptr(const sd_char *a, const sd_char *b) {
|
||||
static inline int strcmp_ptr(const sd_char *a, const sd_char *b) {
|
||||
if (a && b)
|
||||
return strcmp(a, b);
|
||||
|
||||
return CMP(a, b);
|
||||
}
|
||||
|
||||
static inline sd_int strcasecmp_ptr(const sd_char *a, const sd_char *b) {
|
||||
static inline int strcasecmp_ptr(const sd_char *a, const sd_char *b) {
|
||||
if (a && b)
|
||||
return strcasecmp(a, b);
|
||||
|
||||
return CMP(a, b);
|
||||
}
|
||||
|
||||
static inline sd_bool streq_ptr(const sd_char *a, const sd_char *b) {
|
||||
static inline bool streq_ptr(const sd_char *a, const sd_char *b) {
|
||||
return strcmp_ptr(a, b) == 0;
|
||||
}
|
||||
|
||||
static inline sd_bool strcaseeq_ptr(const sd_char *a, const sd_char *b) {
|
||||
static inline bool strcaseeq_ptr(const sd_char *a, const sd_char *b) {
|
||||
return strcasecmp_ptr(a, b) == 0;
|
||||
}
|
||||
|
||||
@@ -63,7 +65,7 @@ sd_char *startswith_no_case(const sd_char *s, const sd_char *prefix) _pure_;
|
||||
sd_char *endswith(const sd_char *s, const sd_char *postfix) _pure_;
|
||||
sd_char *endswith_no_case(const sd_char *s, const sd_char *postfix) _pure_;
|
||||
|
||||
static inline sd_bool isempty(const sd_char *a) {
|
||||
static inline bool isempty(const sd_char *a) {
|
||||
return !a || a[0] == '\0';
|
||||
}
|
||||
|
||||
@@ -71,7 +73,7 @@ static inline const sd_char *strempty(const sd_char *s) {
|
||||
return s ?: STR_C("");
|
||||
}
|
||||
|
||||
static inline const sd_char *yes_no(sd_bool b) {
|
||||
static inline const sd_char *yes_no(bool b) {
|
||||
return b ? STR_C("yes") : STR_C("no");
|
||||
}
|
||||
|
||||
@@ -79,7 +81,7 @@ static inline const sd_char* comparison_operator(int result) {
|
||||
return result < 0 ? STR_C("<") : result > 0 ? STR_C(">") : STR_C("==");
|
||||
}
|
||||
|
||||
sd_int strverscmp_improved(const sd_char *a, const sd_char *b);
|
||||
int strverscmp_improved(const sd_char *a, const sd_char *b);
|
||||
|
||||
/* Like startswith(), but operates on arbitrary memory blocks */
|
||||
static inline void *memory_startswith(const void *p, size_t sz, const sd_char *token) {
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
/* This defines a number of basic types that are one thing in userspace and another in the UEFI environment,
|
||||
* but mostly the same in concept and behaviour.
|
||||
*
|
||||
* Note: if the definition of these types/values has slightly different semantics in userspace and in the
|
||||
* UEFI environment then please prefix its name with "sd_" to make clear these types have special semantics,
|
||||
* and *we* defined them. Otherwise, if the types are effectively 100% identical in behaviour in userspace
|
||||
* and UEFI environment you can omit the prefix. (Examples: sd_char is 8 bit in userspace and 16 bit in UEFI
|
||||
* space hence it should have the sd_ prefix; but size_t in userspace and UINTN in UEFI environment are 100%
|
||||
* defined the same way ultimately, hence it's OK to just define size_t as alias to UINTN in UEFI
|
||||
* environment, so that size_t can be used everywhere, without any "sd_" prefix.)
|
||||
*
|
||||
* Note: we generally prefer the userspace names of types and concepts. i.e. if in doubt please name types
|
||||
* after the userspace vocabulary, and let's keep UEFI vocabulary specific to the UEFI build environment. */
|
||||
|
||||
#ifdef SD_BOOT
|
||||
#include <efi.h>
|
||||
|
||||
typedef BOOLEAN sd_bool;
|
||||
typedef CHAR16 sd_char;
|
||||
typedef INTN sd_int;
|
||||
typedef UINTN size_t;
|
||||
|
||||
#define sd_true TRUE
|
||||
#define sd_false FALSE
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
typedef bool sd_bool;
|
||||
typedef char sd_char;
|
||||
typedef int sd_int;
|
||||
|
||||
#define sd_true true
|
||||
#define sd_false false
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user