Merge pull request #23842 from medhefgo/boot-std

boot: Use standard types
This commit is contained in:
Yu Watanabe
2022-06-27 22:32:31 +09:00
committed by GitHub
45 changed files with 1098 additions and 1156 deletions
+68 -84
View File
@@ -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
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+33 -33
View File
@@ -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:
+6 -6
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+4 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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++;
+4 -4
View File
@@ -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, &current, &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;
}
+2 -1
View File
@@ -6,5 +6,6 @@
#pragma once
#include <efi.h>
#include <stdbool.h>
EFI_STATUS graphics_mode(BOOLEAN on);
EFI_STATUS graphics_mode(bool on);
+3 -3
View File
@@ -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
View File
@@ -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 */
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+9 -7
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+2 -1
View File
@@ -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",
+6 -6
View File
@@ -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);
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -11,6 +11,6 @@
#include <efi.h>
BOOLEAN shim_loaded(void);
bool shim_loaded(void);
EFI_STATUS security_policy_install(void);
+38 -38
View File
@@ -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(
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+2 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}
+3 -3
View File
@@ -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;
}
+2 -2
View File
@@ -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,
+1 -6
View File
@@ -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;
+1 -9
View File
@@ -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);
+9 -11
View File
@@ -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);
-1
View File
@@ -8,7 +8,6 @@ fundamental_headers = files(
'macro-fundamental.h',
'sha256.h',
'string-util-fundamental.h',
'types-fundamental.h',
)
# for sd-boot
+5 -5
View File
@@ -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))
+9 -7
View File
@@ -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) {
-39
View File
@@ -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