|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH] Validate EFI memory descriptors
On Wed, Dec 07, 2022 at 11:04:05AM +0100, Jan Beulich wrote:
> On 07.12.2022 00:57, Demi Marie Obenour wrote:
> > It turns out that these can be invalid in various ways. Based on code
> > Ard Biesheuvel contributed for Linux.
> >
> > Co-developed-by: Ard Biesheuvel <ardb@xxxxxxxxxx>
> > Signed-off-by: Demi Marie Obenour <demi@xxxxxxxxxxxxxxxxxxxxxx>
> > Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx>
>
> This comes with the risk of breaking something that was previously working,
> despite a descriptor being bogus. This _may_ be deemed acceptable, but it
> needs calling out and reasoning about in the description. Even more so that
> elsewhere we're aiming at relaxing things (by default or via command line
> overrides) to remain compatible with all kinds of flawed implementations.
I decided to match Ard’s kernel patch, except for ignoring (as opposed
to using) descriptors that cover the entire 64-bit address space (and
thus have a length in bytes that overflows uint64_t).
What do you propose Xen do instead? A broken memory map is a rather
serious problem; it means that the actual physical address space is
unknown. For Linux I am considering tainting the kernel (with
TAINT_FIRMWARE_WORKAROUND) if it detects an invalid memory descriptor.
> > --- a/xen/common/efi/efi.h
> > +++ b/xen/common/efi/efi.h
> > @@ -51,3 +51,17 @@ void free_ebmalloc_unused_mem(void);
> >
> > const void *pe_find_section(const void *image_base, const size_t
> > image_size,
> > const CHAR16 *section_name, UINTN *size_out);
> > +
> > +static inline UINT64
> > +efi_memory_descriptor_len(const EFI_MEMORY_DESCRIPTOR *desc)
> > +{
> > + uint64_t remaining_space = UINT64_MAX - desc->PhysicalStart;
>
> This wants to derive from PADDR_BITS (or even paddr_bits) rather than
> using UINT64_MAX.
paddr_bits is not available yet, but I can use PADDR_BITS. That does
require an explicit overflow check, but that is fine.
> > --- a/xen/common/efi/runtime.c
> > +++ b/xen/common/efi/runtime.c
> > @@ -270,18 +270,17 @@ int efi_get_info(uint32_t idx, union xenpf_efi_info
> > *info)
> > for ( i = 0; i < efi_memmap_size; i += efi_mdesc_size )
> > {
> > EFI_MEMORY_DESCRIPTOR *desc = efi_memmap + i;
> > - u64 len = desc->NumberOfPages << EFI_PAGE_SHIFT;
> > + uint64_t size, len = efi_memory_descriptor_len(desc);
> >
> > if ( info->mem.addr >= desc->PhysicalStart &&
> > - info->mem.addr < desc->PhysicalStart + len )
> > + info->mem.addr - desc->PhysicalStart < len )
>
> With what efi_memory_descriptor_len() does I don't see why this expression
> would need transformation - there's no overflow possible anymore.
You are correct, but the new version is more idiomatic, IMO.
> > {
> > info->mem.type = desc->Type;
> > info->mem.attr = desc->Attribute;
> > - if ( info->mem.addr + info->mem.size < info->mem.addr ||
>
> This overflow check is not superseded by the use of
> efi_memory_descriptor_len(), so if you think it is not (or no longer)
> needed, you will need to justify that in the description.
The justification is that info->mem.size is no longer used except in
comparison and assignment, so the overflow check is now redundant.
> > - info->mem.addr + info->mem.size >
> > - desc->PhysicalStart + len )
> > - info->mem.size = desc->PhysicalStart + len -
> > - info->mem.addr;
> > + size = desc->PhysicalStart + len - info->mem.addr;
> > + if ( info->mem.size > size )
> > + info->mem.size = size;
> > +
> > return 0;
> > }
>
> Is there any functional change in here that I'm overlooking, or are you
> merely converting this code to meet your personal taste? In the latter
> case I'd prefer if you left the code untouched, with the 2nd best option
> being to split it to a separate (style only) patch, and the 3rd option
> being to at least mention this as a no-op (style only) transformation in
> the description.
There should be no functional change here, but IMO the new version is
much easier to read: first compute the actual size, and if the provided
size is larger, clamp it.
--
Sincerely,
Demi Marie Obenour (she/her/hers)
Invisible Things Lab
Attachment:
signature.asc
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |