From 09e2c939569800c4e0b7270fd4e5692bc9c5e3c6 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Mon, 10 Dec 2012 16:34:35 +0800 Subject: Get the second stage loader from the Load Options This commit replaces the 2nd stage loader path with the first argument in the Load Options and moves the rest arguments (if any) to the Load Options for the 2nd stage loader. For example, to make shim to load elilo.efi, just create a new boot entry with efibootmgr: # efibootmgr -c -L "shim elilo" -l "efi\\shim.efi" -u "elilo.efi" --- shim.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/shim.c b/shim.c index c3aae9e0..44301dd1 100644 --- a/shim.c +++ b/shim.c @@ -42,12 +42,16 @@ #include "netboot.h" #include "shim_cert.h" -#define SECOND_STAGE L"\\grub.efi" +#define DEFAULT_LOADER L"\\grub.efi" #define MOK_MANAGER L"\\MokManager.efi" static EFI_SYSTEM_TABLE *systab; static EFI_STATUS (EFIAPI *entry_point) (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table); +static CHAR16 *second_stage; +static void *load_options; +static UINT32 load_options_size; + /* * The vendor certificate used for validating the second stage loader */ @@ -881,6 +885,10 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize, li->ImageBase = buffer; li->ImageSize = context.ImageSize; + /* Pass the load options to the second stage loader */ + li->LoadOptions = load_options; + li->LoadOptionsSize = load_options_size; + if (!entry_point) { Print(L"Invalid entry point\n"); FreePool(buffer); @@ -1192,7 +1200,7 @@ EFI_STATUS init_grub(EFI_HANDLE image_handle) { EFI_STATUS efi_status; - efi_status = start_image(image_handle, SECOND_STAGE); + efi_status = start_image(image_handle, second_stage); if (efi_status != EFI_SUCCESS) efi_status = start_image(image_handle, MOK_MANAGER); @@ -1312,6 +1320,55 @@ static EFI_STATUS check_mok_sb (void) return status; } +/* + * Check the load options to specify the second stage loader + */ +EFI_STATUS set_second_stage (EFI_HANDLE image_handle) +{ + EFI_STATUS status; + EFI_LOADED_IMAGE *li; + CHAR16 *start = NULL, *c; + int i, remaining_size = 0; + + second_stage = DEFAULT_LOADER; + load_options = NULL; + load_options_size = 0; + + status = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle, + &LoadedImageProtocol, (void **) &li); + if (status != EFI_SUCCESS) { + Print (L"Failed to get load options\n"); + return status; + } + + /* Expect a CHAR16 string with at least one CHAR16 */ + if (li->LoadOptionsSize < 4 || li->LoadOptionsSize % 2 != 0) { + return EFI_BAD_BUFFER_SIZE; + } + c = (CHAR16 *)(li->LoadOptions + (li->LoadOptionsSize - 2)); + if (*c != L'\0') { + return EFI_BAD_BUFFER_SIZE; + } + + for (i = 0; i < li->LoadOptionsSize; i += 2) { + c = (CHAR16 *)(li->LoadOptions + i); + if (*c == L' ') { + *c = L'\0'; + start = c + 1; + remaining_size = li->LoadOptionsSize - i - 2; + break; + } + } + + second_stage = (CHAR16 *)li->LoadOptions; + if (start && remaining_size > 0) { + load_options = start; + load_options_size = remaining_size; + } + + return EFI_SUCCESS; +} + EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab) { EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; @@ -1334,6 +1391,9 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab) */ InitializeLib(image_handle, systab); + /* Set the second stage loader */ + set_second_stage (image_handle); + /* * Check whether the user has configured the system to run in * insecure mode -- cgit v1.2.3 From 4895ca3919bce61154b2a6a95c9102b6a1665678 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 20 Dec 2012 12:55:59 +0800 Subject: Clear the screen before erasing keys --- MokManager.c | 1 + 1 file changed, 1 insertion(+) diff --git a/MokManager.c b/MokManager.c index 5802d274..c6f84d88 100644 --- a/MokManager.c +++ b/MokManager.c @@ -675,6 +675,7 @@ static INTN mok_deletion_prompt (void *MokNew, void *data2, void *data3) { UINT32 length; EFI_STATUS efi_status; + uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); Print(L"Erase all stored keys? (y/N): "); get_line (&length, line, 1, 1); -- cgit v1.2.3 From a64ab2ec6b99ab38e72b7b480e1c3e935bf6921e Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 27 Dec 2012 11:42:45 +0800 Subject: Reboot the system after enrolling/erasing keys --- MokManager.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/MokManager.c b/MokManager.c index c6f84d88..7d6650e6 100644 --- a/MokManager.c +++ b/MokManager.c @@ -637,6 +637,7 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate) } static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) { + EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; CHAR16 line[1]; UINT32 length; EFI_STATUS efi_status; @@ -657,6 +658,19 @@ static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) { Print(L"Failed to enroll keys\n"); return -1; } + + if (auth) { + LibDeleteVariable(L"MokNew", &shim_lock_guid); + LibDeleteVariable(L"MokAuth", &shim_lock_guid); + + Print(L"\nPress a key to reboot system\n"); + Pause(); + uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, + EFI_SUCCESS, 0, NULL); + Print(L"Failed to reboot\n"); + return -1; + } + return 0; } } while (line[0] != 'N' && line[0] != 'n'); @@ -671,6 +685,7 @@ static INTN mok_enrollment_prompt_callback (void *MokNew, void *data2, } static INTN mok_deletion_prompt (void *MokNew, void *data2, void *data3) { + EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; CHAR16 line[1]; UINT32 length; EFI_STATUS efi_status; @@ -687,6 +702,16 @@ static INTN mok_deletion_prompt (void *MokNew, void *data2, void *data3) { Print(L"Failed to erase keys\n"); return -1; } + + LibDeleteVariable(L"MokNew", &shim_lock_guid); + LibDeleteVariable(L"MokAuth", &shim_lock_guid); + + Print(L"\nPress a key to reboot system\n"); + Pause(); + uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, + EFI_SUCCESS, 0, NULL); + Print(L"Failed to reboot\n"); + return -1; } return 0; -- cgit v1.2.3 From 262d671419f1266cbe0e83b7fa3aa85e3b91ddfe Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 27 Dec 2012 11:42:54 +0800 Subject: Add a general function for password matching --- MokManager.c | 148 +++++++++++++++++++++++------------------------------------ 1 file changed, 57 insertions(+), 91 deletions(-) diff --git a/MokManager.c b/MokManager.c index 7d6650e6..ffe37ff7 100644 --- a/MokManager.c +++ b/MokManager.c @@ -558,17 +558,61 @@ done: return status; } +static EFI_STATUS match_password (void *Data, UINTN DataSize, + UINT8 auth[SHA256_DIGEST_SIZE], + CHAR16 *prompt) +{ + EFI_STATUS efi_status; + UINT8 hash[SHA256_DIGEST_SIZE]; + CHAR16 password[PASSWORD_MAX]; + UINT32 pw_length; + UINT8 fail_count = 0; + + while (fail_count < 3) { + if (prompt) { + Print(L"%s", prompt); + } else { + Print(L"Password: "); + } + get_line(&pw_length, password, PASSWORD_MAX, 0); + + if (pw_length < PASSWORD_MIN || pw_length > PASSWORD_MAX) { + Print(L"Invalid password length\n"); + fail_count++; + continue; + } + + efi_status = compute_pw_hash(Data, DataSize, password, + pw_length, hash); + + if (efi_status != EFI_SUCCESS) { + Print(L"Unable to generate password hash\n"); + fail_count++; + continue; + } + + if (CompareMem(auth, hash, SHA256_DIGEST_SIZE) != 0) { + Print(L"Password doesn't match\n"); + fail_count++; + continue; + } + + break; + } + + if (fail_count >= 3) + return EFI_ACCESS_DENIED; + + return EFI_SUCCESS; +} + static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate) { EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; EFI_STATUS efi_status; - UINT8 hash[SHA256_DIGEST_SIZE]; UINT8 auth[SHA256_DIGEST_SIZE]; UINTN auth_size; UINT32 attributes; - CHAR16 password[PASSWORD_MAX]; - UINT32 pw_length; - UINT8 fail_count = 0; if (authenticate) { auth_size = SHA256_DIGEST_SIZE; @@ -582,32 +626,8 @@ static EFI_STATUS store_keys (void *MokNew, UINTN MokNewSize, int authenticate) return efi_status; } - while (fail_count < 3) { - Print(L"Password(%d-%d characters): ", - PASSWORD_MIN, PASSWORD_MAX); - get_line(&pw_length, password, PASSWORD_MAX, 0); - - if (pw_length < 8) { - Print(L"At least %d characters for the password\n", - PASSWORD_MIN); - } - - efi_status = compute_pw_hash(MokNew, MokNewSize, password, - pw_length, hash); - - if (efi_status != EFI_SUCCESS) { - return efi_status; - } - - if (CompareMem(auth, hash, SHA256_DIGEST_SIZE) != 0) { - Print(L"Password doesn't match\n"); - fail_count++; - } else { - break; - } - } - - if (fail_count >= 3) + efi_status = match_password(MokNew, MokNewSize, auth, NULL); + if (efi_status != EFI_SUCCESS) return EFI_ACCESS_DENIED; } @@ -819,9 +839,7 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) { EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; EFI_STATUS efi_status; UINTN MokPWSize = (UINTN)data2; - UINT8 fail_count = 0; UINT8 hash[SHA256_DIGEST_SIZE]; - CHAR16 password[PASSWORD_MAX]; UINT32 length; CHAR16 line[1]; @@ -849,34 +867,8 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) { return 0; } - while (fail_count < 3) { - Print(L"Confirm MOK passphrase: "); - get_line(&length, password, PASSWORD_MAX, 0); - - if ((length < PASSWORD_MIN) || (length > PASSWORD_MAX)) { - Print(L"Invalid password length\n"); - fail_count++; - continue; - } - - efi_status = compute_pw_hash(NULL, 0, password, length, hash); - - if (efi_status != EFI_SUCCESS) { - Print(L"Unable to generate password hash\n"); - fail_count++; - continue; - } - - if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) != 0) { - Print(L"Password doesn't match\n"); - fail_count++; - continue; - } - - break; - } - - if (fail_count >= 3) { + efi_status = match_password(NULL, 0, MokPW, L"Confirm MOK passphrase: "); + if (efi_status != EFI_SUCCESS) { Print(L"Password limit reached\n"); return -1; } @@ -1483,12 +1475,8 @@ static BOOLEAN verify_pw(void) { EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; EFI_STATUS efi_status; - CHAR16 password[PASSWORD_MAX]; - UINT8 fail_count = 0; - UINT8 hash[SHA256_DIGEST_SIZE]; UINT8 pwhash[SHA256_DIGEST_SIZE]; UINTN size = SHA256_DIGEST_SIZE; - UINT32 length; UINT32 attributes; efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokPWStore", @@ -1508,35 +1496,13 @@ static BOOLEAN verify_pw(void) uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); - while (fail_count < 3) { - Print(L"Enter MOK password: "); - get_line(&length, password, PASSWORD_MAX, 0); - - if (length < PASSWORD_MIN || length > PASSWORD_MAX) { - Print(L"Invalid password length\n"); - fail_count++; - continue; - } - - efi_status = compute_pw_hash(NULL, 0, password, length, hash); - - if (efi_status != EFI_SUCCESS) { - Print(L"Unable to generate password hash\n"); - fail_count++; - continue; - } - - if (CompareMem(pwhash, hash, SHA256_DIGEST_SIZE) != 0) { - Print(L"Password doesn't match\n"); - fail_count++; - continue; - } - - return TRUE; + efi_status = match_password(NULL, 0, pwhash, L"Enter MOK password: "); + if (efi_status != EFI_SUCCESS) { + Print(L"Password limit reached\n"); + return FALSE; } - Print(L"Password limit reached\n"); - return FALSE; + return TRUE; } static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, -- cgit v1.2.3 From a05c7c57d9a81d0989e478419a54ab9c88f1fb9a Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 27 Dec 2012 11:42:54 +0800 Subject: MOK doesn't include the signature owner --- MokManager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MokManager.c b/MokManager.c index ffe37ff7..ddf12deb 100644 --- a/MokManager.c +++ b/MokManager.c @@ -124,7 +124,7 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) { Cert = (EFI_SIGNATURE_DATA *) (((UINT8 *) CertList) + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); - list[count].MokSize = CertList->SignatureSize; + list[count].MokSize = CertList->SignatureSize - sizeof(EFI_GUID); list[count].Mok = (void *)Cert->SignatureData; count++; @@ -317,7 +317,7 @@ static void show_mok_info (void *Mok, UINTN MokSize) if (!Mok || MokSize == 0) return; - if (MokSize != 48) { + if (MokSize != SHA256_DIGEST_SIZE) { if (X509ConstructCertificate(Mok, MokSize, (UINT8 **) &X509Cert) && X509Cert != NULL) { show_x509_info(X509Cert); -- cgit v1.2.3 From 92a136d823e211b60656872ee43ade8693057ee1 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 3 Jan 2013 12:20:22 +0800 Subject: Add support for deleting specific keys --- MokManager.c | 336 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- shim.c | 3 +- 2 files changed, 293 insertions(+), 46 deletions(-) diff --git a/MokManager.c b/MokManager.c index ddf12deb..bfcbfd67 100644 --- a/MokManager.c +++ b/MokManager.c @@ -31,6 +31,7 @@ struct menu_item { typedef struct { UINT32 MokSize; UINT8 *Mok; + EFI_GUID Type; } __attribute__ ((packed)) MokListNode; typedef struct { @@ -39,6 +40,32 @@ typedef struct { CHAR16 Password[PASSWORD_MAX]; } __attribute__ ((packed)) MokSBvar; +static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes, + UINTN *size, void **buffer) +{ + EFI_STATUS efi_status; + char allocate = !(*size); + + efi_status = uefi_call_wrapper(RT->GetVariable, 5, name, &guid, + attributes, size, buffer); + + if (efi_status != EFI_BUFFER_TOO_SMALL || !allocate) { + return efi_status; + } + + *buffer = AllocatePool(*size); + + if (!*buffer) { + Print(L"Unable to allocate variable buffer\n"); + return EFI_OUT_OF_RESOURCES; + } + + efi_status = uefi_call_wrapper(RT->GetVariable, 5, name, &guid, + attributes, size, *buffer); + + return efi_status; +} + static EFI_INPUT_KEY get_keystroke (void) { EFI_INPUT_KEY key; @@ -88,6 +115,42 @@ done: return status; } +static UINT32 count_keys(void *Data, UINTN DataSize) +{ + EFI_SIGNATURE_LIST *CertList = Data; + EFI_GUID CertType = EfiCertX509Guid; + EFI_GUID HashType = EfiHashSha256Guid; + UINTN dbsize = DataSize; + UINT32 MokNum = 0; + + while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) { + if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) && + (CompareGuid (&CertList->SignatureType, &HashType) != 0)) { + Print(L"Doesn't look like a key or hash\n"); + dbsize -= CertList->SignatureListSize; + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + + CertList->SignatureListSize); + continue; + } + + if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) && + (CertList->SignatureSize != 48)) { + Print(L"Doesn't look like a valid hash\n"); + dbsize -= CertList->SignatureListSize; + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + + CertList->SignatureListSize); + continue; + } + + MokNum++; + dbsize -= CertList->SignatureListSize; + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + + CertList->SignatureListSize); + } + + return MokNum; +} + static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) { MokListNode *list; EFI_SIGNATURE_LIST *CertList = Data; @@ -126,6 +189,7 @@ static MokListNode *build_mok_list(UINT32 num, void *Data, UINTN DataSize) { list[count].MokSize = CertList->SignatureSize - sizeof(EFI_GUID); list[count].Mok = (void *)Cert->SignatureData; + list[count].Type = CertList->SignatureType; count++; dbsize -= CertList->SignatureListSize; @@ -391,61 +455,35 @@ static INTN get_number () return (INTN)Atoi(input); } -static UINT8 list_keys (void *MokNew, UINTN MokNewSize) +static UINT8 list_keys (void *KeyList, UINTN KeyListSize, CHAR16 *title) { UINT32 MokNum = 0; MokListNode *keys = NULL; INTN key_num = 0; UINT8 initial = 1; - EFI_SIGNATURE_LIST *CertList = MokNew; - EFI_GUID CertType = EfiCertX509Guid; - EFI_GUID HashType = EfiHashSha256Guid; - UINTN dbsize = MokNewSize; - if (MokNewSize < (sizeof(EFI_SIGNATURE_LIST) + - sizeof(EFI_SIGNATURE_DATA))) { + if (KeyListSize < (sizeof(EFI_SIGNATURE_LIST) + + sizeof(EFI_SIGNATURE_DATA))) { Print(L"No keys\n"); Pause(); return 0; } - while ((dbsize > 0) && (dbsize >= CertList->SignatureListSize)) { - if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) && - (CompareGuid (&CertList->SignatureType, &HashType) != 0)) { - Print(L"Doesn't look like a key or hash\n"); - dbsize -= CertList->SignatureListSize; - CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + - CertList->SignatureListSize); - continue; - } - - if ((CompareGuid (&CertList->SignatureType, &CertType) != 0) && - (CertList->SignatureSize != 48)) { - Print(L"Doesn't look like a valid hash\n"); - dbsize -= CertList->SignatureListSize; - CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + - CertList->SignatureListSize); - continue; - } - - MokNum++; - dbsize -= CertList->SignatureListSize; - CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + - CertList->SignatureListSize); - } - - keys = build_mok_list(MokNum, MokNew, MokNewSize); + MokNum = count_keys(KeyList, KeyListSize); + keys = build_mok_list(MokNum, KeyList, KeyListSize); if (!keys) { - Print(L"Failed to construct key list in MokNew\n"); + Print(L"Failed to construct key list\n"); return 0; } do { uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut); + if (title) + Print(L"%s\n", title); Print(L"Input the key number to show the details of the key or\n" L"type \'0\' to continue\n\n"); - Print(L"%d key(s) in the new key list\n\n", MokNum); + Print(L"%d key(s) in the key list\n\n", MokNum); if (key_num > MokNum) { Print(L"[Key %d]\n", key_num); @@ -663,7 +701,7 @@ static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) { EFI_STATUS efi_status; do { - if (!list_keys(MokNew, MokNewSize)) { + if (!list_keys(MokNew, MokNewSize, L"[Enroll MOK]")) { return 0; } @@ -704,7 +742,8 @@ static INTN mok_enrollment_prompt_callback (void *MokNew, void *data2, return mok_enrollment_prompt(MokNew, (UINTN)data2, TRUE); } -static INTN mok_deletion_prompt (void *MokNew, void *data2, void *data3) { +static INTN mok_reset_prompt (void *MokNew, void *data2, void *data3) +{ EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; CHAR16 line[1]; UINT32 length; @@ -737,6 +776,180 @@ static INTN mok_deletion_prompt (void *MokNew, void *data2, void *data3) { return 0; } +static EFI_STATUS write_back_mok_list (MokListNode *list, INTN key_num) +{ + EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; + EFI_STATUS efi_status; + EFI_SIGNATURE_LIST *CertList; + EFI_SIGNATURE_DATA *CertData; + void *Data = NULL, *ptr; + INTN DataSize = 0; + int i; + + for (i = 0; i < key_num; i++) { + if (list[i].Mok == NULL) + continue; + + DataSize += sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_GUID); + DataSize += list[i].MokSize; + } + + Data = AllocatePool(DataSize); + if (Data == NULL && DataSize != 0) + return EFI_OUT_OF_RESOURCES; + + ptr = Data; + + for (i = 0; i < key_num; i++) { + if (list[i].Mok == NULL) + continue; + + CertList = (EFI_SIGNATURE_LIST *)ptr; + CertData = (EFI_SIGNATURE_DATA *)(((uint8_t *)ptr) + + sizeof(EFI_SIGNATURE_LIST)); + + CertList->SignatureType = list[i].Type; + CertList->SignatureListSize = list[i].MokSize + + sizeof(EFI_SIGNATURE_LIST) + + sizeof(EFI_SIGNATURE_DATA) - 1; + CertList->SignatureHeaderSize = 0; + CertList->SignatureSize = list[i].MokSize + sizeof(EFI_GUID); + + CertData->SignatureOwner = shim_lock_guid; + CopyMem(CertData->SignatureData, list[i].Mok, list[i].MokSize); + + ptr = (uint8_t *)ptr + sizeof(EFI_SIGNATURE_LIST) + + sizeof(EFI_GUID) + list[i].MokSize; + } + + efi_status = uefi_call_wrapper(RT->SetVariable, 5, L"MokList", + &shim_lock_guid, + EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS, + DataSize, Data); + if (Data) + FreePool(Data); + + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to set variable %d\n", efi_status); + return efi_status; + } + + return EFI_SUCCESS; +} + +static EFI_STATUS delete_keys (void *MokDel, UINTN MokDelSize) +{ + EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; + EFI_STATUS efi_status; + UINT8 auth[SHA256_DIGEST_SIZE]; + UINTN auth_size = SHA256_DIGEST_SIZE; + UINT32 attributes; + void *MokListData = NULL; + UINTN MokListDataSize = 0; + MokListNode *mok, *del_key; + INTN mok_num, del_num; + int i, j; + + efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth", + &shim_lock_guid, + &attributes, &auth_size, auth); + + if (efi_status != EFI_SUCCESS || auth_size != SHA256_DIGEST_SIZE) { + Print(L"Failed to get MokDelAuth %d\n", efi_status); + return efi_status; + } + + efi_status = match_password(MokDel, MokDelSize, auth, NULL); + if (efi_status != EFI_SUCCESS) + return EFI_ACCESS_DENIED; + + efi_status = get_variable(L"MokList", shim_lock_guid, &attributes, + &MokListDataSize, &MokListData); + + if (attributes & EFI_VARIABLE_RUNTIME_ACCESS) { + Print(L"MokList is compromised!\nErase all keys in MokList!\n"); + if (LibDeleteVariable(L"MokList", &shim_lock_guid) != EFI_SUCCESS) { + Print(L"Failed to erase MokList\n"); + } + return EFI_ACCESS_DENIED; + } + + /* Nothing to do */ + if (!MokListData || MokListDataSize == 0) + return EFI_SUCCESS; + + /* Construct lists */ + mok_num = count_keys(MokListData, MokListDataSize); + mok = build_mok_list(mok_num, MokListData, MokListDataSize); + del_num = count_keys(MokDel, MokDelSize); + del_key = build_mok_list(del_num, MokDel, MokDelSize); + + /* Search and destroy */ + for (i = 0; i < del_num; i++) { + UINT32 key_size = del_key[i].MokSize; + void *key = del_key[i].Mok; + for (j = 0; j < mok_num; j++) { + if (mok[j].MokSize == key_size && + CompareMem(key, mok[j].Mok, key_size) == 0) { + /* Remove the key */ + mok[j].Mok = NULL; + mok[j].MokSize = 0; + } + } + } + + efi_status = write_back_mok_list(mok, mok_num); + + if (MokListData) + FreePool(MokListData); + if (mok) + FreePool(mok); + if (del_key) + FreePool(del_key); + + return efi_status; +} + +static INTN mok_deletion_prompt (void *MokDel, void *data2, void *data3) +{ + EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; + UINTN MokDelSize = (UINTN)data2; + CHAR16 line[1]; + UINT32 length; + EFI_STATUS efi_status; + + do { + if (!list_keys(MokDel, MokDelSize, L"[Delete MOK]")) { + return 0; + } + + Print(L"Delete the key(s)? (y/n): "); + + get_line (&length, line, 1, 1); + + if (line[0] == 'Y' || line[0] == 'y') { + efi_status = delete_keys(MokDel, MokDelSize); + + if (efi_status != EFI_SUCCESS) { + Print(L"Failed to delete keys\n"); + return -1; + } + + LibDeleteVariable(L"MokDel", &shim_lock_guid); + LibDeleteVariable(L"MokDelAuth", &shim_lock_guid); + + Print(L"\nPress a key to reboot system\n"); + Pause(); + uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, + EFI_SUCCESS, 0, NULL); + Print(L"Failed to reboot\n"); + return -1; + } + } while (line[0] != 'N' && line[0] != 'n'); + return -1; +} + static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) { EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; EFI_STATUS efi_status; @@ -1505,12 +1718,15 @@ static BOOLEAN verify_pw(void) return TRUE; } -static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, - UINTN MokNewSize, void *MokSB, - UINTN MokSBSize, void *MokPW, UINTN MokPWSize) +static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, + void *MokNew, UINTN MokNewSize, + void *MokDel, UINTN MokDelSize, + void *MokSB, UINTN MokSBSize, + void *MokPW, UINTN MokPWSize) { struct menu_item *menu_item; UINT32 MokAuth = 0; + UINT32 MokDelAuth = 0; UINTN menucount = 3, i = 0; EFI_STATUS efi_status; EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; @@ -1528,9 +1744,19 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, if ((efi_status == EFI_SUCCESS) && (auth_size == SHA256_DIGEST_SIZE)) MokAuth = 1; + efi_status = uefi_call_wrapper(RT->GetVariable, 5, L"MokDelAuth", + &shim_lock_guid, + &attributes, &auth_size, auth); + + if ((efi_status == EFI_SUCCESS) && (auth_size == SHA256_DIGEST_SIZE)) + MokDelAuth = 1; + if (MokNew || MokAuth) menucount++; + if (MokDel || MokDelAuth) + menucount++; + if (MokSB) menucount++; @@ -1550,9 +1776,9 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, if (MokNew || MokAuth) { if (!MokNew) { - menu_item[i].text = StrDuplicate(L"Delete MOK"); + menu_item[i].text = StrDuplicate(L"Reset MOK"); menu_item[i].colour = EFI_WHITE; - menu_item[i].callback = mok_deletion_prompt; + menu_item[i].callback = mok_reset_prompt; } else { menu_item[i].text = StrDuplicate(L"Enroll MOK"); menu_item[i].colour = EFI_WHITE; @@ -1563,6 +1789,15 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, i++; } + if (MokDel || MokDelAuth) { + menu_item[i].text = StrDuplicate(L"Delete MOK"); + menu_item[i].colour = EFI_WHITE; + menu_item[i].data = MokDel; + menu_item[i].data2 = (void *)MokDelSize; + menu_item[i].callback = mok_deletion_prompt; + i++; + } + if (MokSB) { menu_item[i].text = StrDuplicate(L"Change Secure Boot state"); menu_item[i].colour = EFI_WHITE; @@ -1605,19 +1840,22 @@ static EFI_STATUS enter_mok_menu(EFI_HANDLE image_handle, void *MokNew, static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) { EFI_GUID shim_lock_guid = SHIM_LOCK_GUID; - UINTN MokNewSize = 0, MokSBSize = 0, MokPWSize = 0; + UINTN MokNewSize = 0, MokDelSize = 0, MokSBSize = 0, MokPWSize = 0; void *MokNew = NULL; + void *MokDel = NULL; void *MokSB = NULL; void *MokPW = NULL; MokNew = LibGetVariableAndSize(L"MokNew", &shim_lock_guid, &MokNewSize); + MokDel = LibGetVariableAndSize(L"MokDel", &shim_lock_guid, &MokDelSize); + MokSB = LibGetVariableAndSize(L"MokSB", &shim_lock_guid, &MokSBSize); MokPW = LibGetVariableAndSize(L"MokPW", &shim_lock_guid, &MokPWSize); - enter_mok_menu(image_handle, MokNew, MokNewSize, MokSB, MokSBSize, - MokPW, MokPWSize); + enter_mok_menu(image_handle, MokNew, MokNewSize, MokDel, MokDelSize, + MokSB, MokSBSize, MokPW, MokPWSize); if (MokNew) { if (LibDeleteVariable(L"MokNew", &shim_lock_guid) != EFI_SUCCESS) { @@ -1626,6 +1864,13 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) FreePool (MokNew); } + if (MokDel) { + if (LibDeleteVariable(L"MokDel", &shim_lock_guid) != EFI_SUCCESS) { + Print(L"Failed to delete MokDel\n"); + } + FreePool (MokDel); + } + if (MokSB) { if (LibDeleteVariable(L"MokSB", &shim_lock_guid) != EFI_SUCCESS) { Print(L"Failed to delete MokSB\n"); @@ -1641,6 +1886,7 @@ static EFI_STATUS check_mok_request(EFI_HANDLE image_handle) } LibDeleteVariable(L"MokAuth", &shim_lock_guid); + LibDeleteVariable(L"MokDelAuth", &shim_lock_guid); return EFI_SUCCESS; } diff --git a/shim.c b/shim.c index 44301dd1..dcf1c516 100644 --- a/shim.c +++ b/shim.c @@ -1271,7 +1271,8 @@ EFI_STATUS check_mok_request(EFI_HANDLE image_handle) EFI_STATUS efi_status; if (check_var(L"MokNew") || check_var(L"MokSB") || - check_var(L"MokPW") || check_var(L"MokAuth")) { + check_var(L"MokPW") || check_var(L"MokAuth") || + check_var(L"MokDel")) { efi_status = start_image(image_handle, MOK_MANAGER); if (efi_status != EFI_SUCCESS) { -- cgit v1.2.3 From 4a88de5816a7ac416d30dbd66e5117f5d4c2c74d Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Thu, 3 Jan 2013 12:20:30 +0800 Subject: Make sure the menu shows when the callback fails Since Pause() doesn't clear the key from the input queue, the next ReadKeyStroke reads the queued key instead of the new one. If the user presses "Enter", MokManager exits directly without showing the menu again. --- MokManager.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/MokManager.c b/MokManager.c index bfcbfd67..97588cb6 100644 --- a/MokManager.c +++ b/MokManager.c @@ -1241,6 +1241,9 @@ static void run_menu (CHAR16 *header, UINTN lines, struct menu_item *items, if (ret < 0) { Print(L"Press a key to continue\n"); Pause(); + /* Clear the key in the queue */ + uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, + ST->ConIn, &key); } draw_menu (header, lines, items, count); pos = 0; -- cgit v1.2.3 From 6e1bd3dcb70985e81f1f9d133219b708eb9beddd Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Fri, 26 Apr 2013 11:44:15 -0400 Subject: UEFI Shell sticks the UCS2 of li->FilePath in li->LoadOptions. Ignore it. If li->LoadOptions tells us to execute our own binary, it's clearly not what we want to do for the second stage. So simply ignore that case. Signed-off-by: Peter Jones --- shim.c | 7 ++++++- ucs2.h | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 ucs2.h diff --git a/shim.c b/shim.c index dcf1c516..32b3ae95 100644 --- a/shim.c +++ b/shim.c @@ -41,6 +41,7 @@ #include "signature.h" #include "netboot.h" #include "shim_cert.h" +#include "ucs2.h" #define DEFAULT_LOADER L"\\grub.efi" #define MOK_MANAGER L"\\MokManager.efi" @@ -1328,6 +1329,7 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle) { EFI_STATUS status; EFI_LOADED_IMAGE *li; + CHAR16 *bootpath = NULL; CHAR16 *start = NULL, *c; int i, remaining_size = 0; @@ -1361,7 +1363,10 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle) } } - second_stage = (CHAR16 *)li->LoadOptions; + bootpath = DevicePathToStr(li->FilePath); + if (!StrCaseCmp(bootpath, (CHAR16 *)li->LoadOptions)) + second_stage = (CHAR16 *)li->LoadOptions; + if (start && remaining_size > 0) { load_options = start; load_options_size = remaining_size; diff --git a/ucs2.h b/ucs2.h new file mode 100644 index 00000000..7c49b09b --- /dev/null +++ b/ucs2.h @@ -0,0 +1,57 @@ +/* + * shim - trivial UEFI first-stage bootloader + * + * Copyright 2013 Red Hat, Inc + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Significant portions of this code are derived from Tianocore + * (http://tianocore.sf.net) and are Copyright 2009-2012 Intel + * Corporation. + */ + +#ifndef SHIM_UCS2_H +#define SHIM_UCS2_H + +static inline INTN +__attribute__((unused)) +StrCaseCmp(CHAR16 *s0, CHAR16 *s1) +{ + CHAR16 c0, c1; + while (1) { + if (*s0 == L'\0' || *s1 == L'\0') + return *s1 - *s0; + c0 = (*s0 >= L'a' && *s0 <= L'z') ? *s0 - 32 : *s0; + c1 = (*s1 >= L'a' && *s1 <= L'z') ? *s1 - 32 : *s1; + if (c0 != c1) + return c1 - c0; + s0++; + s1++; + } + return 0; +} + +#endif /* SHIM_UCS2_H */ -- cgit v1.2.3 From 155a76bb8657c6521be71ab3da609ae181376150 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Fri, 26 Apr 2013 11:44:28 -0400 Subject: Don't put the directory in the file path twice. Sometimes when we're creating paths, the ImagePath can contain the directory name already. If that happens, don't add it in again. Signed-off-by: Peter Jones --- shim.c | 3 ++- ucs2.h | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/shim.c b/shim.c index 32b3ae95..7abbe8b4 100644 --- a/shim.c +++ b/shim.c @@ -939,7 +939,8 @@ static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath, } *PathName[0] = '\0'; - StrCat(*PathName, bootpath); + if (StrnCaseCmp(bootpath, ImagePath, StrLen(bootpath))) + StrCat(*PathName, bootpath); StrCat(*PathName, ImagePath); *grubpath = FileDevicePath(device, *PathName); diff --git a/ucs2.h b/ucs2.h index 7c49b09b..03742847 100644 --- a/ucs2.h +++ b/ucs2.h @@ -54,4 +54,23 @@ StrCaseCmp(CHAR16 *s0, CHAR16 *s1) return 0; } +static inline INTN +__attribute__((unused)) +StrnCaseCmp(CHAR16 *s0, CHAR16 *s1, int n) +{ + CHAR16 c0, c1; + int x = 0; + while (n > x++) { + if (*s0 == L'\0' || *s1 == L'\0') + return *s1 - *s0; + c0 = (*s0 >= L'a' && *s0 <= L'z') ? *s0 - 32 : *s0; + c1 = (*s1 >= L'a' && *s1 <= L'z') ? *s1 - 32 : *s1; + if (c0 != c1) + return c1 - c0; + s0++; + s1++; + } + return 0; +} + #endif /* SHIM_UCS2_H */ -- cgit v1.2.3 From 4a3013c76c539997953af1e784224edb49ec233e Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Fri, 26 Apr 2013 12:12:48 -0400 Subject: Get rid of extra label. Signed-off-by: Peter Jones --- shim.c | 1 - 1 file changed, 1 deletion(-) diff --git a/shim.c b/shim.c index 7abbe8b4..d1071d68 100644 --- a/shim.c +++ b/shim.c @@ -1206,7 +1206,6 @@ EFI_STATUS init_grub(EFI_HANDLE image_handle) if (efi_status != EFI_SUCCESS) efi_status = start_image(image_handle, MOK_MANAGER); -done: return efi_status; } -- cgit v1.2.3 From 0283024e0e861e2f933a5a6e22b0a7d0f869df5e Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Tue, 30 Apr 2013 09:45:45 -0400 Subject: Adopt the UEFI shell style LoadOptions The previous commit, 14d4b8e, caused shim failed to parse the name of the 2nd stage loader in UEFI shell. Amend parsing of the name the 2nd stage loader to be compatible with UEFI shell. To create an boot entry for elilo.efi: # efibootmgr -c -L "shim elilo" -l "efi\\shim.efi" -u "shim.efi elilo.efi" --- shim.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/shim.c b/shim.c index d1071d68..0113ed5e 100644 --- a/shim.c +++ b/shim.c @@ -1329,9 +1329,10 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle) { EFI_STATUS status; EFI_LOADED_IMAGE *li; - CHAR16 *bootpath = NULL; CHAR16 *start = NULL, *c; int i, remaining_size = 0; + CHAR16 *loader_str = NULL; + int loader_len = 0; second_stage = DEFAULT_LOADER; load_options = NULL; @@ -1353,6 +1354,11 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle) return EFI_BAD_BUFFER_SIZE; } + /* + * UEFI shell copies the whole line of the command into LoadOptions. + * We ignore the string before the first L' ', i.e. the name of this + * program. + */ for (i = 0; i < li->LoadOptionsSize; i += 2) { c = (CHAR16 *)(li->LoadOptions + i); if (*c == L' ') { @@ -1363,11 +1369,30 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle) } } - bootpath = DevicePathToStr(li->FilePath); - if (!StrCaseCmp(bootpath, (CHAR16 *)li->LoadOptions)) - second_stage = (CHAR16 *)li->LoadOptions; + if (!start || remaining_size <= 0) + return EFI_SUCCESS; - if (start && remaining_size > 0) { + for (i = 0; start[i] != '\0'; i++) { + if (start[i] == L' ' || start[i] == L'\0') + break; + loader_len++; + } + + /* + * Setup the name of the alternative loader and the LoadOptions for + * the loader + */ + if (loader_len > 0) { + loader_str = AllocatePool((loader_len + 1) * sizeof(CHAR16)); + if (!loader_str) { + Print(L"Failed to allocate loader string\n"); + return EFI_OUT_OF_RESOURCES; + } + for (i = 0; i < loader_len; i++) + loader_str[i] = start[i]; + loader_str[loader_len] = L'\0'; + + second_stage = loader_str; load_options = start; load_options_size = remaining_size; } @@ -1444,5 +1469,11 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab) uefi_call_wrapper(BS->UninstallProtocolInterface, 3, handle, &shim_lock_guid, &shim_lock_interface); + /* + * Free the space allocated for the alternative 2nd stage loader + */ + if (load_options_size > 0) + FreePool(second_stage); + return efi_status; } -- cgit v1.2.3 From 8f6eace1897d210ec98fdc358f51345021b5a892 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 30 Apr 2013 09:46:22 -0400 Subject: Add StrCSpn() Signed-off-by: Peter Jones --- ucs2.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/ucs2.h b/ucs2.h index 03742847..d2ad6490 100644 --- a/ucs2.h +++ b/ucs2.h @@ -73,4 +73,20 @@ StrnCaseCmp(CHAR16 *s0, CHAR16 *s1, int n) return 0; } +static inline UINTN +__attribute__((unused)) +StrCSpn(const CHAR16 *s, const CHAR16 *reject) +{ + UINTN ret; + + for (ret = 0; s[ret] != L'\0'; ret++) { + int i; + for (i = 0; reject[i] != L'\0'; i++) { + if (reject[i] == s[ret]) + return ret; + } + } + return ret; +} + #endif /* SHIM_UCS2_H */ -- cgit v1.2.3 From eb9f7f1c23e682040240aaa399efa33488875fe9 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 30 Apr 2013 09:46:22 -0400 Subject: Add a fallback loader for when shim is invoked as BOOTX64.EFI If shim is invoked as \EFI\BOOT\BOOT*.EFI and a file exists named \EFI\BOOT\FALLBACK.EFI, try it instead of our second stage. So don't put fallback.efi on your install media in \EFI\BOOT, because that won't do whatever it is you're hoping for, unless you're hoping not to start the installer. So here's the process for using this: in /EFI/fedora/ (or whichever directory you happen to own), you put: shim.efi grub.efi boot.csv - format is: shim.efi,Nice Label,cmdline arguments,comments - filenames refer only to files in this directory, with no leading characters such as L"./" or L"/EFI/fedora/" - note that while this is CSV, the character encoding is UCS-2 and if /EFI/BOOT/BOOTX64.EFI doesn't already exist, then in /EFI/BOOT: shim.efi as BOOTX64.EFI fallback.efi Signed-off-by: Peter Jones --- Makefile | 9 +- fallback.c | 619 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 627 insertions(+), 1 deletion(-) create mode 100644 fallback.c diff --git a/Makefile b/Makefile index 412eba5e..ba62f510 100644 --- a/Makefile +++ b/Makefile @@ -28,12 +28,14 @@ LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH VERSION = 0.2 -TARGET = shim.efi MokManager.efi.signed +TARGET = shim.efi MokManager.efi.signed fallback.efi.signed OBJS = shim.o netboot.o cert.o dbx.o KEYS = shim_cert.h ocsp.* ca.* shim.crt shim.csr shim.p12 shim.pem shim.key SOURCES = shim.c shim.h netboot.c signature.h PeImage.h MOK_OBJS = MokManager.o MOK_SOURCES = MokManager.c shim.h +FALLBACK_OBJS = fallback.o +FALLBACK_SRCS = fallback.c all: $(TARGET) @@ -65,6 +67,11 @@ dbx.o : dbx.S shim.so: $(OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) +fallback.o: $(FALLBACK_SRCS) + +fallback.so: $(FALLBACK_OBJS) + $(LD) -o $@ $(LDFLAGS) $^ $(EFI_LIBS) + MokManager.o: $(SOURCES) MokManager.so: $(MOK_OBJS) Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a diff --git a/fallback.c b/fallback.c new file mode 100644 index 00000000..8f9bcbe9 --- /dev/null +++ b/fallback.c @@ -0,0 +1,619 @@ +/* + * Copyright 2012-2013 Red Hat, Inc. + * All rights reserved. + * + * See "COPYING" for license terms. + * + * Author(s): Peter Jones + */ + +#include +#include + +#include "ucs2.h" + +EFI_LOADED_IMAGE *this_image = NULL; + +static EFI_STATUS +get_file_size(EFI_FILE_HANDLE fh, UINT64 *retsize) +{ + EFI_STATUS rc; + void *buffer = NULL; + UINTN bs = 0; + EFI_GUID finfo = EFI_FILE_INFO_ID; + + /* The API here is "Call it once with bs=0, it fills in bs, + * then allocate a buffer and ask again to get it filled. */ + rc = uefi_call_wrapper(fh->GetInfo, 4, fh, &finfo, &bs, NULL); + if (rc == EFI_BUFFER_TOO_SMALL) { + buffer = AllocateZeroPool(bs); + if (!buffer) { + Print(L"Could not allocate memory\n"); + return EFI_OUT_OF_RESOURCES; + } + rc = uefi_call_wrapper(fh->GetInfo, 4, fh, &finfo, + &bs, buffer); + } + /* This checks *either* the error from the first GetInfo, if it isn't + * the EFI_BUFFER_TOO_SMALL we're expecting, or the second GetInfo call + * in *any* case. */ + if (EFI_ERROR(rc)) { + Print(L"Could not get file info: %d\n", rc); + if (buffer) + FreePool(buffer); + return rc; + } + EFI_FILE_INFO *fi = buffer; + *retsize = fi->FileSize; + FreePool(buffer); + return EFI_SUCCESS; +} + +EFI_STATUS +read_file(EFI_FILE_HANDLE fh, CHAR16 *fullpath, CHAR16 **buffer, UINT64 *bs) +{ + EFI_FILE_HANDLE fh2; + EFI_STATUS rc = uefi_call_wrapper(fh->Open, 5, fh, &fh2, fullpath, + EFI_FILE_READ_ONLY, 0); + if (EFI_ERROR(rc)) { + Print(L"Couldn't open \"%s\": %d\n", fullpath, rc); + return rc; + } + + UINT64 len = 0; + CHAR16 *b = NULL; + rc = get_file_size(fh2, &len); + if (EFI_ERROR(rc)) { + uefi_call_wrapper(fh2->Close, 1, fh2); + return rc; + } + + b = AllocateZeroPool(len + 2); + if (!buffer) { + Print(L"Could not allocate memory\n"); + uefi_call_wrapper(fh2->Close, 1, fh2); + return EFI_OUT_OF_RESOURCES; + } + + rc = uefi_call_wrapper(fh->Read, 3, fh, &len, b); + if (EFI_ERROR(rc)) { + FreePool(buffer); + uefi_call_wrapper(fh2->Close, 1, fh2); + Print(L"Could not read file: %d\n", rc); + return rc; + } + *buffer = b; + *bs = len; + uefi_call_wrapper(fh2->Close, 1, fh2); + return EFI_SUCCESS; +} + +EFI_STATUS +make_full_path(CHAR16 *dirname, CHAR16 *filename, CHAR16 **out, UINT64 *outlen) +{ + UINT64 len; + + len = StrLen(dirname) + StrLen(filename) + StrLen(L"\\EFI\\\\") + 2; + + CHAR16 *fullpath = AllocateZeroPool(len); + if (!fullpath) { + Print(L"Could not allocate memory\n"); + return EFI_OUT_OF_RESOURCES; + } + + StrCat(fullpath, L"\\EFI\\"); + StrCat(fullpath, dirname); + StrCat(fullpath, L"\\"); + StrCat(fullpath, filename); + + *out = fullpath; + *outlen = len; + return EFI_SUCCESS; +} + +CHAR16 *bootorder = NULL; +int nbootorder = 0; + +EFI_STATUS +add_boot_option(EFI_DEVICE_PATH *dp, CHAR16 *filename, CHAR16 *label, CHAR16 *arguments) +{ + static int i = 0; + CHAR16 varname[] = L"Boot0000"; + CHAR16 hexmap[] = L"0123456789ABCDEF"; + EFI_GUID global = EFI_GLOBAL_VARIABLE; + EFI_STATUS rc; + + for(; i <= 0xffff; i++) { + varname[4] = hexmap[(i & 0xf000) >> 12]; + varname[5] = hexmap[(i & 0x0f00) >> 8]; + varname[6] = hexmap[(i & 0x00f0) >> 4]; + varname[7] = hexmap[(i & 0x000f) >> 0]; + + void *var = LibGetVariable(varname, &global); + if (!var) { + int size = sizeof(UINT32) + sizeof (UINT16) + + StrLen(label)*2 + 2 + DevicePathSize(dp) + + StrLen(arguments) * 2 + 2; + + CHAR8 *data = AllocateZeroPool(size); + CHAR8 *cursor = data; + *(UINT32 *)cursor = LOAD_OPTION_ACTIVE; + cursor += sizeof (UINT32); + *(UINT16 *)cursor = DevicePathSize(dp); + cursor += sizeof (UINT16); + StrCpy((CHAR16 *)cursor, label); + cursor += StrLen(label)*2 + 2; + CopyMem(cursor, dp, DevicePathSize(dp)); + cursor += DevicePathSize(dp); + StrCpy((CHAR16 *)cursor, arguments); + + Print(L"Creating boot entry \"%s\" with label \"%s\" " + L"for file \"%s\"\n", + varname, label, filename); + rc = uefi_call_wrapper(RT->SetVariable, 5, varname, + &global, EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, data); + + FreePool(data); + + if (EFI_ERROR(rc)) { + Print(L"Could not create variable: %d\n", rc); + return rc; + } + + CHAR16 *newbootorder = AllocateZeroPool(sizeof (CHAR16) + * (nbootorder + 1)); + if (!newbootorder) + return EFI_OUT_OF_RESOURCES; + + int j = 0; + if (nbootorder) { + for (j = 0; j < nbootorder; j++) + newbootorder[j] = bootorder[j]; + FreePool(bootorder); + } + newbootorder[j] = i & 0xffff; + bootorder = newbootorder; + nbootorder += 1; +#ifdef DEBUG_FALLBACK + Print(L"nbootorder: %d\nBootOrder: ", nbootorder); + for (j = 0 ; j < nbootorder ; j++) + Print(L"%04x ", bootorder[j]); + Print(L"\n"); +#endif + + return EFI_SUCCESS; + } + } + return EFI_OUT_OF_RESOURCES; +} + +EFI_STATUS +update_boot_order(void) +{ + CHAR16 *oldbootorder; + UINTN size; + EFI_GUID global = EFI_GLOBAL_VARIABLE; + CHAR16 *newbootorder = NULL; + + oldbootorder = LibGetVariableAndSize(L"BootOrder", &global, &size); + if (oldbootorder) { + int n = size / sizeof (CHAR16) + nbootorder; + + newbootorder = AllocateZeroPool(n * sizeof (CHAR16)); + CopyMem(newbootorder, bootorder, nbootorder * sizeof (CHAR16)); + CopyMem(newbootorder + nbootorder, oldbootorder, size); + size = n * sizeof (CHAR16); + } else { + size = nbootorder * sizeof(CHAR16); + newbootorder = AllocateZeroPool(size); + CopyMem(newbootorder, bootorder, size); + } + if (!newbootorder) + return EFI_OUT_OF_RESOURCES; + +#ifdef DEBUG_FALLBACK + Print(L"nbootorder: %d\nBootOrder: ", size / sizeof (CHAR16)); + int j; + for (j = 0 ; j < size / sizeof (CHAR16); j++) + Print(L"%04x ", newbootorder[j]); + Print(L"\n"); +#endif + + if (oldbootorder) { + LibDeleteVariable(L"BootOrder", &global); + FreePool(oldbootorder); + } + + EFI_STATUS rc; + rc = uefi_call_wrapper(RT->SetVariable, 5, L"BootOrder", &global, + EFI_VARIABLE_NON_VOLATILE | + EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS, + size, newbootorder); + FreePool(newbootorder); + return rc; +} + +EFI_STATUS +add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *label, CHAR16 *arguments) +{ + CHAR16 *fullpath = NULL; + UINT64 pathlen = 0; + EFI_STATUS rc = EFI_SUCCESS; + + rc = make_full_path(dirname, filename, &fullpath, &pathlen); + if (EFI_ERROR(rc)) + return rc; + + EFI_DEVICE_PATH *dph = NULL, *dpf = NULL, *dp = NULL; + + dph = DevicePathFromHandle(this_image->DeviceHandle); + if (!dph) { + rc = EFI_OUT_OF_RESOURCES; + goto err; + } + + dpf = FileDevicePath(fh, fullpath); + if (!dpf) { + rc = EFI_OUT_OF_RESOURCES; + goto err; + } + + dp = AppendDevicePath(dph, dpf); + if (!dp) { + rc = EFI_OUT_OF_RESOURCES; + goto err; + } + +#ifdef DEBUG_FALLBACK + UINTN s = DevicePathSize(dp); + int i; + UINT8 *dpv = (void *)dp; + for (i = 0; i < s; i++) { + if (i > 0 && i % 16 == 0) + Print(L"\n"); + Print(L"%02x ", dpv[i]); + } + Print(L"\n"); + + CHAR16 *dps = DevicePathToStr(dp); + Print(L"device path: \"%s\"\n", dps); +#endif + + add_boot_option(dp, fullpath, label, arguments); + FreePool(fullpath); + +err: + if (dph) + FreePool(dph); + if (dpf) + FreePool(dpf); + if (dp) + FreePool(dp); + if (fullpath) + FreePool(fullpath); + return rc; +} + +EFI_STATUS +populate_stanza(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 *csv) +{ +#ifdef DEBUG_FALLBACK + Print(L"CSV data: \"%s\"\n", csv); +#endif + CHAR16 *file = csv; + + UINTN comma0 = StrCSpn(csv, L","); + if (comma0 == 0) + return EFI_INVALID_PARAMETER; + file[comma0] = L'\0'; +#ifdef DEBUG_FALLBACK + Print(L"filename: \"%s\"\n", file); +#endif + + CHAR16 *label = csv + comma0 + 1; + UINTN comma1 = StrCSpn(label, L","); + if (comma1 == 0) + return EFI_INVALID_PARAMETER; + label[comma1] = L'\0'; +#ifdef DEBUG_FALLBACK + Print(L"label: \"%s\"\n", label); +#endif + + CHAR16 *arguments = csv + comma0 +1 + comma1 +1; + UINTN comma2 = StrCSpn(arguments, L","); + arguments[comma2] = L'\0'; + /* This one is optional, so don't check if comma2 is 0 */ +#ifdef DEBUG_FALLBACK + Print(L"arguments: \"%s\"\n", arguments); +#endif + + add_to_boot_list(fh, dirname, file, label, arguments); + + return EFI_SUCCESS; +} + +EFI_STATUS +try_boot_csv(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename) +{ + CHAR16 *fullpath = NULL; + UINT64 pathlen = 0; + EFI_STATUS rc; + + rc = make_full_path(dirname, filename, &fullpath, &pathlen); + if (EFI_ERROR(rc)) + return rc; + +#ifdef DEBUG_FALLBACK + Print(L"Found file \"%s\"\n", fullpath); +#endif + + CHAR16 *buffer; + UINT64 bs; + rc = read_file(fh, fullpath, &buffer, &bs); + if (EFI_ERROR(rc)) { + Print(L"Could not read file \"%s\": %d\n", fullpath, rc); + FreePool(fullpath); + return rc; + } + FreePool(fullpath); + +#ifdef DEBUG_FALLBACK + Print(L"File looks like:\n%s\n", buffer); +#endif + + CHAR16 *start = buffer; + /* If I create boot.csv with the efi shell's "edit" command, + * it starts with 0xfeff. I assume there's some reason for this, + * but it doesn't matter much to me... + */ + if (*start == 0xfeff) + start++; + while (*start) { + while (*start == L'\r' || *start == L'\n') { + start++; + continue; + } + UINTN l = StrCSpn(start, L"\r\n"); + if (l == 0) { + if (start[l] == L'\0') + break; + start++; + continue; + } + CHAR16 c = start[l]; + start[l] = L'\0'; + + populate_stanza(fh, dirname, filename, start); + + start[l] = c; + start += l; + } + + FreePool(buffer); + return EFI_SUCCESS; +} + +EFI_STATUS +find_boot_csv(EFI_FILE_HANDLE fh, CHAR16 *dirname) +{ + EFI_STATUS rc; + void *buffer = NULL; + UINTN bs = 0; + EFI_GUID finfo = EFI_FILE_INFO_ID; + + /* The API here is "Call it once with bs=0, it fills in bs, + * then allocate a buffer and ask again to get it filled. */ + rc = uefi_call_wrapper(fh->GetInfo, 4, fh, &finfo, &bs, NULL); + if (rc == EFI_BUFFER_TOO_SMALL) { + buffer = AllocateZeroPool(bs); + if (!buffer) { + Print(L"Could not allocate memory\n"); + return EFI_OUT_OF_RESOURCES; + } + rc = uefi_call_wrapper(fh->GetInfo, 4, fh, &finfo, + &bs, buffer); + } + /* This checks *either* the error from the first GetInfo, if it isn't + * the EFI_BUFFER_TOO_SMALL we're expecting, or the second GetInfo call + * in *any* case. */ + if (EFI_ERROR(rc)) { + Print(L"Could not get info for \"%s\": %d\n", dirname, rc); + if (buffer) + FreePool(buffer); + return rc; + } + + EFI_FILE_INFO *fi = buffer; + if (!(fi->Attribute & EFI_FILE_DIRECTORY)) { + FreePool(buffer); + return EFI_SUCCESS; + } + FreePool(buffer); + + bs = 0; + do { + bs = 0; + rc = uefi_call_wrapper(fh->Read, 3, fh, &bs, NULL); + if (rc == EFI_BUFFER_TOO_SMALL) { + buffer = AllocateZeroPool(bs); + if (!buffer) { + Print(L"Could not allocate memory\n"); + return EFI_OUT_OF_RESOURCES; + } + + rc = uefi_call_wrapper(fh->Read, 3, fh, &bs, buffer); + } + if (EFI_ERROR(rc)) { + Print(L"Could not read \\EFI\\%s\\: %d\n", dirname, rc); + FreePool(buffer); + return rc; + } + if (bs == 0) + break; + + fi = buffer; + + if (!StrCaseCmp(fi->FileName, L"boot.csv")) { + EFI_FILE_HANDLE fh2; + rc = uefi_call_wrapper(fh->Open, 5, fh, &fh2, + fi->FileName, + EFI_FILE_READ_ONLY, 0); + if (EFI_ERROR(rc) || fh2 == NULL) { + Print(L"Couldn't open \\EFI\\%s\\%s: %d\n", + dirname, fi->FileName, rc); + FreePool(buffer); + buffer = NULL; + continue; + } + rc = try_boot_csv(fh2, dirname, fi->FileName); + uefi_call_wrapper(fh2->Close, 1, fh2); + } + + FreePool(buffer); + buffer = NULL; + } while (bs != 0); + + rc = EFI_SUCCESS; + if (nbootorder > 0) + rc = update_boot_order(); + + return rc; +} + +EFI_STATUS +find_boot_options(EFI_HANDLE device) +{ + EFI_STATUS rc = EFI_SUCCESS; + + EFI_FILE_IO_INTERFACE *fio = NULL; + rc = uefi_call_wrapper(BS->HandleProtocol, 3, device, + &FileSystemProtocol, &fio); + if (EFI_ERROR(rc)) { + Print(L"Couldn't find file system: %d\n", rc); + return rc; + } + + /* EFI_FILE_HANDLE is a pointer to an EFI_FILE, and I have + * *no idea* what frees the memory allocated here. Hopefully + * Close() does. */ + EFI_FILE_HANDLE fh = NULL; + rc = uefi_call_wrapper(fio->OpenVolume, 2, fio, &fh); + if (EFI_ERROR(rc) || fh == NULL) { + Print(L"Couldn't open file system: %d\n", rc); + return rc; + } + + EFI_FILE_HANDLE fh2 = NULL; + rc = uefi_call_wrapper(fh->Open, 5, fh, &fh2, L"EFI", + EFI_FILE_READ_ONLY, 0); + if (EFI_ERROR(rc) || fh2 == NULL) { + Print(L"Couldn't open EFI: %d\n", rc); + uefi_call_wrapper(fh->Close, 1, fh); + return rc; + } + rc = uefi_call_wrapper(fh2->SetPosition, 2, fh2, 0); + if (EFI_ERROR(rc)) { + Print(L"Couldn't set file position: %d\n", rc); + uefi_call_wrapper(fh2->Close, 1, fh2); + uefi_call_wrapper(fh->Close, 1, fh); + return rc; + } + + void *buffer; + UINTN bs; + do { + bs = 0; + rc = uefi_call_wrapper(fh2->Read, 3, fh2, &bs, NULL); + if (rc == EFI_BUFFER_TOO_SMALL || + (rc == EFI_SUCCESS && bs != 0)) { + buffer = AllocateZeroPool(bs); + if (!buffer) { + Print(L"Could not allocate memory\n"); + /* sure, this might work, why not? */ + uefi_call_wrapper(fh2->Close, 1, fh2); + uefi_call_wrapper(fh->Close, 1, fh); + return EFI_OUT_OF_RESOURCES; + } + + rc = uefi_call_wrapper(fh2->Read, 3, fh2, &bs, buffer); + } + if (bs == 0) + break; + + if (EFI_ERROR(rc)) { + Print(L"Could not read \\EFI\\: %d\n", rc); + if (buffer) { + FreePool(buffer); + buffer = NULL; + } + uefi_call_wrapper(fh2->Close, 1, fh2); + uefi_call_wrapper(fh->Close, 1, fh); + return rc; + } + EFI_FILE_INFO *fi = buffer; + + if (!(fi->Attribute & EFI_FILE_DIRECTORY)) { + FreePool(buffer); + buffer = NULL; + continue; + } + if (!StrCmp(fi->FileName, L".") || + !StrCmp(fi->FileName, L"..") || + !StrCaseCmp(fi->FileName, L"BOOT")) { + FreePool(buffer); + buffer = NULL; + continue; + } +#ifdef DEBUG_FALLBACK + Print(L"Found directory named \"%s\"\n", fi->FileName); +#endif + + EFI_FILE_HANDLE fh3; + rc = uefi_call_wrapper(fh->Open, 5, fh2, &fh3, fi->FileName, + EFI_FILE_READ_ONLY, 0); + if (EFI_ERROR(rc)) { + Print(L"%d Couldn't open %s: %d\n", __LINE__, fi->FileName, rc); + FreePool(buffer); + buffer = NULL; + continue; + } + + rc = find_boot_csv(fh3, fi->FileName); + FreePool(buffer); + buffer = NULL; + if (rc == EFI_OUT_OF_RESOURCES) + break; + + } while (1); + + uefi_call_wrapper(fh2->Close, 1, fh2); + uefi_call_wrapper(fh->Close, 1, fh); + return EFI_SUCCESS; +} +EFI_STATUS +efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) +{ + EFI_STATUS rc; + + InitializeLib(image, systab); + + rc = uefi_call_wrapper(BS->HandleProtocol, 3, image, &LoadedImageProtocol, (void *)&this_image); + if (EFI_ERROR(rc)) { + Print(L"Error: could not find loaded image: %d\n", rc); + return rc; + } + + Print(L"System BootOrder not found. Initializing defaults.\n"); + + rc = find_boot_options(this_image->DeviceHandle); + if (EFI_ERROR(rc)) { + Print(L"Error: could not find boot options: %d\n", rc); + return rc; + } + + return EFI_SUCCESS; +} -- cgit v1.2.3 From 6d6b0221693c46adae695e573b300b775d352be6 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 30 Apr 2013 09:46:22 -0400 Subject: Make shim use fallback when appropriate. If we're called as /BOOT/EFI/BOOT*.EFI, and /BOOT/EFI/FALLBACK.EFI exists, give it a shot. Signed-off-by: Peter Jones --- shim.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/shim.c b/shim.c index 0113ed5e..f2b8f1d1 100644 --- a/shim.c +++ b/shim.c @@ -44,6 +44,7 @@ #include "ucs2.h" #define DEFAULT_LOADER L"\\grub.efi" +#define FALLBACK L"\\fallback.efi" #define MOK_MANAGER L"\\MokManager.efi" static EFI_SYSTEM_TABLE *systab; @@ -899,6 +900,69 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize, return EFI_SUCCESS; } +static int +should_use_fallback(EFI_HANDLE image_handle) +{ + EFI_GUID loaded_image_protocol = LOADED_IMAGE_PROTOCOL; + EFI_LOADED_IMAGE *li; + EFI_DEVICE_PATH *devpath; + int i; + unsigned int pathlen = 0; + CHAR16 *bootpath; + EFI_FILE_IO_INTERFACE *fio = NULL; + EFI_FILE_HANDLE vh; + EFI_FILE_HANDLE fh; + EFI_STATUS rc; + + rc = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle, + &loaded_image_protocol, (void **)&li); + if (EFI_ERROR(rc)) + return 0; + + devpath = li->FilePath; + + bootpath = DevicePathToStr(devpath); + + /* Check the beginning of the string and the end, to avoid + * caring about which arch this is. */ + /* I really don't know why, but sometimes bootpath gives us + * L"\\EFI\\BOOT\\/BOOTX64.EFI". So just handle that here... + */ + if (StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\BOOT", 14) && + StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\/BOOT", 15)) + return 0; + pathlen = StrLen(bootpath); + if (pathlen < 5 || StrCaseCmp(bootpath + pathlen - 4, L".EFI")) + return 0; + + for (i=pathlen; i>0; i--) { + if (bootpath[i] == '\\') + break; + } + + bootpath[i+1] = '\0'; + + rc = uefi_call_wrapper(BS->HandleProtocol, 3, li->DeviceHandle, + &FileSystemProtocol, &fio); + if (EFI_ERROR(rc)) + return 0; + + rc = uefi_call_wrapper(fio->OpenVolume, 2, fio, &vh); + if (EFI_ERROR(rc)) + return 0; + + rc = uefi_call_wrapper(vh->Open, 5, vh, &fh, L"\\EFI\\BOOT" FALLBACK, + EFI_FILE_READ_ONLY, 0); + if (EFI_ERROR(rc)) { + uefi_call_wrapper(vh->Close, 1, vh); + return 0; + } + uefi_call_wrapper(fh->Close, 1, fh); + uefi_call_wrapper(vh->Close, 1, vh); + + return 1; +} + /* * Generate the path of an executable given shim's path and the name * of the executable @@ -1202,7 +1266,10 @@ EFI_STATUS init_grub(EFI_HANDLE image_handle) { EFI_STATUS efi_status; - efi_status = start_image(image_handle, second_stage); + if (should_use_fallback(image_handle)) + efi_status = start_image(image_handle, FALLBACK); + else + efi_status = start_image(image_handle, second_stage); if (efi_status != EFI_SUCCESS) efi_status = start_image(image_handle, MOK_MANAGER); -- cgit v1.2.3 From e172354b7ebe7850565208260e9ffff6bf679283 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 30 Apr 2013 09:46:22 -0400 Subject: Fix error checking on AllocateZeroPool() in update_boot_order() Signed-off-by: Peter Jones --- fallback.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fallback.c b/fallback.c index 8f9bcbe9..7f4f8836 100644 --- a/fallback.c +++ b/fallback.c @@ -203,16 +203,18 @@ update_boot_order(void) int n = size / sizeof (CHAR16) + nbootorder; newbootorder = AllocateZeroPool(n * sizeof (CHAR16)); + if (!newbootorder) + return EFI_OUT_OF_RESOURCES; CopyMem(newbootorder, bootorder, nbootorder * sizeof (CHAR16)); CopyMem(newbootorder + nbootorder, oldbootorder, size); size = n * sizeof (CHAR16); } else { size = nbootorder * sizeof(CHAR16); newbootorder = AllocateZeroPool(size); + if (!newbootorder) + return EFI_OUT_OF_RESOURCES; CopyMem(newbootorder, bootorder, size); } - if (!newbootorder) - return EFI_OUT_OF_RESOURCES; #ifdef DEBUG_FALLBACK Print(L"nbootorder: %d\nBootOrder: ", size / sizeof (CHAR16)); -- cgit v1.2.3 From 404e12634438db526db3cebbff2e1899a2e3431a Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 30 Apr 2013 09:46:22 -0400 Subject: Get rid of extra "continue". It's confusing, and it doesn't actually accomplish anything when applied to *either* loop. Signed-off-by: Peter Jones --- fallback.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/fallback.c b/fallback.c index 7f4f8836..00017225 100644 --- a/fallback.c +++ b/fallback.c @@ -375,10 +375,8 @@ try_boot_csv(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename) if (*start == 0xfeff) start++; while (*start) { - while (*start == L'\r' || *start == L'\n') { + while (*start == L'\r' || *start == L'\n') start++; - continue; - } UINTN l = StrCSpn(start, L"\r\n"); if (l == 0) { if (start[l] == L'\0') -- cgit v1.2.3 From 17266fd0578e36dc9da0d5b52b017605d93554b0 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Tue, 30 Apr 2013 09:46:23 -0400 Subject: Fix crash due to memory allocation --- fallback.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fallback.c b/fallback.c index 00017225..5ba0b797 100644 --- a/fallback.c +++ b/fallback.c @@ -95,7 +95,7 @@ make_full_path(CHAR16 *dirname, CHAR16 *filename, CHAR16 **out, UINT64 *outlen) len = StrLen(dirname) + StrLen(filename) + StrLen(L"\\EFI\\\\") + 2; - CHAR16 *fullpath = AllocateZeroPool(len); + CHAR16 *fullpath = AllocateZeroPool(len*sizeof(CHAR16)); if (!fullpath) { Print(L"Could not allocate memory\n"); return EFI_OUT_OF_RESOURCES; @@ -286,11 +286,8 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 * #endif add_boot_option(dp, fullpath, label, arguments); - FreePool(fullpath); err: - if (dph) - FreePool(dph); if (dpf) FreePool(dpf); if (dp) -- cgit v1.2.3 From 117b1214d84392675f537ddfc126cd6e3d41facf Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Tue, 30 Apr 2013 09:46:23 -0400 Subject: Reset the system after restoring the boot entries --- fallback.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fallback.c b/fallback.c index 5ba0b797..6cc59aa6 100644 --- a/fallback.c +++ b/fallback.c @@ -612,5 +612,9 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) return rc; } + Print(L"Reset System\n"); + uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, + EFI_SUCCESS, 0, NULL); + return EFI_SUCCESS; } -- cgit v1.2.3 From 39baf6dff76ac3ab16d8831144a382f1ea6e9085 Mon Sep 17 00:00:00 2001 From: Gary Ching-Pang Lin Date: Tue, 30 Apr 2013 09:46:23 -0400 Subject: Don't update BootOrder until all csv files are processed --- fallback.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/fallback.c b/fallback.c index 6cc59aa6..d3179b6c 100644 --- a/fallback.c +++ b/fallback.c @@ -475,8 +475,6 @@ find_boot_csv(EFI_FILE_HANDLE fh, CHAR16 *dirname) } while (bs != 0); rc = EFI_SUCCESS; - if (nbootorder > 0) - rc = update_boot_order(); return rc; } @@ -587,9 +585,12 @@ find_boot_options(EFI_HANDLE device) } while (1); + if (rc == EFI_SUCCESS && nbootorder > 0) + rc = update_boot_order(); + uefi_call_wrapper(fh2->Close, 1, fh2); uefi_call_wrapper(fh->Close, 1, fh); - return EFI_SUCCESS; + return rc; } EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) -- cgit v1.2.3 From 4f80140b53ba290f3fb2dd4cf9af4637b28f24ed Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 30 Apr 2013 14:21:41 -0400 Subject: Explain byte order handling better. Signed-off-by: Peter Jones --- fallback.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/fallback.c b/fallback.c index d3179b6c..dab3d3dc 100644 --- a/fallback.c +++ b/fallback.c @@ -365,9 +365,13 @@ try_boot_csv(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename) #endif CHAR16 *start = buffer; - /* If I create boot.csv with the efi shell's "edit" command, - * it starts with 0xfeff. I assume there's some reason for this, - * but it doesn't matter much to me... + /* The file may or may not start with the Unicode byte order marker. + * Sadness ensues. Since UEFI is defined as LE, I'm going to decree + * that these files must also be LE. + * + * IT IS THUS SO. + * + * But if we find the LE byte order marker, just skip it. */ if (*start == 0xfeff) start++; -- cgit v1.2.3 From 8807e36aaecfa2c4c67b33480cf44182518e313c Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 2 May 2013 14:58:44 -0400 Subject: [fallback] Try to execute the first new boot option. I'm told rebooting is sometimes unreliable when called here, and we'll get bootx64.efi loaded anyway. I'll just assume that's true and try to load the first option, since it's clearly what we'd prefer happens next. Signed-off-by: Peter Jones --- fallback.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/fallback.c b/fallback.c index dab3d3dc..387c84a8 100644 --- a/fallback.c +++ b/fallback.c @@ -114,6 +114,10 @@ make_full_path(CHAR16 *dirname, CHAR16 *filename, CHAR16 **out, UINT64 *outlen) CHAR16 *bootorder = NULL; int nbootorder = 0; +EFI_DEVICE_PATH *first_new_option = NULL; +VOID *first_new_option_args = NULL; +UINTN first_new_option_size = 0; + EFI_STATUS add_boot_option(EFI_DEVICE_PATH *dp, CHAR16 *filename, CHAR16 *label, CHAR16 *arguments) { @@ -284,6 +288,13 @@ add_to_boot_list(EFI_FILE_HANDLE fh, CHAR16 *dirname, CHAR16 *filename, CHAR16 * CHAR16 *dps = DevicePathToStr(dp); Print(L"device path: \"%s\"\n", dps); #endif + if (!first_new_option) { + CHAR16 *dps = DevicePathToStr(dp); + Print(L"device path: \"%s\"\n", dps); + first_new_option = DuplicateDevicePath(dp); + first_new_option_args = arguments; + first_new_option_size = StrLen(arguments) * sizeof (CHAR16); + } add_boot_option(dp, fullpath, label, arguments); @@ -596,6 +607,33 @@ find_boot_options(EFI_HANDLE device) uefi_call_wrapper(fh->Close, 1, fh); return rc; } + +static EFI_STATUS +try_start_first_option(EFI_HANDLE parent_image_handle) +{ + EFI_STATUS rc; + EFI_HANDLE image_handle; + + if (!first_new_option) { + return EFI_SUCCESS; + } + + rc = uefi_call_wrapper(BS->LoadImage, 6, 0, parent_image_handle, + first_new_option, NULL, 0, + &image_handle); + if (EFI_ERROR(rc)) { + Print(L"LoadImage failed: %d\n", rc); + uefi_call_wrapper(BS->Stall, 1, 2000000); + return rc; + } + rc = uefi_call_wrapper(BS->StartImage, 3, image_handle, NULL, NULL); + if (EFI_ERROR(rc)) { + Print(L"StartImage failed: %d\n", rc); + uefi_call_wrapper(BS->Stall, 1, 2000000); + } + return rc; +} + EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) { @@ -617,8 +655,10 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) return rc; } + try_start_first_option(image); + Print(L"Reset System\n"); - uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm, + uefi_call_wrapper(RT->ResetSystem, 4, EfiResetCold, EFI_SUCCESS, 0, NULL); return EFI_SUCCESS; -- cgit v1.2.3 From 40cf2a423d7a080999cb22d0cb0bae33ab028c62 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Tue, 14 May 2013 13:10:52 -0400 Subject: Pass parameters correctly when booting. Signed-off-by: Peter Jones --- fallback.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fallback.c b/fallback.c index 387c84a8..cf1ebe46 100644 --- a/fallback.c +++ b/fallback.c @@ -626,6 +626,14 @@ try_start_first_option(EFI_HANDLE parent_image_handle) uefi_call_wrapper(BS->Stall, 1, 2000000); return rc; } + + EFI_LOADED_IMAGE *image; + rc = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle, &LoadedImageProtocol, (void *)&image); + if (!EFI_ERROR(rc)) { + image->LoadOptions = first_new_option_args; + image->LoadOptionsSize = first_new_option_size; + } + rc = uefi_call_wrapper(BS->StartImage, 3, image_handle, NULL, NULL); if (EFI_ERROR(rc)) { Print(L"StartImage failed: %d\n", rc); -- cgit v1.2.3 From 35b0b55b3ee0f6d6771c7992b8fefffc54bda48e Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Wed, 15 May 2013 13:37:15 -0400 Subject: Fix some minor type errors. Signed-off-by: Peter Jones --- fallback.c | 2 +- shim.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fallback.c b/fallback.c index cf1ebe46..82ddbf2f 100644 --- a/fallback.c +++ b/fallback.c @@ -501,7 +501,7 @@ find_boot_options(EFI_HANDLE device) EFI_FILE_IO_INTERFACE *fio = NULL; rc = uefi_call_wrapper(BS->HandleProtocol, 3, device, - &FileSystemProtocol, &fio); + &FileSystemProtocol, (void **)&fio); if (EFI_ERROR(rc)) { Print(L"Couldn't find file system: %d\n", rc); return rc; diff --git a/shim.c b/shim.c index f2b8f1d1..c1cf17ae 100644 --- a/shim.c +++ b/shim.c @@ -910,8 +910,8 @@ should_use_fallback(EFI_HANDLE image_handle) unsigned int pathlen = 0; CHAR16 *bootpath; EFI_FILE_IO_INTERFACE *fio = NULL; - EFI_FILE_HANDLE vh; - EFI_FILE_HANDLE fh; + EFI_FILE *vh; + EFI_FILE *fh; EFI_STATUS rc; rc = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle, @@ -943,7 +943,7 @@ should_use_fallback(EFI_HANDLE image_handle) bootpath[i+1] = '\0'; rc = uefi_call_wrapper(BS->HandleProtocol, 3, li->DeviceHandle, - &FileSystemProtocol, &fio); + &FileSystemProtocol, (void **)&fio); if (EFI_ERROR(rc)) return 0; -- cgit v1.2.3 From 2e7fc28d928117447b60ad4a0014d1d496fcabc0 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Wed, 15 May 2013 13:38:00 -0400 Subject: Remove some unnecessary code. Signed-off-by: Peter Jones --- shim.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/shim.c b/shim.c index c1cf17ae..33d4396d 100644 --- a/shim.c +++ b/shim.c @@ -905,8 +905,6 @@ should_use_fallback(EFI_HANDLE image_handle) { EFI_GUID loaded_image_protocol = LOADED_IMAGE_PROTOCOL; EFI_LOADED_IMAGE *li; - EFI_DEVICE_PATH *devpath; - int i; unsigned int pathlen = 0; CHAR16 *bootpath; EFI_FILE_IO_INTERFACE *fio = NULL; @@ -919,9 +917,7 @@ should_use_fallback(EFI_HANDLE image_handle) if (EFI_ERROR(rc)) return 0; - devpath = li->FilePath; - - bootpath = DevicePathToStr(devpath); + bootpath = DevicePathToStr(li->FilePath); /* Check the beginning of the string and the end, to avoid * caring about which arch this is. */ @@ -931,17 +927,11 @@ should_use_fallback(EFI_HANDLE image_handle) if (StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\BOOT", 14) && StrnCaseCmp(bootpath, L"\\EFI\\BOOT\\/BOOT", 15)) return 0; + pathlen = StrLen(bootpath); if (pathlen < 5 || StrCaseCmp(bootpath + pathlen - 4, L".EFI")) return 0; - for (i=pathlen; i>0; i--) { - if (bootpath[i] == '\\') - break; - } - - bootpath[i+1] = '\0'; - rc = uefi_call_wrapper(BS->HandleProtocol, 3, li->DeviceHandle, &FileSystemProtocol, (void **)&fio); if (EFI_ERROR(rc)) -- cgit v1.2.3 From c9d11306e4d6a4c4638735f15852b59f3585e792 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Wed, 15 May 2013 13:38:27 -0400 Subject: Add some error messages when things don't work. Signed-off-by: Peter Jones --- shim.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/shim.c b/shim.c index 33d4396d..16b2faa9 100644 --- a/shim.c +++ b/shim.c @@ -914,8 +914,10 @@ should_use_fallback(EFI_HANDLE image_handle) rc = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle, &loaded_image_protocol, (void **)&li); - if (EFI_ERROR(rc)) + if (EFI_ERROR(rc)) { + Print(L"Could not get image for bootx64.efi: %d\n", rc); return 0; + } bootpath = DevicePathToStr(li->FilePath); @@ -934,16 +936,21 @@ should_use_fallback(EFI_HANDLE image_handle) rc = uefi_call_wrapper(BS->HandleProtocol, 3, li->DeviceHandle, &FileSystemProtocol, (void **)&fio); - if (EFI_ERROR(rc)) + if (EFI_ERROR(rc)) { + Print(L"Could not get fio for li->DeviceHandle: %d\n", rc); return 0; + } rc = uefi_call_wrapper(fio->OpenVolume, 2, fio, &vh); - if (EFI_ERROR(rc)) + if (EFI_ERROR(rc)) { + Print(L"Could not open fio volume: %d\n", rc); return 0; + } rc = uefi_call_wrapper(vh->Open, 5, vh, &fh, L"\\EFI\\BOOT" FALLBACK, EFI_FILE_READ_ONLY, 0); if (EFI_ERROR(rc)) { + Print(L"Could not open \"\\EFI\\BOOT%s\": %d\n", FALLBACK, rc); uefi_call_wrapper(vh->Close, 1, vh); return 0; } -- cgit v1.2.3 From 5bb3e64ed8584947d6d92371f261c12c2421c263 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Wed, 15 May 2013 13:38:44 -0400 Subject: Use the correct define on Open. The value here doesn't actually change any, but we should still use the right name. Signed-off-by: Peter Jones --- shim.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shim.c b/shim.c index 16b2faa9..94b97104 100644 --- a/shim.c +++ b/shim.c @@ -948,7 +948,7 @@ should_use_fallback(EFI_HANDLE image_handle) } rc = uefi_call_wrapper(vh->Open, 5, vh, &fh, L"\\EFI\\BOOT" FALLBACK, - EFI_FILE_READ_ONLY, 0); + EFI_FILE_MODE_READ, 0); if (EFI_ERROR(rc)) { Print(L"Could not open \"\\EFI\\BOOT%s\": %d\n", FALLBACK, rc); uefi_call_wrapper(vh->Close, 1, vh); -- cgit v1.2.3 From aa55fcf149d34eb500eb3529f4cf7905bdba0e96 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 16 May 2013 10:21:15 -0400 Subject: Use MS ABI instead of terrible wrappers. This means that we now require gnu-efi 3.0s Signed-off-by: Peter Jones --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ba62f510..a634e306 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ CFLAGS = -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wcha -Wall -mno-red-zone \ $(EFI_INCLUDES) ifeq ($(ARCH),x86_64) - CFLAGS += -DEFI_FUNCTION_WRAPPER + CFLAGS += -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI endif ifneq ($(origin VENDOR_CERT_FILE), undefined) CFLAGS += -DVENDOR_CERT_FILE=\"$(VENDOR_CERT_FILE)\" -- cgit v1.2.3 From 8e7e92beb8898bdf745dfa362310f8d99cfe65b1 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 16 May 2013 11:03:32 -0400 Subject: Bump version to 0.3 Signed-off-by: Peter Jones --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index a634e306..287fbcf6 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ endif LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH) -L$(LIB_PATH) -LCryptlib -LCryptlib/OpenSSL $(EFI_CRT_OBJS) -VERSION = 0.2 +VERSION = 0.3 TARGET = shim.efi MokManager.efi.signed fallback.efi.signed OBJS = shim.o netboot.o cert.o dbx.o -- cgit v1.2.3 From 632503aa07db59cac13e1578428852aecc224563 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Fri, 31 May 2013 15:34:11 -0400 Subject: Don't use MMX and SSE registers, they aren't initialized. GCC 4.8.0 will try to use these by default, and you'll wind up looping across the (uninitialized!) trap handler for uninitialized instructions. Signed-off-by: Peter Jones --- Cryptlib/Makefile | 2 +- Cryptlib/OpenSSL/Makefile | 2 +- Makefile | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cryptlib/Makefile b/Cryptlib/Makefile index 925db8db..f1add83d 100644 --- a/Cryptlib/Makefile +++ b/Cryptlib/Makefile @@ -10,7 +10,7 @@ LIB_GCC = $(shell $(CC) -print-libgcc-file-name) EFI_LIBS = -lefi -lgnuefi $(LIB_GCC) CFLAGS = -ggdb -O0 -I. -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar \ - -Wall $(EFI_INCLUDES) -mno-red-zone + -Wall $(EFI_INCLUDES) -mno-red-zone -mno-sse -mno-mmx ifeq ($(ARCH),x86_64) CFLAGS += -DEFI_FUNCTION_WRAPPER endif diff --git a/Cryptlib/OpenSSL/Makefile b/Cryptlib/OpenSSL/Makefile index 7fde3829..1bae8414 100644 --- a/Cryptlib/OpenSSL/Makefile +++ b/Cryptlib/OpenSSL/Makefile @@ -9,7 +9,7 @@ EFI_PATH = /usr/lib64/gnuefi LIB_GCC = $(shell $(CC) -print-libgcc-file-name) EFI_LIBS = -lefi -lgnuefi $(LIB_GCC) -CFLAGS = -ggdb -O0 -I. -I.. -I../Include/ -Icrypto -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -nostdinc \ +CFLAGS = -ggdb -O0 -I. -I.. -I../Include/ -Icrypto -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -nostdinc -mno-mmx -mno-sse \ -Wall $(EFI_INCLUDES) -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -DSIXTY_FOUR_BIT_LONG -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SHA0 -DOPENSSL_NO_SHA512 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC -mno-red-zone ifeq ($(ARCH),x86_64) CFLAGS += -DEFI_FUNCTION_WRAPPER diff --git a/Makefile b/Makefile index 287fbcf6..c8f6ec82 100644 --- a/Makefile +++ b/Makefile @@ -14,8 +14,8 @@ EFI_LIBS = -lefi -lgnuefi --start-group Cryptlib/libcryptlib.a Cryptlib/OpenSSL/ EFI_CRT_OBJS = $(EFI_PATH)/crt0-efi-$(ARCH).o EFI_LDS = $(EFI_PATH)/elf_$(ARCH)_efi.lds -CFLAGS = -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar \ - -Wall -mno-red-zone \ +CFLAGS = -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \ + -fshort-wchar -Wall -mno-red-zone -mno-mmx -mno-sse \ $(EFI_INCLUDES) ifeq ($(ARCH),x86_64) CFLAGS += -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI -- cgit v1.2.3 From 6cd79ef9502d7ecc9b936824fde7d1e3b80f800d Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Fri, 31 May 2013 15:34:11 -0400 Subject: EFI_PXE_BASE_CODE_DHCPV6_PACKET is in gnu-efi-3.0t --- netboot.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/netboot.c b/netboot.c index 90fb9cba..c44aeac5 100644 --- a/netboot.c +++ b/netboot.c @@ -56,15 +56,6 @@ static EFI_IP_ADDRESS tftp_addr; static char *full_path; -/* - * Not in the EFI header set yet, so I have to declare it here - */ -typedef struct { - UINT32 MessageType:8; - UINT32 TransactionId:24; - UINT8 DhcpOptions[1024]; -} EFI_PXE_BASE_CODE_DHCPV6_PACKET; - typedef struct { UINT16 OpCode; UINT16 Length; -- cgit v1.2.3 From acf2e8ed1a3224017ab0987a7feccd25e098a4c2 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 10 Jun 2013 16:38:05 -0400 Subject: Make sure all the Makefiles use the same arguments for mmx/sse/ms_abi. Signed-off-by: Peter Jones --- Cryptlib/Makefile | 4 ++-- Cryptlib/OpenSSL/Makefile | 6 +++--- Makefile | 5 +++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Cryptlib/Makefile b/Cryptlib/Makefile index f1add83d..08908389 100644 --- a/Cryptlib/Makefile +++ b/Cryptlib/Makefile @@ -10,9 +10,9 @@ LIB_GCC = $(shell $(CC) -print-libgcc-file-name) EFI_LIBS = -lefi -lgnuefi $(LIB_GCC) CFLAGS = -ggdb -O0 -I. -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar \ - -Wall $(EFI_INCLUDES) -mno-red-zone -mno-sse -mno-mmx + -Wall $(EFI_INCLUDES) -mno-red-zone -maccumulate-outgoing-args -mno-sse -mno-mmx ifeq ($(ARCH),x86_64) - CFLAGS += -DEFI_FUNCTION_WRAPPER + CFLAGS += -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI endif LDFLAGS = -nostdlib -znocombreloc diff --git a/Cryptlib/OpenSSL/Makefile b/Cryptlib/OpenSSL/Makefile index 1bae8414..1960b6b3 100644 --- a/Cryptlib/OpenSSL/Makefile +++ b/Cryptlib/OpenSSL/Makefile @@ -9,10 +9,10 @@ EFI_PATH = /usr/lib64/gnuefi LIB_GCC = $(shell $(CC) -print-libgcc-file-name) EFI_LIBS = -lefi -lgnuefi $(LIB_GCC) -CFLAGS = -ggdb -O0 -I. -I.. -I../Include/ -Icrypto -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -nostdinc -mno-mmx -mno-sse \ - -Wall $(EFI_INCLUDES) -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -DSIXTY_FOUR_BIT_LONG -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SHA0 -DOPENSSL_NO_SHA512 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC -mno-red-zone +CFLAGS = -ggdb -O0 -I. -I.. -I../Include/ -Icrypto -fno-stack-protector -fno-strict-aliasing -fpic -fshort-wchar -nostdinc -mno-mmx -mno-sse -mno-red-zone -maccumulate-outgoing-args \ + -Wall $(EFI_INCLUDES) -DOPENSSL_SYSNAME_UWIN -DOPENSSL_SYS_UEFI -DL_ENDIAN -DSIXTY_FOUR_BIT_LONG -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_SEED -DOPENSSL_NO_RC5 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_SOCK -DOPENSSL_NO_CMS -DOPENSSL_NO_JPAKE -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_ERR -DOPENSSL_NO_KRB5 -DOPENSSL_NO_DYNAMIC_ENGINE -DGETPID_IS_MEANINGLESS -DOPENSSL_NO_STDIO -DOPENSSL_NO_FP_API -DOPENSSL_NO_DGRAM -DOPENSSL_NO_SHA0 -DOPENSSL_NO_SHA512 -DOPENSSL_NO_LHASH -DOPENSSL_NO_HW -DOPENSSL_NO_OCSP -DOPENSSL_NO_LOCKING -DOPENSSL_NO_DEPRECATED -DOPENSSL_SMALL_FOOTPRINT -DPEDANTIC ifeq ($(ARCH),x86_64) - CFLAGS += -DEFI_FUNCTION_WRAPPER + CFLAGS += -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI endif LDFLAGS = -nostdlib -znocombreloc diff --git a/Makefile b/Makefile index c8f6ec82..0c2b90b8 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ SUBDIRS = Cryptlib LIB_PATH = /usr/lib64 EFI_INCLUDE = /usr/include/efi -EFI_INCLUDES = -nostdinc -ICryptlib -ICryptlib/Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol +EFI_INCLUDES = -nostdinc -ICryptlib -ICryptlib/Include -I$(EFI_INCLUDE) -I$(EFI_INCLUDE)/$(ARCH) -I$(EFI_INCLUDE)/protocol EFI_PATH = /usr/lib64/gnuefi LIB_GCC = $(shell $(CC) -print-libgcc-file-name) @@ -15,7 +15,8 @@ EFI_CRT_OBJS = $(EFI_PATH)/crt0-efi-$(ARCH).o EFI_LDS = $(EFI_PATH)/elf_$(ARCH)_efi.lds CFLAGS = -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \ - -fshort-wchar -Wall -mno-red-zone -mno-mmx -mno-sse \ + -fshort-wchar -Wall -mno-red-zone -maccumulate-outgoing-args \ + -mno-mmx -mno-sse \ $(EFI_INCLUDES) ifeq ($(ARCH),x86_64) CFLAGS += -DEFI_FUNCTION_WRAPPER -DGNU_EFI_USE_MS_ABI -- cgit v1.2.3 From 1de10962e795d09981007a582fdaf1b859c368fe Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 10 Jun 2013 17:34:55 -0400 Subject: Remove FALLBACK_OBJS during clean as well. Signed-off-by: Peter Jones --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 0c2b90b8..e7f6e498 100644 --- a/Makefile +++ b/Makefile @@ -102,8 +102,8 @@ Cryptlib/OpenSSL/libopenssl.a: clean: $(MAKE) -C Cryptlib clean $(MAKE) -C Cryptlib/OpenSSL clean - rm -rf $(TARGET) $(OBJS) $(MOK_OBJS) $(KEYS) certdb - rm -f *.debug *.so + rm -rf $(TARGET) $(OBJS) $(MOK_OBJS) $(FALLBACK_OBJS) $(KEYS) certdb + rm -f *.debug *.so *.efi GITTAG = $(VERSION) -- cgit v1.2.3 From 6b4255de1203320a5a71f27b08e8e782d04c461c Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 10 Jun 2013 17:35:33 -0400 Subject: vendor_cert_size's size in the binary should be 4, not -4. The thing about subtraction is that the minuend needs to be before the subtrahend in the text. Signed-off-by: Peter Jones --- cert.S | 2 +- dbx.S | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cert.S b/cert.S index 7f89029e..70b9c3f2 100644 --- a/cert.S +++ b/cert.S @@ -10,7 +10,7 @@ vendor_cert_size: .data .align 1 .type vendor_cert, @object - .size vendor_cert_size, vendor_cert_size-vendor_cert + .size vendor_cert, .L0-vendor_cert vendor_cert: .incbin VENDOR_CERT_FILE .L0: diff --git a/dbx.S b/dbx.S index a26fc387..03db1aee 100644 --- a/dbx.S +++ b/dbx.S @@ -10,7 +10,7 @@ vendor_dbx_size: .data .align 1 .type vendor_dbx, @object - .size vendor_dbx_size, vendor_dbx_size-vendor_dbx + .size vendor_dbx, .L0-vendor_dbx vendor_dbx: .incbin VENDOR_DBX_FILE .L0: -- cgit v1.2.3 From c682b514bf057ca38eadcb330861b3fa5ead541d Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 10 Jun 2013 17:35:33 -0400 Subject: Move embedded certificates to their own section. With this change, the embedded certificate and dbx lists (vendor_cert, vendor_cert_size, vendor_dbx, and vendor_dbx_size) wind up being in a section named .vendor_cert, and so will look something like: ------ fenchurch:~/devel/github.com/shim$ objdump -h shim.efi shim.efi: file format pei-x86-64 Sections: Idx Name Size VMA LMA File off Algn 0 .eh_frame 000174a8 0000000000005000 0000000000005000 00000400 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 1 .text 000aa7e1 000000000001d000 000000000001d000 00017a00 2**4 CONTENTS, ALLOC, LOAD, READONLY, CODE 2 .reloc 0000000a 00000000000c8000 00000000000c8000 000c2200 2**0 CONTENTS, ALLOC, LOAD, READONLY, DATA 3 .data 00031228 00000000000c9000 00000000000c9000 000c2400 2**5 CONTENTS, ALLOC, LOAD, DATA 4 .vendor_cert 00000375 00000000000fb000 00000000000fb000 000f3800 2**0 CONTENTS, READONLY 5 .dynamic 000000f0 00000000000fc000 00000000000fc000 000f3c00 2**3 CONTENTS, ALLOC, LOAD, DATA 6 .rela 0002afa8 00000000000fd000 00000000000fd000 000f3e00 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA 7 .dynsym 0000f1f8 0000000000128000 0000000000128000 0011ee00 2**3 CONTENTS, ALLOC, LOAD, READONLY, DATA ------ This simplifies a security audit, because it means that different versions of shim with substantially the same code with different keys will be more easily comperable, and therefore logic differences may be more easily identified. This also means that if there's a trusted build you want to use, you can remove the certificates, implant new ones, and have it signed, and the code sections won't change. Signed-off-by: Peter Jones --- Makefile | 3 ++- cert.S | 4 +++ dbx.S | 4 +++ elf_ia32_efi.lds | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ elf_ia64_efi.lds | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ elf_x86_64_efi.lds | 68 +++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 elf_ia32_efi.lds create mode 100644 elf_ia64_efi.lds create mode 100644 elf_x86_64_efi.lds diff --git a/Makefile b/Makefile index e7f6e498..0c263924 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ LIB_GCC = $(shell $(CC) -print-libgcc-file-name) EFI_LIBS = -lefi -lgnuefi --start-group Cryptlib/libcryptlib.a Cryptlib/OpenSSL/libopenssl.a --end-group $(LIB_GCC) EFI_CRT_OBJS = $(EFI_PATH)/crt0-efi-$(ARCH).o -EFI_LDS = $(EFI_PATH)/elf_$(ARCH)_efi.lds +EFI_LDS = elf_$(ARCH)_efi.lds CFLAGS = -ggdb -O0 -fno-stack-protector -fno-strict-aliasing -fpic \ -fshort-wchar -Wall -mno-red-zone -maccumulate-outgoing-args \ @@ -88,6 +88,7 @@ Cryptlib/OpenSSL/libopenssl.a: objcopy -j .text -j .sdata -j .data \ -j .dynamic -j .dynsym -j .rel \ -j .rela -j .reloc -j .eh_frame \ + -j .vendor_cert \ --target=efi-app-$(ARCH) $^ $@ objcopy -j .text -j .sdata -j .data \ -j .dynamic -j .dynsym -j .rel \ diff --git a/cert.S b/cert.S index 70b9c3f2..4be0a241 100644 --- a/cert.S +++ b/cert.S @@ -4,6 +4,7 @@ .align 1 .type vendor_cert_size, @object .size vendor_cert_size, 4 + .section .vendor_cert, "", @progbits vendor_cert_size: .long .L0 - vendor_cert .globl vendor_cert @@ -11,6 +12,7 @@ vendor_cert_size: .align 1 .type vendor_cert, @object .size vendor_cert, .L0-vendor_cert + .section .vendor_cert, "", @progbits vendor_cert: .incbin VENDOR_CERT_FILE .L0: @@ -19,6 +21,7 @@ vendor_cert: .bss .type vendor_cert, @object .size vendor_cert, 1 + .section .vendor_cert, "", @progbits vendor_cert: .zero 1 @@ -27,6 +30,7 @@ vendor_cert: .align 4 .type vendor_cert_size, @object .size vendor_cert_size, 4 + .section .vendor_cert, "", @progbits vendor_cert_size: .long 1 #endif diff --git a/dbx.S b/dbx.S index 03db1aee..9ccdb676 100644 --- a/dbx.S +++ b/dbx.S @@ -4,6 +4,7 @@ .align 1 .type vendor_dbx_size, @object .size vendor_dbx_size, 4 + .section .vendor_cert, "", @progbits vendor_dbx_size: .long .L0 - vendor_dbx .globl vendor_dbx @@ -11,6 +12,7 @@ vendor_dbx_size: .align 1 .type vendor_dbx, @object .size vendor_dbx, .L0-vendor_dbx + .section .vendor_cert, "", @progbits vendor_dbx: .incbin VENDOR_DBX_FILE .L0: @@ -19,6 +21,7 @@ vendor_dbx: .bss .type vendor_dbx, @object .size vendor_dbx, 1 + .section .vendor_cert, "", @progbits vendor_dbx: .zero 1 @@ -27,6 +30,7 @@ vendor_dbx: .align 4 .type vendor_dbx_size, @object .size vendor_dbx_size, 4 + .section .vendor_cert, "", @progbits vendor_dbx_size: .long 0 #endif diff --git a/elf_ia32_efi.lds b/elf_ia32_efi.lds new file mode 100644 index 00000000..12d4085b --- /dev/null +++ b/elf_ia32_efi.lds @@ -0,0 +1,69 @@ +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") +OUTPUT_ARCH(i386) +ENTRY(_start) +SECTIONS +{ + . = 0; + ImageBase = .; + .hash : { *(.hash) } /* this MUST come first! */ + . = ALIGN(4096); + .text : + { + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + } + .reloc : + { + *(.reloc) + } + . = ALIGN(4096); + .data : + { + *(.rodata*) + *(.data) + *(.data1) + *(.data.*) + *(.sdata) + *(.got.plt) + *(.got) + /* the EFI loader doesn't seem to like a .bss section, so we stick + it all into .data: */ + *(.sbss) + *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + . = ALIGN(4096); + .vendor_cert : + { + *(.vendor_cert) + } + . = ALIGN(4096); + .dynamic : { *(.dynamic) } + . = ALIGN(4096); + .rel : + { + *(.rel.data) + *(.rel.data.*) + *(.rel.got) + *(.rel.stab) + *(.data.rel.ro.local) + *(.data.rel.local) + *(.data.rel.ro) + *(.data.rel*) + } + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } + . = ALIGN(4096); + /DISCARD/ : + { + *(.rel.reloc) + *(.eh_frame) + *(.note.GNU-stack) + } + .comment 0 : { *(.comment) } +} diff --git a/elf_ia64_efi.lds b/elf_ia64_efi.lds new file mode 100644 index 00000000..d8dea4b7 --- /dev/null +++ b/elf_ia64_efi.lds @@ -0,0 +1,75 @@ +OUTPUT_FORMAT("elf64-ia64-little") +OUTPUT_ARCH(ia64) +ENTRY(_start_plabel) +SECTIONS +{ + . = 0; + ImageBase = .; + .hash : { *(.hash) } /* this MUST come first! */ + . = ALIGN(4096); + .text : + { + *(.text) + *(.text.*) + *(.gnu.linkonce.t.*) + } + . = ALIGN(4096); + __gp = ALIGN (8) + 0x200000; + .sdata : + { + *(.got.plt) + *(.got) + *(.srodata) + *(.sdata) + *(.sbss) + *(.scommon) + } + . = ALIGN(4096); + .data : + { + *(.rodata*) + *(.ctors) + *(.data*) + *(.gnu.linkonce.d*) + *(.plabel) /* data whose relocs we want to ignore */ + /* the EFI loader doesn't seem to like a .bss section, so we stick + it all into .data: */ + *(.dynbss) + *(.bss) + *(COMMON) + } + . = ALIGN(4096); + .vendor_cert : + { + *(.vendor_cert) + } + . = ALIGN(4096); + .dynamic : { *(.dynamic) } + . = ALIGN(4096); + .rela : + { + *(.rela.text) + *(.rela.data*) + *(.rela.sdata) + *(.rela.got) + *(.rela.gnu.linkonce.d*) + *(.rela.stab) + *(.rela.ctors) + } + . = ALIGN(4096); + .reloc : /* This is the PECOFF .reloc section! */ + { + *(.reloc) + } + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } + /DISCARD/ : + { + *(.rela.plabel) + *(.rela.reloc) + *(.IA_64.unwind*) + *(.IA64.unwind*) + } +} diff --git a/elf_x86_64_efi.lds b/elf_x86_64_efi.lds new file mode 100644 index 00000000..f9811028 --- /dev/null +++ b/elf_x86_64_efi.lds @@ -0,0 +1,68 @@ +/* Same as elf_x86_64_fbsd_efi.lds, except for OUTPUT_FORMAT below - KEEP IN SYNC */ +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") +OUTPUT_ARCH(i386:x86-64) +ENTRY(_start) +SECTIONS +{ + . = 0; + ImageBase = .; + .hash : { *(.hash) } /* this MUST come first! */ + . = ALIGN(4096); + .eh_frame : + { + *(.eh_frame) + } + . = ALIGN(4096); + .text : + { + *(.text) + } + . = ALIGN(4096); + .reloc : + { + *(.reloc) + } + . = ALIGN(4096); + .data : + { + *(.rodata*) + *(.got.plt) + *(.got) + *(.data*) + *(.sdata) + /* the EFI loader doesn't seem to like a .bss section, so we stick + it all into .data: */ + *(.sbss) + *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + *(.rel.local) + } + . = ALIGN(4096); + .vendor_cert : + { + *(.vendor_cert) + } + . = ALIGN(4096); + .dynamic : { *(.dynamic) } + . = ALIGN(4096); + .rela : + { + *(.rela.data*) + *(.rela.got) + *(.rela.stab) + } + . = ALIGN(4096); + .dynsym : { *(.dynsym) } + . = ALIGN(4096); + .dynstr : { *(.dynstr) } + . = ALIGN(4096); + .ignored.reloc : + { + *(.rela.reloc) + *(.eh_frame) + *(.note.GNU-stack) + } + .comment 0 : { *(.comment) } +} -- cgit v1.2.3 From 63bdfd8501049f5b141b07cd147155e43e5f8b31 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 10 Jun 2013 17:36:22 -0400 Subject: add a .gitignore Signed-off-by: Peter Jones --- .gitignore | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..e46ec8a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +.*.sw? +certdb +shim_cert.h +*.a +*.cer +*.crl +*.crt +*.csr +*.db +*.db.attr +*.db.attr.old +*.db.old +*.domain.txt +*.efi +*.efi.debug +*.efi.signed +*.key +*.key +*.o +*.pem +*.p12 +*.so +*.srl +*.srl.old -- cgit v1.2.3 From f80edcbe7d004af24ad1d85655f1b04da5a2bb7f Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 10 Jun 2013 17:36:23 -0400 Subject: Make .vendor_cert get the right flags set. Signed-off-by: Peter Jones --- cert.S | 8 ++++---- dbx.S | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/cert.S b/cert.S index 4be0a241..2ed9b6d7 100644 --- a/cert.S +++ b/cert.S @@ -4,7 +4,7 @@ .align 1 .type vendor_cert_size, @object .size vendor_cert_size, 4 - .section .vendor_cert, "", @progbits + .section .vendor_cert, "a", @progbits vendor_cert_size: .long .L0 - vendor_cert .globl vendor_cert @@ -12,7 +12,7 @@ vendor_cert_size: .align 1 .type vendor_cert, @object .size vendor_cert, .L0-vendor_cert - .section .vendor_cert, "", @progbits + .section .vendor_cert, "a", @progbits vendor_cert: .incbin VENDOR_CERT_FILE .L0: @@ -21,7 +21,7 @@ vendor_cert: .bss .type vendor_cert, @object .size vendor_cert, 1 - .section .vendor_cert, "", @progbits + .section .vendor_cert, "a", @progbits vendor_cert: .zero 1 @@ -30,7 +30,7 @@ vendor_cert: .align 4 .type vendor_cert_size, @object .size vendor_cert_size, 4 - .section .vendor_cert, "", @progbits + .section .vendor_cert, "a", @progbits vendor_cert_size: .long 1 #endif diff --git a/dbx.S b/dbx.S index 9ccdb676..7b19c5c2 100644 --- a/dbx.S +++ b/dbx.S @@ -4,7 +4,7 @@ .align 1 .type vendor_dbx_size, @object .size vendor_dbx_size, 4 - .section .vendor_cert, "", @progbits + .section .vendor_cert, "a", @progbits vendor_dbx_size: .long .L0 - vendor_dbx .globl vendor_dbx @@ -12,7 +12,7 @@ vendor_dbx_size: .align 1 .type vendor_dbx, @object .size vendor_dbx, .L0-vendor_dbx - .section .vendor_cert, "", @progbits + .section .vendor_cert, "a", @progbits vendor_dbx: .incbin VENDOR_DBX_FILE .L0: @@ -21,7 +21,7 @@ vendor_dbx: .bss .type vendor_dbx, @object .size vendor_dbx, 1 - .section .vendor_cert, "", @progbits + .section .vendor_cert, "a", @progbits vendor_dbx: .zero 1 @@ -30,7 +30,7 @@ vendor_dbx: .align 4 .type vendor_dbx_size, @object .size vendor_dbx_size, 4 - .section .vendor_cert, "", @progbits + .section .vendor_cert, "a", @progbits vendor_dbx_size: .long 0 #endif -- cgit v1.2.3 From ff1409c37b9e27f862aed8fa4077b44904b2b802 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 10 Jun 2013 17:51:57 -0400 Subject: Make DBX be included in build if the environment is set right. Signed-off-by: Peter Jones --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index 0c263924..e69c74ad 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,9 @@ endif ifneq ($(origin VENDOR_CERT_FILE), undefined) CFLAGS += -DVENDOR_CERT_FILE=\"$(VENDOR_CERT_FILE)\" endif +ifneq ($(origin VENDOR_DBX_FILE), undefined) + CFLAGS += -DVENDOR_DBX_FILE=\"$(VENDOR_DBX_FILE)\" +endif LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH) -L$(LIB_PATH) -LCryptlib -LCryptlib/OpenSSL $(EFI_CRT_OBJS) -- cgit v1.2.3 From d141608bf820a1f1052b335073cd4c2dc9221d1d Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 10 Jun 2013 17:51:57 -0400 Subject: Bump version to 0.4 Since I've finally merged in the "sections" branch, best to increment the version number. Signed-off-by: Peter Jones --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e69c74ad..4bdd6032 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,7 @@ endif LDFLAGS = -nostdlib -znocombreloc -T $(EFI_LDS) -shared -Bsymbolic -L$(EFI_PATH) -L$(LIB_PATH) -LCryptlib -LCryptlib/OpenSSL $(EFI_CRT_OBJS) -VERSION = 0.3 +VERSION = 0.4 TARGET = shim.efi MokManager.efi.signed fallback.efi.signed OBJS = shim.o netboot.o cert.o dbx.o -- cgit v1.2.3