[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v3 3/4] Add a new hypercall to get the ESRT



On Mon, May 02, 2022 at 08:24:30AM +0200, Jan Beulich wrote:
> On 29.04.2022 19:06, Demi Marie Obenour wrote:
> > On Fri, Apr 29, 2022 at 10:40:42AM +0200, Jan Beulich wrote:
> >> On 29.04.2022 00:54, Demi Marie Obenour wrote:
> >>> On Thu, Apr 28, 2022 at 08:47:49AM +0200, Jan Beulich wrote:
> >>>> On 27.04.2022 21:08, Demi Marie Obenour wrote:
> >>>>> On further thought, I think the hypercall approach is actually better
> >>>>> than reserving the ESRT.  I really do not want XEN_FW_EFI_MEM_INFO to
> >>>>> return anything other than the actual firmware-provided memory
> >>>>> information, and the current approach seems to require more and more
> >>>>> special-casing of the ESRT, not to mention potentially wasting memory
> >>>>> and splitting a potentially large memory region into two smaller ones.
> >>>>> By copying the entire ESRT into memory owned by Xen, the logic becomes
> >>>>> significantly simpler on both the Xen and dom0 sides.
> >>>>
> >>>> I actually did consider the option of making a private copy when you did
> >>>> send the initial version of this, but I'm not convinced this simplifies
> >>>> things from a kernel perspective: They'd now need to discover the table
> >>>> by some entirely different means. In Linux at least such divergence
> >>>> "just for Xen" hasn't been liked in the past.
> >>>>
> >>>> There's also the question of how to propagate the information across
> >>>> kexec. But I guess that question exists even outside of Xen, with the
> >>>> area living in memory which the OS is expected to recycle.
> >>>
> >>> Indeed it does.  A simple rule might be, “Only trust the ESRT if it is
> >>> in memory of type EfiRuntimeServicesData.”  That is easy to achieve by
> >>> monkeypatching the config table as you suggested below.
> >>>
> >>> I *am* worried that the config table might be mapped read-only on some
> >>> systems, in which case the overwrite would cause a fatal page fault.  Is
> >>> there a way for Xen to check for this?
> >>
> >> While in boot mode, aiui page tables aren't supposed to be enforcing
> >> access restrictions. Recall that on other architectures EFI even runs
> >> with paging disabled; this simply is not possible for x86-64.
> > 
> > Yikes!  No wonder firmware has nonexistent exploit mitigations.  They
> > really ought to start porting UEFI to Rust, with ASLR, NX, stack
> > canaries, a hardened allocator, and support for de-priviliged services
> > that run in user mode.
> > 
> > That reminds me: Can Xen itself run from ROM?
> 
> I guess that could be possible in principle, but would certainly require
> some work.
> 
> >  Xen is being ported to
> > POWER for use in Qubes OS, and one approach under consideration is to
> > have Xen and a mini-dom0 be part of the firmware.  Personally, I really
> > like this approach, as it makes untrusted storage domains much simpler.
> > If this should be a separate email thread, let me know.
> 
> It probably should be.

I will make one at some point.

> >> So
> >> portable firmware shouldn't map anything r/o. In principle the pointer
> >> could still be in ROM; I consider this unlikely, but we could check
> >> for that (just like we could do a page table walk to figure out
> >> whether a r/o mapping would prevent us from updating the field).
> > 
> > Is there a utility function that could be used for this?
> 
> I don't think there is.

Then it is good that none is necessary :)

Also, should the various bug checks I added be replaced by ASSERT()?

> >>>  It could also be undefined behavior to modify it.
> >>
> >> That's the bigger worry I have.
> > 
> > Turns out that it is *not* undefined behavior, so long as
> > ExitBootServices() has not been called.  This is becaues EFI drivers
> > will modify the config table, so firmware cannot assume it to be
> > read-only.
> 
> Ah, right - we could even use InstallConfigurationTable() ourselves
> to make the adjustment.

That is even simpler than I thought!  I was worried that
InstallConfigurationTable() would assume that memory for the table was
allocated a certain way and cause invalid free errors, but at least
TianoCore does not do that.

> >>>>> Is using ebmalloc() to allocate a copy of the ESRT a reasonable option?
> >>>>
> >>>> I'd suggest to try hard to avoid ebmalloc(). It ought to be possible to
> >>>> make the copy before ExitBootServices(), via normal EFI allocation. If
> >>>> replacing a pointer in the config table was okay(ish), this could even
> >>>> be utilized to overcome the kexec problem.
> >>>
> >>> What type should I use for the allocation?  EfiLoaderData looks like the
> >>> most consistent choice, but I am not sure if memory so allocated remains
> >>> valid when Xen hands off to the OS, so EfiRuntimeServicesData might be a
> >>> better choice.
> >>
> >> It definitely is. We do recycle EfiLoaderData ourselves.
> > 
> > I wonder why the ESRT was not in EfiRuntimeServicesData to begin with.
> 
> So do I.

I suspect the assumption was that the ESRT would be parsed by the OS
before ExitBootServices(), and that the OS would have no need for the
ESRT after that.

> >>>  To avoid memory leaks from repeated kexec(), this could
> >>> be made conditional on the ESRT not being in memory of type
> >>> EfiRuntimeServicesData to begin with.
> >>
> >> Of course - there's no point relocating the blob when it already is
> >> immune to recycling.
> > 
> > Yup.  Is it reasonable for dom0 to check that the ESRT is in
> > EfiRuntimeServicesData when under Xen?
> 
> I think it is, but kernel folks may not like Xen specific code in this
> (or about any) area.
> 
> Jan

There is PVops et al already :)

-- 
Sincerely,
Demi Marie Obenour (she/her/hers)
Invisible Things Lab

Attachment: signature.asc
Description: PGP signature


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.