From e4c1c48eebd072b2fa6f27fd9b7baa731350ebe8 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Mon, 29 Jun 2020 11:49:58 +0200 Subject: efi_loader: fix incorrect use of EFI_EXIT() efi_get_variable_common() does not use EFI_ENTRY(). So we should not use EFI_EXIT() either. Fixes: 767f6eeb01d3 ("efi_loader: variable: support variable authentication") Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_variable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index 6271dbcf41..c262cb5972 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -606,7 +606,7 @@ static efi_status_t efi_get_variable_common(u16 *variable_name, u32 attr; if (!variable_name || !vendor || !data_size) - return EFI_EXIT(EFI_INVALID_PARAMETER); + return EFI_INVALID_PARAMETER; ret = efi_to_native(&native_name, variable_name, vendor); if (ret) -- cgit v1.2.3 From f7a963c6af5a077631a4ff43fcd10533969b14b2 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Tue, 9 Jun 2020 14:09:31 +0900 Subject: efi_loader: change efi objects initialization order The simplest solution to revert the commit b32ac16f9a32 ("test/py: fix test_efi_secboot/conftest.py") is to move efi_console_register() forward before efi_disk_register(). Signed-off-by: AKASHI Takahiro Reviewed by: Heinrich Schuchardt --- lib/efi_loader/efi_setup.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index dd0c53fc23..671f6da12b 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -140,6 +140,10 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; + ret = efi_console_register(); + if (ret != EFI_SUCCESS) + goto out; + #ifdef CONFIG_PARTITIONS ret = efi_disk_register(); if (ret != EFI_SUCCESS) @@ -185,9 +189,6 @@ efi_status_t efi_init_obj_list(void) if (ret != EFI_SUCCESS) goto out; - ret = efi_console_register(); - if (ret != EFI_SUCCESS) - goto out; #if defined(CONFIG_LCD) || defined(CONFIG_DM_VIDEO) ret = efi_gop_register(); if (ret != EFI_SUCCESS) -- cgit v1.2.3 From 3e9019d4816945f7448e0182f9e5466385503345 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Tue, 9 Jun 2020 14:09:33 +0900 Subject: efi_loader: signature: replace debug to EFI_PRINT Just for style consistency, replace all the uses of debug to EFI_PRINT in efi_signature.c Signed-off-by: AKASHI Takahiro Reviewed-by: Heinrich Schuchardt --- lib/efi_loader/efi_signature.c | 121 +++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 59 deletions(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_signature.c b/lib/efi_loader/efi_signature.c index 6685253856..3a634d7b57 100644 --- a/lib/efi_loader/efi_signature.c +++ b/lib/efi_loader/efi_signature.c @@ -42,14 +42,14 @@ static bool efi_hash_regions(struct efi_image_regions *regs, void **hash, *size = 0; *hash = calloc(1, SHA256_SUM_LEN); if (!*hash) { - debug("Out of memory\n"); + EFI_PRINT("Out of memory\n"); return false; } *size = SHA256_SUM_LEN; hash_calculate("sha256", regs->reg, regs->num, *hash); #ifdef DEBUG - debug("hash calculated:\n"); + EFI_PRINT("hash calculated:\n"); print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1, *hash, SHA256_SUM_LEN, false); #endif @@ -75,7 +75,7 @@ static bool efi_hash_msg_content(struct pkcs7_message *msg, void **hash, *size = 0; *hash = calloc(1, SHA256_SUM_LEN); if (!*hash) { - debug("Out of memory\n"); + EFI_PRINT("Out of memory\n"); free(msg); return false; } @@ -86,7 +86,7 @@ static bool efi_hash_msg_content(struct pkcs7_message *msg, void **hash, hash_calculate("sha256", ®tmp, 1, *hash); #ifdef DEBUG - debug("hash calculated based on contentInfo:\n"); + EFI_PRINT("hash calculated based on contentInfo:\n"); print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1, *hash, SHA256_SUM_LEN, false); #endif @@ -119,8 +119,8 @@ static bool efi_signature_verify(struct efi_image_regions *regs, char c; bool verified; - debug("%s: Enter, %p, %p, %p(issuer: %s, subject: %s)\n", __func__, - regs, ps_info, cert, cert->issuer, cert->subject); + EFI_PRINT("%s: Enter, %p, %p, %p(issuer: %s, subject: %s)\n", __func__, + regs, ps_info, cert, cert->issuer, cert->subject); verified = false; @@ -138,7 +138,8 @@ static bool efi_signature_verify(struct efi_image_regions *regs, info.checksum = image_get_checksum_algo("sha256,rsa2048"); info.name = "sha256,rsa2048"; } else { - debug("unknown msg digest algo: %s\n", ps_info->sig->hash_algo); + EFI_PRINT("unknown msg digest algo: %s\n", + ps_info->sig->hash_algo); goto out; } info.crypto = image_get_crypto_algo(info.name); @@ -147,21 +148,22 @@ static bool efi_signature_verify(struct efi_image_regions *regs, info.keylen = cert->pub->keylen; /* verify signature */ - debug("%s: crypto: %s, signature len:%x\n", __func__, - info.name, ps_info->sig->s_size); + EFI_PRINT("%s: crypto: %s, signature len:%x\n", __func__, + info.name, ps_info->sig->s_size); if (ps_info->aa_set & (1UL << sinfo_has_message_digest)) { - debug("%s: RSA verify authentication attribute\n", __func__); + EFI_PRINT("%s: RSA verify authentication attribute\n", + __func__); /* * NOTE: This path will be executed only for * PE image authentication */ /* check if hash matches digest first */ - debug("checking msg digest first, len:0x%x\n", - ps_info->msgdigest_len); + EFI_PRINT("checking msg digest first, len:0x%x\n", + ps_info->msgdigest_len); #ifdef DEBUG - debug("hash in database:\n"); + EFI_PRINT("hash in database:\n"); print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1, ps_info->msgdigest, ps_info->msgdigest_len, false); @@ -173,14 +175,14 @@ static bool efi_signature_verify(struct efi_image_regions *regs, /* for authenticated variable */ if (ps_info->msgdigest_len != size || memcmp(hash, ps_info->msgdigest, size)) { - debug("Digest doesn't match\n"); + EFI_PRINT("Digest doesn't match\n"); free(hash); goto out; } free(hash); } else { - debug("Digesting image failed\n"); + EFI_PRINT("Digesting image failed\n"); goto out; } @@ -195,7 +197,7 @@ static bool efi_signature_verify(struct efi_image_regions *regs, ps_info->sig->s, ps_info->sig->s_size)) verified = true; } else { - debug("%s: RSA verify content data\n", __func__); + EFI_PRINT("%s: RSA verify content data\n", __func__); /* against all data */ if (!rsa_verify(&info, regs->reg, regs->num, ps_info->sig->s, ps_info->sig->s_size)) @@ -203,7 +205,7 @@ static bool efi_signature_verify(struct efi_image_regions *regs, } out: - debug("%s: Exit, verified: %d\n", __func__, verified); + EFI_PRINT("%s: Exit, verified: %d\n", __func__, verified); return verified; } @@ -233,26 +235,26 @@ bool efi_signature_verify_with_list(struct efi_image_regions *regs, struct efi_sig_data *sig_data; bool verified = false; - debug("%s: Enter, %p, %p, %p, %p\n", __func__, - regs, signed_info, siglist, valid_cert); + EFI_PRINT("%s: Enter, %p, %p, %p, %p\n", __func__, + regs, signed_info, siglist, valid_cert); if (!signed_info) { void *hash; size_t size; - debug("%s: unsigned image\n", __func__); + EFI_PRINT("%s: unsigned image\n", __func__); /* * verify based on calculated hash value * TODO: support other hash algorithms */ if (guidcmp(&siglist->sig_type, &efi_guid_sha256)) { - debug("Digest algorithm is not supported: %pUl\n", - &siglist->sig_type); + EFI_PRINT("Digest algorithm is not supported: %pUl\n", + &siglist->sig_type); goto out; } if (!efi_hash_regions(regs, &hash, &size)) { - debug("Digesting unsigned image failed\n"); + EFI_PRINT("Digesting unsigned image failed\n"); goto out; } @@ -260,7 +262,7 @@ bool efi_signature_verify_with_list(struct efi_image_regions *regs, for (sig_data = siglist->sig_data_list; sig_data; sig_data = sig_data->next) { #ifdef DEBUG - debug("Msg digest in database:\n"); + EFI_PRINT("Msg digest in database:\n"); print_hex_dump(" ", DUMP_PREFIX_OFFSET, 16, 1, sig_data->data, sig_data->size, false); #endif @@ -275,10 +277,10 @@ bool efi_signature_verify_with_list(struct efi_image_regions *regs, goto out; } - debug("%s: signed image\n", __func__); + EFI_PRINT("%s: signed image\n", __func__); if (guidcmp(&siglist->sig_type, &efi_guid_cert_x509)) { - debug("Signature type is not supported: %pUl\n", - &siglist->sig_type); + EFI_PRINT("Signature type is not supported: %pUl\n", + &siglist->sig_type); goto out; } @@ -289,7 +291,7 @@ bool efi_signature_verify_with_list(struct efi_image_regions *regs, cert = x509_cert_parse(sig_data->data, sig_data->size); if (IS_ERR(cert)) { - debug("Parsing x509 certificate failed\n"); + EFI_PRINT("Parsing x509 certificate failed\n"); goto out; } @@ -306,7 +308,7 @@ bool efi_signature_verify_with_list(struct efi_image_regions *regs, } out: - debug("%s: Exit, verified: %d\n", __func__, verified); + EFI_PRINT("%s: Exit, verified: %d\n", __func__, verified); return verified; } @@ -331,7 +333,7 @@ bool efi_signature_verify_with_sigdb(struct efi_image_regions *regs, struct efi_signature_store *siglist; bool verified = false; - debug("%s: Enter, %p, %p, %p, %p\n", __func__, regs, msg, db, cert); + EFI_PRINT("%s: Enter, %p, %p, %p, %p\n", __func__, regs, msg, db, cert); if (!db) goto out; @@ -341,7 +343,7 @@ bool efi_signature_verify_with_sigdb(struct efi_image_regions *regs, /* for unsigned image */ if (!msg) { - debug("%s: Verify unsigned image with db\n", __func__); + EFI_PRINT("%s: Verify unsigned image with db\n", __func__); for (siglist = db; siglist; siglist = siglist->next) if (efi_signature_verify_with_list(regs, NULL, NULL, siglist, cert)) { @@ -353,10 +355,10 @@ bool efi_signature_verify_with_sigdb(struct efi_image_regions *regs, } /* for signed image or variable */ - debug("%s: Verify signed image with db\n", __func__); + EFI_PRINT("%s: Verify signed image with db\n", __func__); for (info = msg->signed_infos; info; info = info->next) { - debug("Signed Info: digest algo: %s, pkey algo: %s\n", - info->sig->hash_algo, info->sig->pkey_algo); + EFI_PRINT("Signed Info: digest algo: %s, pkey algo: %s\n", + info->sig->hash_algo, info->sig->pkey_algo); for (siglist = db; siglist; siglist = siglist->next) { if (efi_signature_verify_with_list(regs, msg, info, @@ -368,7 +370,7 @@ bool efi_signature_verify_with_sigdb(struct efi_image_regions *regs, } out: - debug("%s: Exit, verified: %d\n", __func__, verified); + EFI_PRINT("%s: Exit, verified: %d\n", __func__, verified); return verified; } @@ -400,21 +402,21 @@ static bool efi_search_siglist(struct x509_certificate *cert, if (guidcmp(&siglist->sig_type, &efi_guid_cert_x509_sha256)) { /* TODO: other hash algos */ - debug("Certificate's digest type is not supported: %pUl\n", - &siglist->sig_type); + EFI_PRINT("Certificate's digest type is not supported: %pUl\n", + &siglist->sig_type); goto out; } /* calculate hash of TBSCertificate */ msg = calloc(1, SHA256_SUM_LEN); if (!msg) { - debug("Out of memory\n"); + EFI_PRINT("Out of memory\n"); goto out; } hash = calloc(1, SHA256_SUM_LEN); if (!hash) { - debug("Out of memory\n"); + EFI_PRINT("Out of memory\n"); goto out; } @@ -465,7 +467,7 @@ bool efi_signature_verify_cert(struct x509_certificate *cert, time64_t revoc_time; bool found = false; - debug("%s: Enter, %p, %p\n", __func__, dbx, cert); + EFI_PRINT("%s: Enter, %p, %p\n", __func__, dbx, cert); if (!cert) return false; @@ -480,7 +482,7 @@ bool efi_signature_verify_cert(struct x509_certificate *cert, } } - debug("%s: Exit, verified: %d\n", __func__, !found); + EFI_PRINT("%s: Exit, verified: %d\n", __func__, !found); return !found; } @@ -501,7 +503,7 @@ bool efi_signature_verify_signers(struct pkcs7_message *msg, struct pkcs7_signed_info *info; bool found = false; - debug("%s: Enter, %p, %p\n", __func__, msg, dbx); + EFI_PRINT("%s: Enter, %p, %p\n", __func__, msg, dbx); if (!msg) goto out; @@ -514,7 +516,7 @@ bool efi_signature_verify_signers(struct pkcs7_message *msg, } } out: - debug("%s: Exit, verified: %d\n", __func__, !found); + EFI_PRINT("%s: Exit, verified: %d\n", __func__, !found); return !found; } @@ -539,7 +541,7 @@ efi_status_t efi_image_region_add(struct efi_image_regions *regs, int i, j; if (regs->num >= regs->max) { - debug("%s: no more room for regions\n", __func__); + EFI_PRINT("%s: no more room for regions\n", __func__); return EFI_OUT_OF_RESOURCES; } @@ -556,8 +558,8 @@ efi_status_t efi_image_region_add(struct efi_image_regions *regs, if ((start >= reg->data && start < reg->data + reg->size) || (end > reg->data && end < reg->data + reg->size)) { - debug("%s: new region already part of another\n", - __func__); + EFI_PRINT("%s: new region already part of another\n", + __func__); return EFI_INVALID_PARAMETER; } @@ -649,14 +651,14 @@ efi_sigstore_parse_siglist(struct efi_signature_list *esl) if (esl->signature_list_size <= (sizeof(*esl) + esl->signature_header_size)) { - debug("Siglist in wrong format\n"); + EFI_PRINT("Siglist in wrong format\n"); return NULL; } /* Create a head */ siglist = calloc(sizeof(*siglist), 1); if (!siglist) { - debug("Out of memory\n"); + EFI_PRINT("Out of memory\n"); goto err; } memcpy(&siglist->sig_type, &esl->signature_type, sizeof(efi_guid_t)); @@ -671,14 +673,14 @@ efi_sigstore_parse_siglist(struct efi_signature_list *esl) while (left > 0) { /* Signature must exist if there is remaining data. */ if (left < esl->signature_size) { - debug("Certificate is too small\n"); + EFI_PRINT("Certificate is too small\n"); goto err; } sig_data = calloc(esl->signature_size - sizeof(esd->signature_owner), 1); if (!sig_data) { - debug("Out of memory\n"); + EFI_PRINT("Out of memory\n"); goto err; } @@ -689,7 +691,7 @@ efi_sigstore_parse_siglist(struct efi_signature_list *esl) - sizeof(esd->signature_owner); sig_data->data = malloc(sig_data->size); if (!sig_data->data) { - debug("Out of memory\n"); + EFI_PRINT("Out of memory\n"); goto err; } memcpy(sig_data->data, esd->signature_data, sig_data->size); @@ -735,7 +737,7 @@ struct efi_signature_store *efi_sigstore_parse_sigdb(u16 *name) } else if (!u16_strcmp(name, L"db") || !u16_strcmp(name, L"dbx")) { vendor = &efi_guid_image_security_database; } else { - debug("unknown signature database, %ls\n", name); + EFI_PRINT("unknown signature database, %ls\n", name); return NULL; } @@ -743,23 +745,23 @@ struct efi_signature_store *efi_sigstore_parse_sigdb(u16 *name) db_size = 0; ret = EFI_CALL(efi_get_variable(name, vendor, NULL, &db_size, NULL)); if (ret == EFI_NOT_FOUND) { - debug("variable, %ls, not found\n", name); + EFI_PRINT("variable, %ls, not found\n", name); sigstore = calloc(sizeof(*sigstore), 1); return sigstore; } else if (ret != EFI_BUFFER_TOO_SMALL) { - debug("Getting variable, %ls, failed\n", name); + EFI_PRINT("Getting variable, %ls, failed\n", name); return NULL; } db = malloc(db_size); if (!db) { - debug("Out of memory\n"); + EFI_PRINT("Out of memory\n"); return NULL; } ret = EFI_CALL(efi_get_variable(name, vendor, NULL, &db_size, db)); if (ret != EFI_SUCCESS) { - debug("Getting variable, %ls, failed\n", name); + EFI_PRINT("Getting variable, %ls, failed\n", name); goto err; } @@ -768,19 +770,20 @@ struct efi_signature_store *efi_sigstore_parse_sigdb(u16 *name) while (db_size > 0) { /* List must exist if there is remaining data. */ if (db_size < sizeof(*esl)) { - debug("variable, %ls, in wrong format\n", name); + EFI_PRINT("variable, %ls, in wrong format\n", name); goto err; } if (db_size < esl->signature_list_size) { - debug("variable, %ls, in wrong format\n", name); + EFI_PRINT("variable, %ls, in wrong format\n", name); goto err; } /* Parse a single siglist. */ siglist = efi_sigstore_parse_siglist(esl); if (!siglist) { - debug("Parsing signature list of %ls failed\n", name); + EFI_PRINT("Parsing signature list of %ls failed\n", + name); goto err; } -- cgit v1.2.3 From ce3c3865b0c321116e59437abec96da3745ba619 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Tue, 9 Jun 2020 14:09:34 +0900 Subject: efi_loader: variable: replace debug to EFI_PRINT Just for style consistency, replace all the uses of debug() to EFI_PRINT in efi_variable.c. Signed-off-by: AKASHI Takahiro Reviewed-by: Heinrich Schuchardt --- lib/efi_loader/efi_variable.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index c262cb5972..74a9c65402 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -243,7 +243,8 @@ static efi_status_t efi_transfer_secure_state(enum efi_secure_mode mode) { efi_status_t ret; - debug("Switching secure state from %d to %d\n", efi_secure_mode, mode); + EFI_PRINT("Switching secure state from %d to %d\n", efi_secure_mode, + mode); if (mode == EFI_MODE_DEPLOYED) { ret = efi_set_secure_state(1, 0, 0, 1); @@ -394,16 +395,16 @@ static struct pkcs7_message *efi_variable_parse_signature(const void *buf, * TODO: * The header should be composed in a more refined manner. */ - debug("Makeshift prefix added to authentication data\n"); + EFI_PRINT("Makeshift prefix added to authentication data\n"); ebuflen = sizeof(pkcs7_hdr) + buflen; if (ebuflen <= 0x7f) { - debug("Data is too short\n"); + EFI_PRINT("Data is too short\n"); return NULL; } ebuf = malloc(ebuflen); if (!ebuf) { - debug("Out of memory\n"); + EFI_PRINT("Out of memory\n"); return NULL; } @@ -527,7 +528,7 @@ static efi_status_t efi_variable_authenticate(u16 *variable, auth->auth_info.hdr.dwLength - sizeof(auth->auth_info)); if (!var_sig) { - debug("Parsing variable's signature failed\n"); + EFI_PRINT("Parsing variable's signature failed\n"); goto err; } @@ -558,14 +559,14 @@ static efi_status_t efi_variable_authenticate(u16 *variable, /* verify signature */ if (efi_signature_verify_with_sigdb(regs, var_sig, truststore, NULL)) { - debug("Verified\n"); + EFI_PRINT("Verified\n"); } else { if (truststore2 && efi_signature_verify_with_sigdb(regs, var_sig, truststore2, NULL)) { - debug("Verified\n"); + EFI_PRINT("Verified\n"); } else { - debug("Verifying variable's signature failed\n"); + EFI_PRINT("Verifying variable's signature failed\n"); goto err; } } @@ -640,7 +641,7 @@ static efi_status_t efi_get_variable_common(u16 *variable_name, } if (!data) { - debug("Variable with no data shouldn't exist.\n"); + EFI_PRINT("Variable with no data shouldn't exist.\n"); return EFI_INVALID_PARAMETER; } @@ -659,7 +660,7 @@ static efi_status_t efi_get_variable_common(u16 *variable_name, } if (!data) { - debug("Variable with no data shouldn't exist.\n"); + EFI_PRINT("Variable with no data shouldn't exist.\n"); return EFI_INVALID_PARAMETER; } @@ -940,8 +941,8 @@ static efi_status_t efi_set_variable_common(u16 *variable_name, /* authentication is mandatory */ if (!(attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) { - debug("%ls: AUTHENTICATED_WRITE_ACCESS required\n", - variable_name); + EFI_PRINT("%ls: AUTHENTICATED_WRITE_ACCESS required\n", + variable_name); ret = EFI_INVALID_PARAMETER; goto err; } @@ -970,7 +971,7 @@ static efi_status_t efi_set_variable_common(u16 *variable_name, if (attributes & (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)) { - debug("Secure boot is not configured\n"); + EFI_PRINT("Secure boot is not configured\n"); ret = EFI_INVALID_PARAMETER; goto err; } -- cgit v1.2.3 From 1b6c08548c85ec8bb1d57f12fb219cc2e31547c8 Mon Sep 17 00:00:00 2001 From: AKASHI Takahiro Date: Tue, 9 Jun 2020 14:09:35 +0900 Subject: efi_loader: image_loader: replace debug to EFI_PRINT Just for style consistency, replace all the uses of debug() to EFI_PRINT() in efi_image_loader.c. Signed-off-by: AKASHI Takahiro Reviewed-by: Heinrich Schuchardt --- lib/efi_loader/efi_image_loader.c | 64 ++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 31 deletions(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c index 230d41ae5e..06a2ebdb90 100644 --- a/lib/efi_loader/efi_image_loader.c +++ b/lib/efi_loader/efi_image_loader.c @@ -325,8 +325,8 @@ bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp, authoff = opt->DataDirectory[ctidx].VirtualAddress; authsz = opt->DataDirectory[ctidx].Size; } else { - debug("%s: Invalid optional header magic %x\n", __func__, - nt->OptionalHeader.Magic); + EFI_PRINT("%s: Invalid optional header magic %x\n", __func__, + nt->OptionalHeader.Magic); goto err; } @@ -336,7 +336,7 @@ bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp, nt->FileHeader.SizeOfOptionalHeader); sorted = calloc(sizeof(IMAGE_SECTION_HEADER *), num_sections); if (!sorted) { - debug("%s: Out of memory\n", __func__); + EFI_PRINT("%s: Out of memory\n", __func__); goto err; } @@ -355,13 +355,13 @@ bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp, efi_image_region_add(regs, efi + sorted[i]->PointerToRawData, efi + sorted[i]->PointerToRawData + size, 0); - debug("section[%d](%s): raw: 0x%x-0x%x, virt: %x-%x\n", - i, sorted[i]->Name, - sorted[i]->PointerToRawData, - sorted[i]->PointerToRawData + size, - sorted[i]->VirtualAddress, - sorted[i]->VirtualAddress - + sorted[i]->Misc.VirtualSize); + EFI_PRINT("section[%d](%s): raw: 0x%x-0x%x, virt: %x-%x\n", + i, sorted[i]->Name, + sorted[i]->PointerToRawData, + sorted[i]->PointerToRawData + size, + sorted[i]->VirtualAddress, + sorted[i]->VirtualAddress + + sorted[i]->Misc.VirtualSize); bytes_hashed += size; } @@ -369,8 +369,8 @@ bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp, /* 3. Extra data excluding Certificates Table */ if (bytes_hashed + authsz < len) { - debug("extra data for hash: %zu\n", - len - (bytes_hashed + authsz)); + EFI_PRINT("extra data for hash: %lu\n", + len - (bytes_hashed + authsz)); efi_image_region_add(regs, efi + bytes_hashed, efi + len - authsz, 0); } @@ -378,18 +378,19 @@ bool efi_image_parse(void *efi, size_t len, struct efi_image_regions **regp, /* Return Certificates Table */ if (authsz) { if (len < authoff + authsz) { - debug("%s: Size for auth too large: %u >= %zu\n", - __func__, authsz, len - authoff); + EFI_PRINT("%s: Size for auth too large: %u >= %zu\n", + __func__, authsz, len - authoff); goto err; } if (authsz < sizeof(*auth)) { - debug("%s: Size for auth too small: %u < %zu\n", - __func__, authsz, sizeof(*auth)); + EFI_PRINT("%s: Size for auth too small: %u < %zu\n", + __func__, authsz, sizeof(*auth)); goto err; } *auth = efi + authoff; *auth_len = authsz; - debug("WIN_CERTIFICATE: 0x%x, size: 0x%x\n", authoff, authsz); + EFI_PRINT("WIN_CERTIFICATE: 0x%x, size: 0x%x\n", authoff, + authsz); } else { *auth = NULL; *auth_len = 0; @@ -423,19 +424,19 @@ static bool efi_image_unsigned_authenticate(struct efi_image_regions *regs) dbx = efi_sigstore_parse_sigdb(L"dbx"); if (!dbx) { - debug("Getting signature database(dbx) failed\n"); + EFI_PRINT("Getting signature database(dbx) failed\n"); goto out; } db = efi_sigstore_parse_sigdb(L"db"); if (!db) { - debug("Getting signature database(db) failed\n"); + EFI_PRINT("Getting signature database(db) failed\n"); goto out; } /* try black-list first */ if (efi_signature_verify_with_sigdb(regs, NULL, dbx, NULL)) { - debug("Image is not signed and rejected by \"dbx\"\n"); + EFI_PRINT("Image is not signed and rejected by \"dbx\"\n"); goto out; } @@ -443,7 +444,7 @@ static bool efi_image_unsigned_authenticate(struct efi_image_regions *regs) if (efi_signature_verify_with_sigdb(regs, NULL, db, NULL)) ret = true; else - debug("Image is not signed and not found in \"db\" or \"dbx\"\n"); + EFI_PRINT("Image is not signed and not found in \"db\" or \"dbx\"\n"); out: efi_sigstore_free(db); @@ -504,7 +505,7 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) if (!efi_image_parse(efi, efi_size, ®s, &wincerts, &wincerts_len)) { - debug("Parsing PE executable image failed\n"); + EFI_PRINT("Parsing PE executable image failed\n"); goto err; } @@ -520,13 +521,13 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) */ db = efi_sigstore_parse_sigdb(L"db"); if (!db) { - debug("Getting signature database(db) failed\n"); + EFI_PRINT("Getting signature database(db) failed\n"); goto err; } dbx = efi_sigstore_parse_sigdb(L"dbx"); if (!dbx) { - debug("Getting signature database(dbx) failed\n"); + EFI_PRINT("Getting signature database(dbx) failed\n"); goto err; } @@ -535,26 +536,27 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) (void *)wincert < (void *)wincerts + wincerts_len; wincert = (void *)wincert + ALIGN(wincert->dwLength, 8)) { if (wincert->dwLength < sizeof(*wincert)) { - debug("%s: dwLength too small: %u < %zu\n", - __func__, wincert->dwLength, sizeof(*wincert)); + EFI_PRINT("%s: dwLength too small: %u < %zu\n", + __func__, wincert->dwLength, + sizeof(*wincert)); goto err; } msg = pkcs7_parse_message((void *)wincert + sizeof(*wincert), wincert->dwLength - sizeof(*wincert)); if (IS_ERR(msg)) { - debug("Parsing image's signature failed\n"); + EFI_PRINT("Parsing image's signature failed\n"); msg = NULL; goto err; } /* try black-list first */ if (efi_signature_verify_with_sigdb(regs, msg, dbx, NULL)) { - debug("Signature was rejected by \"dbx\"\n"); + EFI_PRINT("Signature was rejected by \"dbx\"\n"); goto err; } if (!efi_signature_verify_signers(msg, dbx)) { - debug("Signer was rejected by \"dbx\"\n"); + EFI_PRINT("Signer was rejected by \"dbx\"\n"); goto err; } else { ret = true; @@ -562,14 +564,14 @@ static bool efi_image_authenticate(void *efi, size_t efi_size) /* try white-list */ if (!efi_signature_verify_with_sigdb(regs, msg, db, &cert)) { - debug("Verifying signature with \"db\" failed\n"); + EFI_PRINT("Verifying signature with \"db\" failed\n"); goto err; } else { ret = true; } if (!efi_signature_verify_cert(cert, dbx)) { - debug("Certificate was rejected by \"dbx\"\n"); + EFI_PRINT("Certificate was rejected by \"dbx\"\n"); goto err; } else { ret = true; -- cgit v1.2.3 From 28164c925ef02082f6320542acee744f8712ae9c Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 1 Jul 2020 20:01:52 +0200 Subject: efi_loader: fix efi_image_region_add() Use start and end address consistently as half-open interval. Simplify the code. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_signature.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_signature.c b/lib/efi_loader/efi_signature.c index 3a634d7b57..e05c471c61 100644 --- a/lib/efi_loader/efi_signature.c +++ b/lib/efi_loader/efi_signature.c @@ -521,15 +521,19 @@ out: } /** - * efi_image_region_add - add an entry of region + * efi_image_region_add() - add an entry of region * @regs: Pointer to array of regions - * @start: Start address of region - * @end: End address of region + * @start: Start address of region (included) + * @end: End address of region (excluded) * @nocheck: flag against overlapped regions * - * Take one entry of region [@start, @end] and append it to the list - * pointed to by @regs. If @nocheck is false, overlapping among entries - * will be checked first. + * Take one entry of region [@start, @end[ and insert it into the list. + * + * * If @nocheck is false, the list will be sorted ascending by address. + * Overlapping entries will not be allowed. + * + * * If @nocheck is true, the list will be sorted ascending by sequence + * of adding the entries. Overlapping is allowed. * * Return: status code */ @@ -553,22 +557,21 @@ efi_status_t efi_image_region_add(struct efi_image_regions *regs, if (nocheck) continue; - if (start > reg->data + reg->size) + /* new data after registered region */ + if (start >= reg->data + reg->size) continue; - if ((start >= reg->data && start < reg->data + reg->size) || - (end > reg->data && end < reg->data + reg->size)) { - EFI_PRINT("%s: new region already part of another\n", - __func__); - return EFI_INVALID_PARAMETER; - } - - if (start < reg->data && end < reg->data + reg->size) { + /* new data preceding registered region */ + if (end <= reg->data) { for (j = regs->num - 1; j >= i; j--) - memcpy(®s->reg[j], ®s->reg[j + 1], + memcpy(®s->reg[j + 1], ®s->reg[j], sizeof(*reg)); break; } + + /* new data overlapping registered region */ + EFI_PRINT("%s: new region already part of another\n", __func__); + return EFI_INVALID_PARAMETER; } reg = ®s->reg[i]; -- cgit v1.2.3 From 33f183f68b76226a1053694418d2c283371bee72 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 1 Jul 2020 12:44:00 +0200 Subject: efi_loader: add missing validation of timestamp The UEFI specification requires that when UEFI variables are set using time based authentication we have to check that unused fields of the timestamp are zero Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_variable.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index 74a9c65402..f9a0efd427 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -481,11 +481,15 @@ static efi_status_t efi_variable_authenticate(u16 *variable, if (guidcmp(&auth->auth_info.cert_type, &efi_guid_cert_type_pkcs7)) goto err; + memcpy(×tamp, &auth->time_stamp, sizeof(timestamp)); + if (timestamp.pad1 || timestamp.nanosecond || timestamp.timezone || + timestamp.daylight || timestamp.pad2) + goto err; + *data += sizeof(auth->time_stamp) + auth->auth_info.hdr.dwLength; *data_size -= (sizeof(auth->time_stamp) + auth->auth_info.hdr.dwLength); - memcpy(×tamp, &auth->time_stamp, sizeof(timestamp)); memset(&tm, 0, sizeof(tm)); tm.tm_year = timestamp.year; tm.tm_mon = timestamp.month; -- cgit v1.2.3 From cb7116030aff44f48f29bdc3bd7ed22f7ad74bb9 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 1 Jul 2020 15:32:47 +0200 Subject: efi_loader: time based authentication When overwriting an existing time base authenticated variable we should compare to the preceding time value and not to the start of the epoch. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_variable.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index f9a0efd427..4d49fd60dc 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -35,7 +35,8 @@ static u8 efi_vendor_keys; static efi_status_t efi_get_variable_common(u16 *variable_name, const efi_guid_t *vendor, u32 *attributes, - efi_uintn_t *data_size, void *data); + efi_uintn_t *data_size, void *data, + u64 *timep); static efi_status_t efi_set_variable_common(u16 *variable_name, const efi_guid_t *vendor, @@ -309,7 +310,7 @@ static efi_status_t efi_init_secure_state(void) size = 0; ret = efi_get_variable_common(L"PK", &efi_global_variable_guid, - NULL, &size, NULL); + NULL, &size, NULL, NULL); if (ret == EFI_BUFFER_TOO_SMALL) { if (IS_ENABLED(CONFIG_EFI_SECURE_BOOT)) mode = EFI_MODE_USER; @@ -601,7 +602,8 @@ static efi_status_t efi_variable_authenticate(u16 *variable, static efi_status_t efi_get_variable_common(u16 *variable_name, const efi_guid_t *vendor, u32 *attributes, - efi_uintn_t *data_size, void *data) + efi_uintn_t *data_size, void *data, + u64 *timep) { char *native_name; efi_status_t ret; @@ -626,6 +628,9 @@ static efi_status_t efi_get_variable_common(u16 *variable_name, val = parse_attr(val, &attr, &time); + if (timep) + *timep = time; + in_size = *data_size; if ((s = prefix(val, "(blob)"))) { @@ -709,7 +714,7 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, data_size, data); ret = efi_get_variable_common(variable_name, vendor, attributes, - data_size, data); + data_size, data, NULL); return EFI_EXIT(ret); } @@ -905,7 +910,7 @@ static efi_status_t efi_set_variable_common(u16 *variable_name, old_size = 0; attr = 0; ret = efi_get_variable_common(variable_name, vendor, &attr, - &old_size, NULL); + &old_size, NULL, &time); append = !!(attributes & EFI_VARIABLE_APPEND_WRITE); attributes &= ~(u32)EFI_VARIABLE_APPEND_WRITE; delete = !append && (!data_size || !attributes); @@ -996,7 +1001,7 @@ static efi_status_t efi_set_variable_common(u16 *variable_name, goto err; } ret = efi_get_variable_common(variable_name, vendor, - &attr, &old_size, old_data); + &attr, &old_size, old_data, NULL); if (ret != EFI_SUCCESS) goto err; } else { -- cgit v1.2.3 From 7a373e54350b8cbc27b402d881a07e29a6107c0d Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 31 May 2020 10:07:31 +0200 Subject: efi_loader: use log function in boot manager When booting via the boot manager use log function for user messages instead of printf() and debug(). Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_bootmgr.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c index e144b3e7f4..e268e9c4b8 100644 --- a/lib/efi_loader/efi_bootmgr.c +++ b/lib/efi_loader/efi_bootmgr.c @@ -5,6 +5,8 @@ * Copyright (c) 2017 Rob Clark */ +#define LOG_CATEGORY LOGC_EFI + #include #include #include @@ -203,14 +205,14 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle) if (lo.attributes & LOAD_OPTION_ACTIVE) { u32 attributes; - debug("%s: trying to load \"%ls\" from %pD\n", - __func__, lo.label, lo.file_path); + log_debug("%s: trying to load \"%ls\" from %pD\n", + __func__, lo.label, lo.file_path); ret = EFI_CALL(efi_load_image(true, efi_root, lo.file_path, NULL, 0, handle)); if (ret != EFI_SUCCESS) { - printf("Loading from Boot%04X '%ls' failed\n", n, - lo.label); + log_warning("Loading %ls '%ls' failed\n", + varname, lo.label); goto error; } @@ -224,11 +226,11 @@ static efi_status_t try_load_entry(u16 n, efi_handle_t *handle) if (ret != EFI_SUCCESS) { if (EFI_CALL(efi_unload_image(*handle)) != EFI_SUCCESS) - printf("Unloading image failed\n"); + log_err("Unloading image failed\n"); goto error; } - printf("Booting: %ls\n", lo.label); + log_info("Booting: %ls\n", lo.label); } else { ret = EFI_LOAD_ERROR; } @@ -268,7 +270,7 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle) if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) { /* BootNext does exist here */ if (ret == EFI_BUFFER_TOO_SMALL || size != sizeof(u16)) - printf("BootNext must be 16-bit integer\n"); + log_err("BootNext must be 16-bit integer\n"); /* delete BootNext */ ret = EFI_CALL(efi_set_variable( @@ -283,24 +285,26 @@ efi_status_t efi_bootmgr_load(efi_handle_t *handle) ret = try_load_entry(bootnext, handle); if (ret == EFI_SUCCESS) return ret; - printf("Loading from BootNext failed, falling back to BootOrder\n"); + log_warning( + "Loading from BootNext failed, falling back to BootOrder\n"); } } else { - printf("Deleting BootNext failed\n"); + log_err("Deleting BootNext failed\n"); } } /* BootOrder */ bootorder = get_var(L"BootOrder", &efi_global_variable_guid, &size); if (!bootorder) { - printf("BootOrder not defined\n"); + log_info("BootOrder not defined\n"); ret = EFI_NOT_FOUND; goto error; } num = size / sizeof(uint16_t); for (i = 0; i < num; i++) { - debug("%s: trying to load Boot%04X\n", __func__, bootorder[i]); + log_debug("%s trying to load Boot%04X\n", __func__, + bootorder[i]); ret = try_load_entry(bootorder[i], handle); if (ret == EFI_SUCCESS) break; -- cgit v1.2.3 From 3a92f85f2121bb76061758e2830a5a1572729bcf Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 30 Jun 2020 12:02:14 +0200 Subject: efi_loader: rtc_mktime() called twice Don't call rtc_mktime() twice with the same argument in efi_variable_authenticate(). Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_variable.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c index 4d49fd60dc..efaba869ef 100644 --- a/lib/efi_loader/efi_variable.c +++ b/lib/efi_loader/efi_variable.c @@ -577,7 +577,7 @@ static efi_status_t efi_variable_authenticate(u16 *variable, } /* finished checking */ - *time = rtc_mktime(&tm); + *time = new_time; ret = EFI_SUCCESS; err: -- cgit v1.2.3 From 15b1bf10d1a1b21ecbf20169e30688df1c8e34be Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Thu, 19 Mar 2020 18:21:58 +0000 Subject: efi_loader: export initialization state Export the UEFI sub-system initialization state. This will allow to treat the setting of UEFI variables during and after initialization differently. Signed-off-by: Heinrich Schuchardt --- include/efi_loader.h | 3 +++ lib/efi_loader/efi_setup.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/include/efi_loader.h b/include/efi_loader.h index c2cae814b6..fc9344c742 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -56,6 +56,9 @@ static inline void *guidcpy(void *dst, const void *src) /* Root node */ extern efi_handle_t efi_root; +/* Set to EFI_SUCCESS when initialized */ +extern efi_status_t efi_obj_list_initialized; + /* EFI system partition */ extern struct efi_system_partition { enum if_type if_type; diff --git a/lib/efi_loader/efi_setup.c b/lib/efi_loader/efi_setup.c index 671f6da12b..a3b05a4a9b 100644 --- a/lib/efi_loader/efi_setup.c +++ b/lib/efi_loader/efi_setup.c @@ -11,7 +11,7 @@ #define OBJ_LIST_NOT_INITIALIZED 1 -static efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED; +efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED; /* * Allow unaligned memory access. -- cgit v1.2.3 From 93f6201af71d9a0a521c99212e6066778270a357 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 21 Mar 2020 20:45:50 +0100 Subject: efi_loader: imply FAT, FAT_WRITE The UEFI spec requires support for the FAT file system. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/Kconfig | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index aad37b7155..6c9df3a767 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -15,6 +15,8 @@ config EFI_LOADER select HAVE_BLOCK_DEVICE select REGEX imply CFB_CONSOLE_ANSI + imply FAT + imply FAT_WRITE imply USB_KEYBOARD_FN_KEYS imply VIDEO_ANSI help -- cgit v1.2.3