summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MokManager.c70
-rw-r--r--shim.c51
2 files changed, 91 insertions, 30 deletions
diff --git a/MokManager.c b/MokManager.c
index f7504d0d..eb5bb919 100644
--- a/MokManager.c
+++ b/MokManager.c
@@ -664,7 +664,9 @@ static UINTN mok_enrollment_prompt (void *MokNew, UINTN MokNewSize, int auth) {
}
static INTN mok_enrollment_prompt_callback (void *MokNew, void *data2,
- void *data3) {
+ void *data3)
+{
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
return mok_enrollment_prompt(MokNew, (UINTN)data2, TRUE);
}
@@ -694,15 +696,12 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) {
EFI_STATUS efi_status;
UINTN MokSBSize = (UINTN)data2;
MokSBvar *var = MokSB;
- CHAR16 password[1];
- UINT8 correct = 0, fail_count = 0;
- UINT8 hash[SHA256_DIGEST_SIZE];
+ CHAR16 pass1, pass2, pass3;
+ UINT8 fail_count = 0;
UINT32 length;
CHAR16 line[1];
UINT8 sbval = 1;
- UINT8 pos;
-
- LibDeleteVariable(L"MokSB", &shim_lock_guid);
+ UINT8 pos1, pos2, pos3;
if (MokSBSize != sizeof(MokSBvar)) {
Print(L"Invalid MokSB variable contents\n");
@@ -711,23 +710,37 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) {
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
- while (correct < 3) {
- RandomBytes (&pos, sizeof(pos));
+ while (fail_count < 3) {
+ RandomBytes (&pos1, sizeof(pos1));
+ pos1 = (pos1 % var->PWLen);
+
+ do {
+ RandomBytes (&pos2, sizeof(pos2));
+ pos2 = (pos2 % var->PWLen);
+ } while (pos2 == pos1);
+
+ do {
+ RandomBytes (&pos3, sizeof(pos3));
+ pos3 = (pos3 % var->PWLen) ;
+ } while (pos3 == pos2 || pos3 == pos1);
+
+ Print(L"Enter password character %d: ", pos1 + 1);
+ get_line(&length, &pass1, 1, 0);
- pos = pos % var->PWLen;
+ Print(L"Enter password character %d: ", pos2 + 1);
+ get_line(&length, &pass2, 1, 0);
- Print(L"Enter password character %d: ", pos + 1);
- get_line(&length, password, 1, 0);
+ Print(L"Enter password character %d: ", pos3 + 1);
+ get_line(&length, &pass3, 1, 0);
- if (password[0] != var->Password[pos]) {
+ if (pass1 != var->Password[pos1] ||
+ pass2 != var->Password[pos2] ||
+ pass3 != var->Password[pos3]) {
Print(L"Invalid character\n");
fail_count++;
} else {
- correct++;
- }
-
- if (fail_count >= 3)
break;
+ }
}
if (fail_count >= 3) {
@@ -761,6 +774,8 @@ static INTN mok_sb_prompt (void *MokSB, void *data2, void *data3) {
&shim_lock_guid);
}
+ LibDeleteVariable(L"MokSB", &shim_lock_guid);
+
Print(L"Press a key to reboot system\n");
Pause();
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
@@ -789,10 +804,25 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) {
return -1;
}
- LibDeleteVariable(L"MokPW", &shim_lock_guid);
-
uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+ SetMem(hash, SHA256_DIGEST_SIZE, 0);
+
+ if (CompareMem(MokPW, hash, SHA256_DIGEST_SIZE) == 0) {
+ Print(L"Clear MOK password? (y/n): ");
+
+ do {
+ get_line (&length, line, 1, 1);
+
+ if (line[0] == 'Y' || line[0] == 'y') {
+ LibDeleteVariable(L"MokPWStore", &shim_lock_guid);
+ LibDeleteVariable(L"MokPW", &shim_lock_guid);
+ }
+ } while (line[0] != 'N' && line[0] != 'n');
+
+ return 0;
+ }
+
while (fail_count < 3) {
Print(L"Confirm MOK passphrase: ");
get_line(&length, password, PASSWORD_MAX, 0);
@@ -842,6 +872,8 @@ static INTN mok_pw_prompt (void *MokPW, void *data2, void *data3) {
return -1;
}
+ LibDeleteVariable(L"MokPW", &shim_lock_guid);
+
Print(L"Press a key to reboot system\n");
Pause();
uefi_call_wrapper(RT->ResetSystem, 4, EfiResetWarm,
diff --git a/shim.c b/shim.c
index 81e42314..2f7f8c2e 100644
--- a/shim.c
+++ b/shim.c
@@ -82,8 +82,7 @@ static EFI_STATUS get_variable (CHAR16 *name, EFI_GUID guid, UINT32 *attributes,
return efi_status;
}
- if (allocate)
- *buffer = AllocatePool(*size);
+ *buffer = AllocatePool(*size);
if (!*buffer) {
Print(L"Unable to allocate variable buffer\n");
@@ -545,7 +544,8 @@ static EFI_STATUS generate_hash (char *data, int datasize,
if (!hashbase) {
Print(L"Malformed section header\n");
- return EFI_INVALID_PARAMETER;
+ status = EFI_INVALID_PARAMETER;
+ goto done;
}
if (!(Sha256Update(sha256ctx, hashbase, hashsize)) ||
@@ -625,6 +625,11 @@ static EFI_STATUS verify_buffer (char *data, int datasize,
WIN_CERTIFICATE_EFI_PKCS *cert;
unsigned int size = datasize;
+ if (context->SecDir->Size == 0) {
+ Print(L"Empty security header\n");
+ return EFI_INVALID_PARAMETER;
+ }
+
cert = ImageAddress (data, size, context->SecDir->VirtualAddress);
if (!cert) {
@@ -683,9 +688,19 @@ static EFI_STATUS read_header(void *data, unsigned int datasize,
EFI_IMAGE_DOS_HEADER *DosHdr = data;
EFI_IMAGE_OPTIONAL_HEADER_UNION *PEHdr = data;
+ if (datasize < sizeof(EFI_IMAGE_DOS_HEADER)) {
+ Print(L"Invalid image\n");
+ return EFI_UNSUPPORTED;
+ }
+
if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE)
PEHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((char *)data + DosHdr->e_lfanew);
+ if ((((UINT8 *)PEHdr - (UINT8 *)data) + sizeof(EFI_IMAGE_OPTIONAL_HEADER_UNION)) > datasize) {
+ Print(L"Invalid image\n");
+ return EFI_UNSUPPORTED;
+ }
+
if (PEHdr->Te.Signature != EFI_IMAGE_NT_SIGNATURE) {
Print(L"Unsupported image type\n");
return EFI_UNSUPPORTED;
@@ -712,13 +727,18 @@ static EFI_STATUS read_header(void *data, unsigned int datasize,
context->FirstSection = (EFI_IMAGE_SECTION_HEADER *)((char *)PEHdr + PEHdr->Pe32.FileHeader.SizeOfOptionalHeader + sizeof(UINT32) + sizeof(EFI_IMAGE_FILE_HEADER));
context->SecDir = (EFI_IMAGE_DATA_DIRECTORY *) &PEHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
- if (context->SecDir->VirtualAddress >= datasize) {
- Print(L"Malformed security header\n");
- return EFI_INVALID_PARAMETER;
+ if (context->ImageSize < context->SizeOfHeaders) {
+ Print(L"Invalid image\n");
+ return EFI_UNSUPPORTED;
}
- if (context->SecDir->Size == 0) {
- Print(L"Empty security header\n");
+ if (((UINT8 *)context->SecDir - (UINT8 *)data) > (datasize - sizeof(EFI_IMAGE_DATA_DIRECTORY))) {
+ Print(L"Invalid image\n");
+ return EFI_UNSUPPORTED;
+ }
+
+ if (context->SecDir->VirtualAddress >= datasize) {
+ Print(L"Malformed security header\n");
return EFI_INVALID_PARAMETER;
}
@@ -831,7 +851,7 @@ static EFI_STATUS generate_path(EFI_LOADED_IMAGE *li, CHAR16 *ImagePath,
bootpath[i+1] = '\0';
- if (bootpath[i-i] == '\\')
+ if (i == 0 || bootpath[i-i] == '\\')
bootpath[i] = '\0';
*PathName = AllocatePool(StrSize(bootpath) + StrSize(ImagePath));
@@ -904,6 +924,7 @@ static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data,
&buffersize, fileinfo);
if (efi_status == EFI_BUFFER_TOO_SMALL) {
+ FreePool(fileinfo);
fileinfo = AllocatePool(buffersize);
if (!fileinfo) {
Print(L"Unable to allocate file info buffer\n");
@@ -946,6 +967,8 @@ static EFI_STATUS load_image (EFI_LOADED_IMAGE *li, void **data,
*datasize = buffersize;
+ FreePool(fileinfo);
+
return EFI_SUCCESS;
error:
if (*data) {
@@ -983,7 +1006,7 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
EFI_STATUS efi_status;
EFI_LOADED_IMAGE *li, li_bak;
EFI_DEVICE_PATH *path;
- CHAR16 *PathName;
+ CHAR16 *PathName = NULL;
void *data = NULL;
int datasize;
@@ -1019,10 +1042,16 @@ EFI_STATUS start_image(EFI_HANDLE image_handle, CHAR16 *ImagePath)
goto done;
}
- efi_status = uefi_call_wrapper(entry_point, 3, image_handle, systab);
+ efi_status = uefi_call_wrapper(entry_point, 2, image_handle, systab);
CopyMem(li, &li_bak, sizeof(li_bak));
done:
+ if (PathName)
+ FreePool(PathName);
+
+ if (data)
+ FreePool(data);
+
return efi_status;
}