linux/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attr...

104 lines
3.4 KiB
Diff

Origin: https://lore.kernel.org/patchwork/cover/933178/
From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com>
Subject: [PATCH 4/4] MODSIGN: check the attributes of db and mok
That's better for checking the attributes of db and mok variables
before loading certificates to kernel keyring.
For db and dbx, both of them are authenticated variables. Which
means that they can only be modified by manufacturer's key. So
the kernel should checks EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS
attribute before we trust it.
For mok-rt and mokx-rt, both of them are created by shim boot loader
to forward the mok/mokx content to runtime. They must be runtime-volatile
variables. So kernel should checks that the attributes map did not set
EFI_VARIABLE_NON_VOLATILE bit before we trust it.
Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com>
---
certs/load_uefi.c | 35 +++++++++++++++++++++++------------
1 file changed, 23 insertions(+), 12 deletions(-)
diff --git a/certs/load_uefi.c b/certs/load_uefi.c
index dc66a79..52526bd 100644
--- a/certs/load_uefi.c
+++ b/certs/load_uefi.c
@@ -36,12 +36,14 @@
* Get a certificate list blob from the named EFI variable.
*/
static __init int get_cert_list(efi_char16_t *name, efi_guid_t *guid,
- unsigned long *size, void **cert_list)
+ unsigned long *size, void **cert_list,
+ u32 pos_attr, u32 neg_attr)
{
efi_status_t status;
unsigned long lsize = 4;
unsigned long tmpdb[4];
void *db;
+ u32 attr = 0;
status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb);
if (status == EFI_NOT_FOUND) {
@@ -61,12 +63,19 @@
return -ENOMEM;
}
- status = efi.get_variable(name, guid, NULL, &lsize, db);
+ status = efi.get_variable(name, guid, &attr, &lsize, db);
if (status != EFI_SUCCESS) {
kfree(db);
pr_err("Error reading db var: 0x%lx\n", status);
return efi_status_to_err(status);
}
+ /* must have positive attributes and no negative attributes */
+ if ((pos_attr && !(attr & pos_attr)) ||
+ (neg_attr && (attr & neg_attr))) {
+ kfree(db);
+ pr_err("Error reading db var attributes: 0x%016x\n", attr);
+ return -1;
+ }
*size = lsize;
*cert_list = db;
@@ -159,7 +168,8 @@
* an error if we can't get them.
*/
if (!uefi_check_ignore_db()) {
- rc = get_cert_list(L"db", &secure_var, &dbsize, &db);
+ rc = get_cert_list(L"db", &secure_var, &dbsize, &db,
+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 0);
if (rc < 0) {
pr_err("MODSIGN: Couldn't get UEFI db list\n");
} else if (dbsize != 0) {
@@ -171,7 +181,8 @@
}
}
- rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx);
+ rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx,
+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 0);
if (rc < 0) {
pr_info("MODSIGN: Couldn't get UEFI dbx list\n");
} else if (dbxsize != 0) {
@@ -187,7 +198,8 @@
if (!efi_enabled(EFI_SECURE_BOOT))
return 0;
- rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok);
+ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok,
+ 0, EFI_VARIABLE_NON_VOLATILE);
if (rc < 0) {
pr_info("MODSIGN: Couldn't get UEFI MokListRT\n");
} else if (moksize != 0) {
@@ -198,7 +210,8 @@
kfree(mok);
}
- rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx);
+ rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx,
+ 0, EFI_VARIABLE_NON_VOLATILE);
if (rc < 0) {
pr_info("MODSIGN: Couldn't get UEFI MokListXRT\n");
} else if (mokxsize != 0) {