Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mirror some more efi variables to mok-variables #723

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ CFLAGS += -DENABLE_SHIM_CERT
else
TARGETS += $(MMNAME) $(FBNAME)
endif
OBJS = shim.o globals.o mok.o netboot.o cert.o dp.o loader-proto.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o pe-relocate.o httpboot.o csv.o load-options.o utils.o
OBJS = shim.o globals.o memattrs.o mok.o netboot.o cert.o dp.o loader-proto.o tpm.o version.o errlog.o sbat.o sbat_data.o sbat_var.o pe.o pe-relocate.o httpboot.o csv.o load-options.o utils.o
KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key shim.cer
ORIG_SOURCES = shim.c globals.c mok.c netboot.c dp.c loader-proto.c tpm.c errlog.c sbat.c pe.c pe-relocate.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S
ORIG_SOURCES = shim.c globals.c memattrs.c mok.c netboot.c dp.c loader-proto.c tpm.c errlog.c sbat.c pe.c pe-relocate.c httpboot.c shim.h version.h $(wildcard include/*.h) cert.S sbat_var.S
MOK_OBJS = MokManager.o PasswordCrypt.o crypt_blowfish.o errlog.o sbat_data.o globals.o dp.o
ORIG_MOK_SOURCES = MokManager.c PasswordCrypt.c crypt_blowfish.c shim.h $(wildcard include/*.h)
FALLBACK_OBJS = fallback.o tpm.o errlog.o sbat_data.o globals.o utils.o
Expand Down
10 changes: 10 additions & 0 deletions MokVars.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,13 @@ to trust CA keys in the MokList. BS,NV

MokListTrustedRT: A copy of MokListTrusted made available to the kernel
at runtime. BS,RT

HSIStatus: Status of various security features:
heap-is-executable: 0: heap allocations are not executable by default
1: heap allocations are executable
stack-is-executable: 0: UEFI stack is not executable
1: UEFI stack is executable
ro-sections-are-writable: 0: read-only sections are not writable
1: read-only sections are writable
has-memory-attribute-protocol: 0: platform does not provide the EFI Memory Attribute Protocol
1: platform does provide the EFI Memory Attribute Protocol
149 changes: 149 additions & 0 deletions errlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,153 @@ ClearErrors(VOID)
errs = NULL;
}

static size_t
format_error_log(UINT8 *dest, size_t dest_sz)
{
size_t err_log_sz = 0;
size_t pos = 0;

for (UINTN i = 0; i < nerrs; i++)
err_log_sz += StrSize(errs[i]);

if (!dest || dest_sz < err_log_sz)
return err_log_sz;

ZeroMem(dest, err_log_sz);
for (UINTN i = 0; i < nerrs; i++) {
UINTN sz = StrSize(errs[i]);
CopyMem(&dest[pos], errs[i], sz);
pos += sz;
}

return err_log_sz;
}

static UINT8 *debug_log = NULL;
static size_t debug_log_sz = 0;
static size_t debug_log_alloc = 0;

UINTN EFIAPI
log_debug_print(const CHAR16 *fmt, ...)
{
ms_va_list args;
CHAR16 *buf;
size_t buf_sz;
UINTN ret = 0;

ms_va_start(args, fmt);
buf = VPoolPrint(fmt, args);
if (!buf)
return 0;
ms_va_end(args);

ret = StrLen(buf);
buf_sz = StrSize(buf);
if (debug_log_sz + buf_sz > debug_log_alloc) {
size_t new_alloc_sz = debug_log_alloc;
CHAR16 *new_debug_log;

new_alloc_sz += buf_sz;
new_alloc_sz = ALIGN_UP(new_alloc_sz, 4096);

new_debug_log = ReallocatePool(debug_log, debug_log_alloc, new_alloc_sz);
if (!new_debug_log)
return 0;
debug_log = (UINT8 *)new_debug_log;
debug_log_alloc = new_alloc_sz;
}

CopyMem(&debug_log[debug_log_sz], buf, buf_sz);
debug_log_sz += buf_sz;
FreePool(buf);
return ret;
}

static size_t
format_debug_log(UINT8 *dest, size_t dest_sz)
{
if (!dest || dest_sz < debug_log_sz)
return debug_log_sz;

ZeroMem(dest, debug_log_sz);
CopyMem(dest, debug_log, debug_log_sz);
return debug_log_sz;
}

void
save_logs(void)
{
struct mok_variable_config_entry *cfg_table = NULL;
struct mok_variable_config_entry *new_table = NULL;
struct mok_variable_config_entry *entry = NULL;
size_t new_table_sz;
UINTN pos = 0;
EFI_STATUS efi_status;
EFI_CONFIGURATION_TABLE *CT;
EFI_GUID bogus_guid = { 0x29f2f0db, 0xd025, 0x4aa6, { 0x99, 0x58, 0xa0, 0x21, 0x8b, 0x1d, 0xec, 0x0e }};
size_t errlog_sz, dbglog_sz;

errlog_sz = format_error_log(NULL, 0);
dbglog_sz = format_debug_log(NULL, 0);

if (errlog_sz == 0 && dbglog_sz == 0) {
console_print(L"No console or debug log?!?!?\n");
return;
}

for (UINTN i = 0; i < ST->NumberOfTableEntries; i++) {
CT = &ST->ConfigurationTable[i];

if (CompareGuid(&MOK_VARIABLE_STORE, &CT->VendorGuid) == 0) {
cfg_table = CT->VendorTable;
break;
}
CT = NULL;
}

entry = cfg_table;
while (entry && entry->name[0] != 0) {
size_t entry_sz;
entry = (struct mok_variable_config_entry *)((uintptr_t)cfg_table + pos);

entry_sz = sizeof(*entry);
entry_sz += entry->data_size;

if (entry->name[0] != 0)
pos += entry_sz;
}

new_table_sz = pos + 3 * sizeof(*entry) + errlog_sz + dbglog_sz;
new_table = AllocateZeroPool(new_table_sz);
if (!new_table)
return;

CopyMem(new_table, cfg_table, pos);

entry = (struct mok_variable_config_entry *)((uintptr_t)new_table + pos);
if (errlog_sz) {
strcpy(entry->name, "shim-err.txt");
entry->data_size = errlog_sz;
format_error_log(&entry->data[0], errlog_sz);

pos += sizeof(*entry) + errlog_sz;
entry = (struct mok_variable_config_entry *)((uintptr_t)new_table + pos);
}
if (dbglog_sz) {
strcpy(entry->name, "shim-dbg.txt");
entry->data_size = dbglog_sz;
format_debug_log(&entry->data[0], dbglog_sz);

pos += sizeof(*entry) + dbglog_sz;
// entry = (struct mok_variable_config_entry *)((uintptr_t)new_table + pos);
}

if (CT) {
CopyMem(&CT->VendorGuid, &bogus_guid, sizeof(bogus_guid));
}
efi_status = BS->InstallConfigurationTable(&MOK_VARIABLE_STORE, new_table);
if (EFI_ERROR(efi_status))
console_print(L"Could not re-install MoK configuration table: %r\n", efi_status);
}

// vim:fenc=utf-8:tw=75
1 change: 1 addition & 0 deletions globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ verification_method_t verification_method;
SHIM_IMAGE_LOADER shim_image_loader_interface;

UINT8 user_insecure_mode;
UINTN hsi_status = 0;
UINT8 ignore_db;
UINT8 trust_mok_list;
UINT8 mok_policy = 0;
Expand Down
7 changes: 6 additions & 1 deletion include/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,14 +175,19 @@
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)
#endif

#ifndef ALIGN
#ifndef __ALIGN
#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask))
#define __ALIGN(x, a) __ALIGN_MASK(x, (typeof(x))(a) - 1)
#endif
#ifndef ALIGN
#define ALIGN(x, a) __ALIGN((x), (a))
#endif
#ifndef ALIGN_DOWN
#define ALIGN_DOWN(x, a) __ALIGN((x) - ((a) - 1), (a))
#endif
#ifndef ALIGN_UP
#define ALIGN_UP(addr, align) (((addr) + (typeof (addr)) (align) - 1) & ~((typeof (addr)) (align) - 1))
#endif

#define MIN(a, b) ({(a) < (b) ? (a) : (b);})
#define MAX(a, b) ({(a) <= (b) ? (b) : (a);})
Expand Down
1 change: 1 addition & 0 deletions include/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ extern UINT32 verbose;
#ifndef SHIM_UNIT_TEST
#define dprint_(fmt, ...) ({ \
UINTN __dprint_ret = 0; \
log_debug_print((fmt), ##__VA_ARGS__); \
if (verbose) \
__dprint_ret = console_print((fmt), ##__VA_ARGS__); \
__dprint_ret; \
Expand Down
22 changes: 22 additions & 0 deletions include/errlog.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: BSD-2-Clause-Patent
/*
* errlog.h - error logging utilities
* Copyright Peter Jones <pjones@redhat.com>
*/

#ifndef ERRLOG_H_
#define ERRLOG_H_

extern EFI_STATUS EFIAPI LogError_(const char *file, int line, const char *func,
const CHAR16 *fmt, ...);
extern EFI_STATUS EFIAPI VLogError(const char *file, int line, const char *func,
const CHAR16 *fmt, ms_va_list args);
extern VOID LogHexdump_(const char *file, int line, const char *func,
const void *data, size_t sz);
extern VOID PrintErrors(VOID);
extern VOID ClearErrors(VOID);
extern void save_logs(void);
extern UINTN EFIAPI log_debug_print(const CHAR16 *fmt, ...);

#endif /* !ERRLOG_H_ */
// vim:fenc=utf-8:tw=75:noet
17 changes: 17 additions & 0 deletions include/memattrs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// SPDX-License-Identifier: BSD-2-Clause-Patent
/*
* memattrs.h - EFI and DXE memory attribute helpers
* Copyright Peter Jones <pjones@redhat.com>
*/

#ifndef SHIM_MEMATTRS_H_
#define SHIM_MEMATTRS_H_

extern EFI_STATUS get_mem_attrs (uintptr_t addr, size_t size, uint64_t *attrs);
extern EFI_STATUS update_mem_attrs(uintptr_t addr, uint64_t size,
uint64_t set_attrs, uint64_t clear_attrs);

extern void get_hsi_mem_info(void);

#endif /* !SHIM_MEMATTRS_H_ */
// vim:fenc=utf-8:tw=75:noet
37 changes: 37 additions & 0 deletions include/mok.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ typedef enum {

struct mok_state_variable;
typedef vendor_addend_category_t (vendor_addend_categorizer_t)(struct mok_state_variable *);
typedef UINTN (mok_variable_format_helper_t)(UINT8 *buf, size_t sz, struct mok_state_variable *);

#define MOK_MIRROR_KEYDB 0x01
#define MOK_MIRROR_DELETE_FIRST 0x02
#define MOK_VARIABLE_MEASURE 0x04
#define MOK_VARIABLE_LOG 0x08
#define MOK_VARIABLE_INVERSE 0x10
#define MOK_VARIABLE_CONFIG_ONLY 0x20

/*
* MoK variables that need to have their storage validated.
Expand Down Expand Up @@ -81,6 +89,8 @@ struct mok_state_variable {
* MOK_MIRROR_DELETE_FIRST delete any existing variable first
* MOK_VARIABLE_MEASURE extend PCR 7 and log the hash change
* MOK_VARIABLE_LOG measure into whatever .pcr says and log
* MOK_VARIABLE_CONFIG_ONLY don't create a UEFI variable, only add
* it to the config space variables.
*/
UINTN pcr; /* PCR to measure and hash to */

Expand All @@ -89,6 +99,23 @@ struct mok_state_variable {
* mirrored.
*/
UINT8 *state;

/*
* If this is non-NULL, this function will be called during the
* "import" phase to format the variable data. It'll get called
* twice, once as:
*
* sz = format(NULL, 0, ptr);
*
* a buffer of size sz will then be allocated, and it'll be called
* again to fill the buffer:
*
* format(buf, sz, ptr);
*
* Note that as an implementation detail data and data_size must be
* NULL and 0 respectively for this entry.
*/
mok_variable_format_helper_t *format;
};

extern size_t n_mok_state_variables;
Expand All @@ -105,5 +132,15 @@ struct mok_variable_config_entry {
*/
#define MOK_POLICY_REQUIRE_NX 1

extern UINTN hsi_status;
/* heap is executable */
#define SHIM_HSI_STATUS_HEAPX 0x00000001ULL
/* stack is executable */
#define SHIM_HSI_STATUS_STACKX 0x00000002ULL
/* read-only sections are writable */
#define SHIM_HSI_STATUS_ROW 0x00000004ULL
/* platform provides the EFI Memory Attribute Protocol */
#define SHIM_HSI_STATUS_HASMAP 0x00000008ULL

#endif /* !SHIM_MOK_H_ */
// vim:fenc=utf-8:tw=75:noet
6 changes: 6 additions & 0 deletions include/test-data-efivars-1.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,5 +106,11 @@ static const unsigned char test_data_efivars_1_MokListTrustedRT[] ={
0x01
};

static const unsigned char test_data_efivars_1_HSIStatus[] =
"heap-is-executable: 0\n"
"stack-is-executable: 0\n"
"ro-sections-are-writable: 0\n"
"has-memory-attribute-protocol: 0\n";

#endif /* !TEST_DATA_EFIVARS_1_H_ */
// vim:fenc=utf-8:tw=75:noet
Loading
Loading