Check if the gettime runtime service is valid.
The U-Boot efi runtime service expects us to set the address map before calling any runtime services. It will then remap a few functions to their runtime version. One of these is the gettime function. If we call into this without having set a runtime map we get a page fault. Add a check to see if this is valid in efi_init() so we don't try to use the possibly invalid pointer. Reviewed by: imp, kevans (both previous version) X-MFC-With: r330868 Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D14759
This commit is contained in:
parent
400326b667
commit
ed4c884f2e
@ -99,6 +99,25 @@ efi_status_to_errno(efi_status status)
|
||||
|
||||
static struct mtx efi_lock;
|
||||
|
||||
static bool
|
||||
efi_is_in_map(struct efi_md *map, int ndesc, int descsz, vm_offset_t addr)
|
||||
{
|
||||
struct efi_md *p;
|
||||
int i;
|
||||
|
||||
for (i = 0, p = map; i < ndesc; i++, p = efi_next_descriptor(p,
|
||||
descsz)) {
|
||||
if ((p->md_attr & EFI_MD_ATTR_RT) == 0)
|
||||
continue;
|
||||
|
||||
if (addr >= (uintptr_t)p->md_virt &&
|
||||
addr < (uintptr_t)p->md_virt + p->md_pages * PAGE_SIZE)
|
||||
return (true);
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
static int
|
||||
efi_init(void)
|
||||
{
|
||||
@ -164,6 +183,24 @@ efi_init(void)
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some UEFI implementations have multiple implementations of the
|
||||
* RS->GetTime function. They switch from one we can only use early
|
||||
* in the boot process to one valid as a RunTime service only when we
|
||||
* call RS->SetVirtualAddressMap. As this is not always the case, e.g.
|
||||
* with an old loader.efi, check if the RS->GetTime function is within
|
||||
* the EFI map, and fail to attach if not.
|
||||
*/
|
||||
if (!efi_is_in_map(map, efihdr->memory_size / efihdr->descriptor_size,
|
||||
efihdr->descriptor_size, (vm_offset_t)efi_runtime->rt_gettime)) {
|
||||
if (bootverbose)
|
||||
printf(
|
||||
"EFI runtime services table has an invalid pointer\n");
|
||||
efi_runtime = NULL;
|
||||
efi_destroy_1t1_map();
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user