Merge pull request #34717 from anonymix007/fundamental-boot-changes
Fundamental and boot changes for multi-dt UKIs
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
#include "sbat.h"
|
||||
#include "secure-boot.h"
|
||||
#include "shim.h"
|
||||
#include "smbios.h"
|
||||
#include "ticks.h"
|
||||
#include "tpm2-pcr.h"
|
||||
#include "uki.h"
|
||||
|
||||
@@ -68,6 +68,8 @@ typedef uint64_t EFI_PHYSICAL_ADDRESS;
|
||||
# error Unsupported pointer size
|
||||
#endif
|
||||
|
||||
#define EFI_STATUS_IS_ERROR(s) (((s) & EFI_ERROR_MASK) != 0)
|
||||
|
||||
#define EFIWARN(s) ((EFI_STATUS) s)
|
||||
#define EFIERR(s) ((EFI_STATUS) (s | EFI_ERROR_MASK))
|
||||
|
||||
|
||||
+3
-4
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "log.h"
|
||||
#include "proto/rng.h"
|
||||
#include "proto/simple-text-io.h"
|
||||
#include "util.h"
|
||||
|
||||
static unsigned log_count = 0;
|
||||
@@ -32,14 +31,14 @@ void efi_assert(const char *expr, const char *file, unsigned line, const char *f
|
||||
freeze();
|
||||
}
|
||||
|
||||
EFI_STATUS log_internal(EFI_STATUS status, const char *format, ...) {
|
||||
EFI_STATUS log_internal(EFI_STATUS status, uint8_t text_color, const char *format, ...) {
|
||||
assert(format);
|
||||
|
||||
int32_t attr = ST->ConOut->Mode->Attribute;
|
||||
|
||||
if (ST->ConOut->Mode->CursorColumn > 0)
|
||||
ST->ConOut->OutputString(ST->ConOut, (char16_t *) u"\r\n");
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_TEXT_ATTR(EFI_LIGHTRED, EFI_BLACK));
|
||||
ST->ConOut->SetAttribute(ST->ConOut, EFI_TEXT_ATTR(text_color, EFI_BLACK));
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
@@ -58,7 +57,7 @@ void log_hexdump(const char16_t *prefix, const void *data, size_t size) {
|
||||
/* Debugging helper — please keep this around, even if not used */
|
||||
|
||||
_cleanup_free_ char16_t *hex = hexdump(data, size);
|
||||
log_internal(EFI_SUCCESS, "%ls[%zu]: %ls", prefix, size, hex);
|
||||
log_internal(EFI_SUCCESS, EFI_LIGHTRED, "%ls[%zu]: %ls", prefix, size, hex);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+8
-5
@@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "efi-string.h"
|
||||
#include "proto/simple-text-io.h"
|
||||
|
||||
#if defined __has_attribute
|
||||
# if __has_attribute(no_stack_protector)
|
||||
@@ -21,11 +22,13 @@ __attribute__((no_stack_protector, noinline)) void __stack_chk_guard_init(void);
|
||||
|
||||
_noreturn_ void freeze(void);
|
||||
void log_wait(void);
|
||||
_gnu_printf_(2, 3) EFI_STATUS log_internal(EFI_STATUS status, const char *format, ...);
|
||||
#define log_error_status(status, ...) log_internal(status, __VA_ARGS__)
|
||||
#define log_error(...) log_internal(EFI_INVALID_PARAMETER, __VA_ARGS__)
|
||||
#define log_oom() log_internal(EFI_OUT_OF_RESOURCES, "Out of memory.")
|
||||
#define log_trace() log_internal(EFI_SUCCESS, "%s:%i@%s", __FILE__, __LINE__, __func__)
|
||||
_gnu_printf_(3, 4) EFI_STATUS log_internal(EFI_STATUS status, uint8_t text_color, const char *format, ...);
|
||||
#define log_debug(...) log_internal(EFI_SUCCESS, EFI_LIGHTGRAY, __VA_ARGS__)
|
||||
#define log_info(...) log_internal(EFI_SUCCESS, EFI_WHITE, __VA_ARGS__)
|
||||
#define log_error_status(status, ...) log_internal(status, EFI_LIGHTRED, __VA_ARGS__)
|
||||
#define log_error(...) log_internal(EFI_INVALID_PARAMETER, EFI_LIGHTRED, __VA_ARGS__)
|
||||
#define log_oom() log_internal(EFI_OUT_OF_RESOURCES, EFI_LIGHTRED, "Out of memory.")
|
||||
#define log_trace() log_internal(EFI_SUCCESS, EFI_LIGHTRED, "%s:%i@%s", __FILE__, __LINE__, __func__)
|
||||
|
||||
#ifdef EFI_DEBUG
|
||||
void log_hexdump(const char16_t *prefix, const void *data, size_t size);
|
||||
|
||||
@@ -270,6 +270,7 @@ libefi_sources = files(
|
||||
'random-seed.c',
|
||||
'secure-boot.c',
|
||||
'shim.c',
|
||||
'smbios.c',
|
||||
'ticks.c',
|
||||
'util.c',
|
||||
'vmm.c',
|
||||
|
||||
@@ -0,0 +1,250 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "efi-string.h"
|
||||
#include "efivars.h"
|
||||
#include "proto/device-path.h"
|
||||
#include "smbios.h"
|
||||
#include "string-util-fundamental.h"
|
||||
#include "util.h"
|
||||
|
||||
#define SMBIOS_TABLE_GUID \
|
||||
GUID_DEF(0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
|
||||
#define SMBIOS3_TABLE_GUID \
|
||||
GUID_DEF(0xf2fd1544, 0x9794, 0x4a2c, 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94)
|
||||
|
||||
typedef struct {
|
||||
uint8_t anchor_string[4];
|
||||
uint8_t entry_point_structure_checksum;
|
||||
uint8_t entry_point_length;
|
||||
uint8_t major_version;
|
||||
uint8_t minor_version;
|
||||
uint16_t max_structure_size;
|
||||
uint8_t entry_point_revision;
|
||||
uint8_t formatted_area[5];
|
||||
uint8_t intermediate_anchor_string[5];
|
||||
uint8_t intermediate_checksum;
|
||||
uint16_t table_length;
|
||||
uint32_t table_address;
|
||||
uint16_t number_of_smbios_structures;
|
||||
uint8_t smbios_bcd_revision;
|
||||
} _packed_ SmbiosEntryPoint;
|
||||
|
||||
typedef struct {
|
||||
uint8_t anchor_string[5];
|
||||
uint8_t entry_point_structure_checksum;
|
||||
uint8_t entry_point_length;
|
||||
uint8_t major_version;
|
||||
uint8_t minor_version;
|
||||
uint8_t docrev;
|
||||
uint8_t entry_point_revision;
|
||||
uint8_t reserved;
|
||||
uint32_t table_maximum_size;
|
||||
uint64_t table_address;
|
||||
} _packed_ Smbios3EntryPoint;
|
||||
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t handle[2];
|
||||
} _packed_ SmbiosHeader;
|
||||
|
||||
typedef struct {
|
||||
SmbiosHeader header;
|
||||
uint8_t vendor;
|
||||
uint8_t bios_version;
|
||||
uint16_t bios_segment;
|
||||
uint8_t bios_release_date;
|
||||
uint8_t bios_size;
|
||||
uint64_t bios_characteristics;
|
||||
uint8_t bios_characteristics_ext[2];
|
||||
} _packed_ SmbiosTableType0;
|
||||
|
||||
typedef struct {
|
||||
SmbiosHeader header;
|
||||
uint8_t manufacturer;
|
||||
uint8_t product_name;
|
||||
uint8_t version;
|
||||
uint8_t serial_number;
|
||||
EFI_GUID uuid;
|
||||
uint8_t wake_up_type;
|
||||
uint8_t sku_number;
|
||||
uint8_t family;
|
||||
} _packed_ SmbiosTableType1;
|
||||
|
||||
typedef struct {
|
||||
SmbiosHeader header;
|
||||
uint8_t manufacturer;
|
||||
uint8_t product_name;
|
||||
uint8_t version;
|
||||
uint8_t serial_number;
|
||||
} _packed_ SmbiosTableType2;
|
||||
|
||||
typedef struct {
|
||||
SmbiosHeader header;
|
||||
uint8_t count;
|
||||
char contents[];
|
||||
} _packed_ SmbiosTableType11;
|
||||
|
||||
static const void *find_smbios_configuration_table(uint64_t *ret_size) {
|
||||
assert(ret_size);
|
||||
|
||||
const Smbios3EntryPoint *entry3 = find_configuration_table(MAKE_GUID_PTR(SMBIOS3_TABLE));
|
||||
if (entry3 && memcmp(entry3->anchor_string, "_SM3_", 5) == 0 &&
|
||||
entry3->entry_point_length <= sizeof(*entry3)) {
|
||||
*ret_size = entry3->table_maximum_size;
|
||||
return PHYSICAL_ADDRESS_TO_POINTER(entry3->table_address);
|
||||
}
|
||||
|
||||
const SmbiosEntryPoint *entry = find_configuration_table(MAKE_GUID_PTR(SMBIOS_TABLE));
|
||||
if (entry && memcmp(entry->anchor_string, "_SM_", 4) == 0 &&
|
||||
entry->entry_point_length <= sizeof(*entry)) {
|
||||
*ret_size = entry->table_length;
|
||||
return PHYSICAL_ADDRESS_TO_POINTER(entry->table_address);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const SmbiosHeader *get_smbios_table(uint8_t type, size_t min_size, uint64_t *ret_size_left) {
|
||||
uint64_t size = 0;
|
||||
const uint8_t *p = find_smbios_configuration_table(&size);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
for (;;) {
|
||||
if (size < sizeof(SmbiosHeader))
|
||||
return NULL;
|
||||
|
||||
const SmbiosHeader *header = (const SmbiosHeader *) p;
|
||||
|
||||
/* End of table. */
|
||||
if (header->type == 127)
|
||||
return NULL;
|
||||
|
||||
if (size < header->length)
|
||||
return NULL;
|
||||
|
||||
if (header->type == type) {
|
||||
/* Table is smaller than the minimum expected size? Refuse */
|
||||
if (header->length < min_size)
|
||||
return NULL;
|
||||
|
||||
if (ret_size_left)
|
||||
*ret_size_left = size;
|
||||
return header; /* Yay! */
|
||||
}
|
||||
|
||||
/* Skip over formatted area. */
|
||||
size -= header->length;
|
||||
p += header->length;
|
||||
|
||||
/* Special case: if there are no strings appended, we'll see two NUL bytes, skip over them */
|
||||
if (size >= 2 && p[0] == 0 && p[1] == 0) {
|
||||
size -= 2;
|
||||
p += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip over a populated string table. */
|
||||
bool first = true;
|
||||
for (;;) {
|
||||
const uint8_t *e = memchr(p, 0, size);
|
||||
if (!e)
|
||||
return NULL;
|
||||
|
||||
if (!first && e == p) {/* Double NUL byte means we've reached the end of the string table. */
|
||||
p++;
|
||||
size--;
|
||||
break;
|
||||
}
|
||||
|
||||
size -= e + 1 - p;
|
||||
p = e + 1;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool smbios_in_hypervisor(void) {
|
||||
/* Look up BIOS Information (Type 0). */
|
||||
const SmbiosTableType0 *type0 = (const SmbiosTableType0 *) get_smbios_table(0, sizeof(SmbiosTableType0), /* left= */ NULL);
|
||||
if (!type0)
|
||||
return false;
|
||||
|
||||
/* Bit 4 of 2nd BIOS characteristics extension bytes indicates virtualization. */
|
||||
return FLAGS_SET(type0->bios_characteristics_ext[1], 1 << 4);
|
||||
}
|
||||
|
||||
const char* smbios_find_oem_string(const char *name) {
|
||||
uint64_t left;
|
||||
|
||||
assert(name);
|
||||
|
||||
const SmbiosTableType11 *type11 = (const SmbiosTableType11 *) get_smbios_table(11, sizeof(SmbiosTableType11), &left);
|
||||
if (!type11)
|
||||
return NULL;
|
||||
|
||||
const char *s = type11->contents;
|
||||
|
||||
assert(left >= type11->header.length); /* get_smbios_table() already validated this */
|
||||
left -= type11->header.length;
|
||||
const char *limit = s + left;
|
||||
|
||||
for (const char *p = s; p < limit; ) {
|
||||
const char *e = memchr(p, 0, limit - p);
|
||||
if (!e || e == p) /* Double NUL byte means we've reached the end of the OEM strings. */
|
||||
break;
|
||||
|
||||
const char *eq = startswith8(p, name);
|
||||
if (eq && *eq == '=')
|
||||
return eq + 1;
|
||||
|
||||
p = e + 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* smbios_get_string(const SmbiosHeader *header, size_t nr, uint64_t left) {
|
||||
assert(header);
|
||||
const char *s = (const char *) header;
|
||||
|
||||
/* We assume that get_smbios_table() already validated the header size making some superficial sense */
|
||||
assert(left >= header->length);
|
||||
s += header->length;
|
||||
left -= header->length;
|
||||
|
||||
size_t index = 1;
|
||||
for (const char *p = s, *limit = s + left; index <= nr && p < limit; index++) {
|
||||
const char *e = memchr(p, 0, limit - p);
|
||||
if (!e || e == p) /* Double NUL byte means we've reached the end of the strings. */
|
||||
break;
|
||||
|
||||
if (index == nr)
|
||||
return p;
|
||||
|
||||
p = e + 1;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void smbios_raw_info_populate(RawSmbiosInfo *ret_info) {
|
||||
assert(ret_info);
|
||||
uint64_t left;
|
||||
|
||||
const SmbiosTableType1 *type1 = (const SmbiosTableType1 *) get_smbios_table(1, sizeof(SmbiosTableType1), &left);
|
||||
if (type1) {
|
||||
ret_info->manufacturer = smbios_get_string(&type1->header, type1->manufacturer, left);
|
||||
ret_info->product_name = smbios_get_string(&type1->header, type1->product_name, left);
|
||||
ret_info->product_sku = smbios_get_string(&type1->header, type1->sku_number, left);
|
||||
ret_info->family = smbios_get_string(&type1->header, type1->family, left);
|
||||
}
|
||||
|
||||
const SmbiosTableType2 *type2 = (const SmbiosTableType2 *) get_smbios_table(2, sizeof(SmbiosTableType2), &left);
|
||||
if (type2) {
|
||||
ret_info->baseboard_manufacturer = smbios_get_string(&type2->header, type2->manufacturer, left);
|
||||
ret_info->baseboard_product = smbios_get_string(&type2->header, type2->product_name, left);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "efi.h"
|
||||
|
||||
bool smbios_in_hypervisor(void);
|
||||
|
||||
const char* smbios_find_oem_string(const char *name);
|
||||
|
||||
typedef struct RawSmbiosInfo {
|
||||
const char *manufacturer;
|
||||
const char *product_name;
|
||||
const char *product_sku;
|
||||
const char *family;
|
||||
const char *baseboard_product;
|
||||
const char *baseboard_manufacturer;
|
||||
} RawSmbiosInfo;
|
||||
|
||||
void smbios_raw_info_populate(RawSmbiosInfo *ret_info);
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "sbat.h"
|
||||
#include "secure-boot.h"
|
||||
#include "shim.h"
|
||||
#include "smbios.h"
|
||||
#include "splash.h"
|
||||
#include "tpm2-pcr.h"
|
||||
#include "uki.h"
|
||||
|
||||
@@ -2,8 +2,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "efi.h"
|
||||
#include "efi-string.h"
|
||||
#include "log.h"
|
||||
#include "proto/file-io.h"
|
||||
#include "memory-util-fundamental.h"
|
||||
#include "string-util-fundamental.h"
|
||||
|
||||
/* This is provided by the linker. */
|
||||
@@ -31,6 +33,19 @@ static inline void freep(void *p) {
|
||||
_malloc_ _alloc_(1) _returns_nonnull_ _warn_unused_result_
|
||||
void *xmalloc(size_t size);
|
||||
|
||||
_malloc_ _alloc_(1) _returns_nonnull_ _warn_unused_result_
|
||||
static inline void *xcalloc(size_t size) {
|
||||
void *t = xmalloc(size);
|
||||
memzero(t, size);
|
||||
return t;
|
||||
}
|
||||
|
||||
_malloc_ _alloc_(1, 2) _returns_nonnull_ _warn_unused_result_
|
||||
static inline void *xcalloc_multiply(size_t n, size_t size) {
|
||||
assert_se(MUL_ASSIGN_SAFE(&size, n));
|
||||
return xcalloc(size);
|
||||
}
|
||||
|
||||
_malloc_ _alloc_(1, 2) _returns_nonnull_ _warn_unused_result_
|
||||
static inline void *xmalloc_multiply(size_t n, size_t size) {
|
||||
assert_se(MUL_ASSIGN_SAFE(&size, n));
|
||||
@@ -188,3 +203,12 @@ static inline bool efi_guid_equal(const EFI_GUID *a, const EFI_GUID *b) {
|
||||
void *find_configuration_table(const EFI_GUID *guid);
|
||||
|
||||
char16_t *get_extra_dir(const EFI_DEVICE_PATH *file_path);
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
# define be32toh(x) __builtin_bswap32(x)
|
||||
#else
|
||||
# error "Unexpected byte order in EFI mode?"
|
||||
#endif
|
||||
|
||||
#define bswap_16(x) __builtin_bswap16(x)
|
||||
#define bswap_32(x) __builtin_bswap32(x)
|
||||
|
||||
+1
-180
@@ -10,6 +10,7 @@
|
||||
#include "efi-string.h"
|
||||
#include "efivars.h"
|
||||
#include "proto/device-path.h"
|
||||
#include "smbios.h"
|
||||
#include "string-util-fundamental.h"
|
||||
#include "util.h"
|
||||
#include "vmm.h"
|
||||
@@ -135,156 +136,6 @@ static bool cpuid_in_hypervisor(void) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#define SMBIOS_TABLE_GUID \
|
||||
GUID_DEF(0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d)
|
||||
#define SMBIOS3_TABLE_GUID \
|
||||
GUID_DEF(0xf2fd1544, 0x9794, 0x4a2c, 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94)
|
||||
|
||||
typedef struct {
|
||||
uint8_t anchor_string[4];
|
||||
uint8_t entry_point_structure_checksum;
|
||||
uint8_t entry_point_length;
|
||||
uint8_t major_version;
|
||||
uint8_t minor_version;
|
||||
uint16_t max_structure_size;
|
||||
uint8_t entry_point_revision;
|
||||
uint8_t formatted_area[5];
|
||||
uint8_t intermediate_anchor_string[5];
|
||||
uint8_t intermediate_checksum;
|
||||
uint16_t table_length;
|
||||
uint32_t table_address;
|
||||
uint16_t number_of_smbios_structures;
|
||||
uint8_t smbios_bcd_revision;
|
||||
} _packed_ SmbiosEntryPoint;
|
||||
|
||||
typedef struct {
|
||||
uint8_t anchor_string[5];
|
||||
uint8_t entry_point_structure_checksum;
|
||||
uint8_t entry_point_length;
|
||||
uint8_t major_version;
|
||||
uint8_t minor_version;
|
||||
uint8_t docrev;
|
||||
uint8_t entry_point_revision;
|
||||
uint8_t reserved;
|
||||
uint32_t table_maximum_size;
|
||||
uint64_t table_address;
|
||||
} _packed_ Smbios3EntryPoint;
|
||||
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t handle[2];
|
||||
} _packed_ SmbiosHeader;
|
||||
|
||||
typedef struct {
|
||||
SmbiosHeader header;
|
||||
uint8_t vendor;
|
||||
uint8_t bios_version;
|
||||
uint16_t bios_segment;
|
||||
uint8_t bios_release_date;
|
||||
uint8_t bios_size;
|
||||
uint64_t bios_characteristics;
|
||||
uint8_t bios_characteristics_ext[2];
|
||||
} _packed_ SmbiosTableType0;
|
||||
|
||||
typedef struct {
|
||||
SmbiosHeader header;
|
||||
uint8_t count;
|
||||
char contents[];
|
||||
} _packed_ SmbiosTableType11;
|
||||
|
||||
static const void *find_smbios_configuration_table(uint64_t *ret_size) {
|
||||
assert(ret_size);
|
||||
|
||||
const Smbios3EntryPoint *entry3 = find_configuration_table(MAKE_GUID_PTR(SMBIOS3_TABLE));
|
||||
if (entry3 && memcmp(entry3->anchor_string, "_SM3_", 5) == 0 &&
|
||||
entry3->entry_point_length <= sizeof(*entry3)) {
|
||||
*ret_size = entry3->table_maximum_size;
|
||||
return PHYSICAL_ADDRESS_TO_POINTER(entry3->table_address);
|
||||
}
|
||||
|
||||
const SmbiosEntryPoint *entry = find_configuration_table(MAKE_GUID_PTR(SMBIOS_TABLE));
|
||||
if (entry && memcmp(entry->anchor_string, "_SM_", 4) == 0 &&
|
||||
entry->entry_point_length <= sizeof(*entry)) {
|
||||
*ret_size = entry->table_length;
|
||||
return PHYSICAL_ADDRESS_TO_POINTER(entry->table_address);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const SmbiosHeader *get_smbios_table(uint8_t type, size_t min_size, uint64_t *ret_size_left) {
|
||||
uint64_t size = 0;
|
||||
const uint8_t *p = find_smbios_configuration_table(&size);
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
for (;;) {
|
||||
if (size < sizeof(SmbiosHeader))
|
||||
return NULL;
|
||||
|
||||
const SmbiosHeader *header = (const SmbiosHeader *) p;
|
||||
|
||||
/* End of table. */
|
||||
if (header->type == 127)
|
||||
return NULL;
|
||||
|
||||
if (size < header->length)
|
||||
return NULL;
|
||||
|
||||
if (header->type == type) {
|
||||
/* Table is smaller than the minimum expected size? Refuse */
|
||||
if (header->length < min_size)
|
||||
return NULL;
|
||||
|
||||
if (ret_size_left)
|
||||
*ret_size_left = size;
|
||||
return header; /* Yay! */
|
||||
}
|
||||
|
||||
/* Skip over formatted area. */
|
||||
size -= header->length;
|
||||
p += header->length;
|
||||
|
||||
/* Special case: if there are no strings appended, we'll see two NUL bytes, skip over them */
|
||||
if (size >= 2 && p[0] == 0 && p[1] == 0) {
|
||||
size -= 2;
|
||||
p += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Skip over a populated string table. */
|
||||
bool first = true;
|
||||
for (;;) {
|
||||
const uint8_t *e = memchr(p, 0, size);
|
||||
if (!e)
|
||||
return NULL;
|
||||
|
||||
if (!first && e == p) {/* Double NUL byte means we've reached the end of the string table. */
|
||||
p++;
|
||||
size--;
|
||||
break;
|
||||
}
|
||||
|
||||
size -= e + 1 - p;
|
||||
p = e + 1;
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool smbios_in_hypervisor(void) {
|
||||
/* Look up BIOS Information (Type 0). */
|
||||
const SmbiosTableType0 *type0 = (const SmbiosTableType0 *) get_smbios_table(0, sizeof(SmbiosTableType0), /* left= */ NULL);
|
||||
if (!type0)
|
||||
return false;
|
||||
|
||||
/* Bit 4 of 2nd BIOS characteristics extension bytes indicates virtualization. */
|
||||
return FLAGS_SET(type0->bios_characteristics_ext[1], 1 << 4);
|
||||
}
|
||||
|
||||
bool in_hypervisor(void) {
|
||||
static int cache = -1;
|
||||
if (cache >= 0)
|
||||
@@ -294,36 +145,6 @@ bool in_hypervisor(void) {
|
||||
return cache;
|
||||
}
|
||||
|
||||
const char* smbios_find_oem_string(const char *name) {
|
||||
uint64_t left;
|
||||
|
||||
assert(name);
|
||||
|
||||
const SmbiosTableType11 *type11 = (const SmbiosTableType11 *) get_smbios_table(11, sizeof(SmbiosTableType11), &left);
|
||||
if (!type11)
|
||||
return NULL;
|
||||
|
||||
const char *s = type11->contents;
|
||||
|
||||
assert(left >= type11->header.length); /* get_smbios_table() already validated this */
|
||||
left -= type11->header.length;
|
||||
const char *limit = s + left;
|
||||
|
||||
for (const char *p = s; p < limit; ) {
|
||||
const char *e = memchr(p, 0, limit - p);
|
||||
if (!e || e == p) /* Double NUL byte means we've reached the end of the OEM strings. */
|
||||
break;
|
||||
|
||||
const char *eq = startswith8(p, name);
|
||||
if (eq && *eq == '=')
|
||||
return eq + 1;
|
||||
|
||||
p = e + 1;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
static uint32_t cpuid_leaf(uint32_t eax, char ret_sig[static 13], bool swapped) {
|
||||
/* zero-init as some queries explicitly require subleaf == 0 */
|
||||
|
||||
@@ -9,5 +9,3 @@ EFI_STATUS vmm_open(EFI_HANDLE *ret_vmm_dev, EFI_FILE **ret_vmm_dir);
|
||||
bool in_hypervisor(void);
|
||||
|
||||
bool is_confidential_vm(void);
|
||||
|
||||
const char* smbios_find_oem_string(const char *name);
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#if !SD_BOOT
|
||||
# include <stdint.h>
|
||||
/* Matches EFI API definition of the same structure for userspace */
|
||||
typedef struct {
|
||||
uint32_t Data1;
|
||||
uint16_t Data2;
|
||||
uint16_t Data3;
|
||||
uint8_t Data4[8];
|
||||
} EFI_GUID;
|
||||
#endif
|
||||
+16
-22
@@ -5,6 +5,7 @@
|
||||
#include "alloc-util.h"
|
||||
#include "dirent-util.h"
|
||||
#include "efi-api.h"
|
||||
#include "efi-fundamental.h"
|
||||
#include "efivars.h"
|
||||
#include "fd-util.h"
|
||||
#include "fileio.h"
|
||||
@@ -523,29 +524,22 @@ bool efi_has_tpm2(void) {
|
||||
|
||||
#endif
|
||||
|
||||
struct efi_guid {
|
||||
uint32_t u1;
|
||||
uint16_t u2;
|
||||
uint16_t u3;
|
||||
uint8_t u4[8];
|
||||
} _packed_;
|
||||
|
||||
sd_id128_t efi_guid_to_id128(const void *guid) {
|
||||
const struct efi_guid *uuid = ASSERT_PTR(guid); /* cast is safe, because struct efi_guid is packed */
|
||||
const EFI_GUID *uuid = ASSERT_PTR(guid); /* cast is safe, because struct efi_guid is packed */
|
||||
sd_id128_t id128;
|
||||
|
||||
id128.bytes[0] = (uuid->u1 >> 24) & 0xff;
|
||||
id128.bytes[1] = (uuid->u1 >> 16) & 0xff;
|
||||
id128.bytes[2] = (uuid->u1 >> 8) & 0xff;
|
||||
id128.bytes[3] = uuid->u1 & 0xff;
|
||||
id128.bytes[0] = (uuid->Data1 >> 24) & 0xff;
|
||||
id128.bytes[1] = (uuid->Data1 >> 16) & 0xff;
|
||||
id128.bytes[2] = (uuid->Data1 >> 8) & 0xff;
|
||||
id128.bytes[3] = uuid->Data1 & 0xff;
|
||||
|
||||
id128.bytes[4] = (uuid->u2 >> 8) & 0xff;
|
||||
id128.bytes[5] = uuid->u2 & 0xff;
|
||||
id128.bytes[4] = (uuid->Data2 >> 8) & 0xff;
|
||||
id128.bytes[5] = uuid->Data2 & 0xff;
|
||||
|
||||
id128.bytes[6] = (uuid->u3 >> 8) & 0xff;
|
||||
id128.bytes[7] = uuid->u3 & 0xff;
|
||||
id128.bytes[6] = (uuid->Data3 >> 8) & 0xff;
|
||||
id128.bytes[7] = uuid->Data3 & 0xff;
|
||||
|
||||
memcpy(&id128.bytes[8], uuid->u4, sizeof(uuid->u4));
|
||||
memcpy(&id128.bytes[8], uuid->Data4, sizeof(uuid->Data4));
|
||||
|
||||
return id128;
|
||||
}
|
||||
@@ -553,11 +547,11 @@ sd_id128_t efi_guid_to_id128(const void *guid) {
|
||||
void efi_id128_to_guid(sd_id128_t id, void *ret_guid) {
|
||||
assert(ret_guid);
|
||||
|
||||
struct efi_guid uuid = {
|
||||
.u1 = id.bytes[0] << 24 | id.bytes[1] << 16 | id.bytes[2] << 8 | id.bytes[3],
|
||||
.u2 = id.bytes[4] << 8 | id.bytes[5],
|
||||
.u3 = id.bytes[6] << 8 | id.bytes[7],
|
||||
EFI_GUID uuid = {
|
||||
.Data1 = id.bytes[0] << 24 | id.bytes[1] << 16 | id.bytes[2] << 8 | id.bytes[3],
|
||||
.Data2 = id.bytes[4] << 8 | id.bytes[5],
|
||||
.Data3 = id.bytes[6] << 8 | id.bytes[7],
|
||||
};
|
||||
memcpy(uuid.u4, id.bytes+8, sizeof(uuid.u4));
|
||||
memcpy(uuid.Data4, id.bytes+8, sizeof(uuid.Data4));
|
||||
memcpy(ret_guid, &uuid, sizeof(uuid));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user