Re: [PATCH v11 5/9] x86/efi: Disable LASS while mapping the EFI runtime services

H. Peter Anvin
2025-11-08T16:20:09Z

On November 7, 2025 4:48:05 PM PST, Andy Lutomirski <luto@kernel.org> wrote:
>
>
>On Fri, Nov 7, 2025, at 2:09 AM, Ard Biesheuvel wrote:
>> On Fri, 7 Nov 2025 at 10:40, Peter Zijlstra <peterz@infradead.org> wrote:
>>>
>>> On Fri, Nov 07, 2025 at 10:22:30AM +0100, Ard Biesheuvel wrote:
>>>
>>> > > But that's just the thing EFI is *NOT* trusted! We're basically
>>> > > disabling all security features (not listed above are CET and CFI) to
>>> > > run this random garbage we have no control over.
>>> > >
>>> > > How about we just flat out refuse EFI runtime services? What are they
>>> > > actually needed for? Why are we bending over backwards and subverting
>>> > > our security for this stuff?
>>> >
>>> > On x86, it is mostly the EFI variable services that user space has
>>> > come to rely on, not only for setting the boot path (which typically
>>> > happens only once at installation time, when the path to GRUB is set
>>> > as the first boot option). Unfortunately, the systemd folks have taken
>>> > a liking to this feature too, and have started storing things in
>>> > there.
>>>
>>> *groan*, so booting with noefi (I just went and found that option) will
>>> cause a modern Linux system to fail booting?
>>>
>>
>> As long as you install with EFI enabled, the impact of efi=noruntime
>> should be limited, given that x86 does not rely on EFI runtime
>> services for the RTC or for reboot/poweroff. But you will lose access
>> to the EFI variable store. (Not sure what 'noefi' does in comparison,
>> but keeping EFI enabled at boot time for things like secure/measured
>> boot and storage encryption will probably result in a net positive
>> impact on security/hardening as long as you avoid calling into the
>> firmware after boot)
>>
>>
>>> > There is also PRM, which is much worse, as it permits devices in the
>>> > ACPI namespace to call firmware routines that are mapped privileged in
>>> > the OS address space in the same way. I objected to this at the time,
>>> > and asked for a facility where we could at least mark such code as
>>> > unprivileged (and run it as such) but this was ignored, as Intel and
>>> > MS had already sealed the deal and put this into production. This is
>>> > much worse than typical EFI routines, as the PRM code is ODM/OEM code
>>> > rather than something that comes from the upstream EFI implementation.
>>> > It is basically a dumping ground for code that used to run in SMM
>>> > because it was too ugly to run anywhere else. </rant>
>>>
>>> What the actual fuck!! And we support this garbage? Without
>>> pr_err(FW_BUG ) notification?
>>>
>>> How can one find such devices? I need to check my machine.
>>>
>>
>> Unless you have a PRMT table in the list of ACPI tables, your system
>> shouldn't be affected by this.
>>
>>> > It would be nice if we could
>>> >
>>> > a) Get rid of SetVirtualAddressMap(), which is another insane hack
>>> > that should never have been supported on 64-bit systems. On arm64, we
>>> > no longer call it unless there is a specific need for it (some Ampere
>>> > Altra systems with buggy firmware will crash otherwise). On x86,
>>> > though, it might be tricky because there so much buggy firmware.
>>> > Perhaps we should phase it out by checking for the UEFI version, so
>>> > that future systems will avoid it. This would mean, however, that EFI
>>> > code remains in the low user address space, which may not be what you
>>> > want (unless we do c) perhaps?)
>>> >
>>> > b) Run EFI runtime calls in a sandbox VM - there was a PoC implemented
>>> > for arm64 a couple of years ago, but it was very intrusive and the ARM
>>> > intern in question went on to do more satisyfing work.
>>> >
>>> > c) Unmap the kernel KPTI style while the runtime calls are in
>>> > progress? This should be rather straight-forward, although it might
>>> > not help a lot as the code in question still runs privileged.
>>>
>>> At the very least I think we should start printing scary messages about
>>> disabling security to run untrusted code. This is all quite insane :/
>>
>> I agree in principle. However, calling it 'untrusted' is a bit
>> misleading here, given that you already rely on the same body of code
>> to boot your computer to begin with. I.e., if you suspect that the
>> code in question is conspiring against you, not calling it at runtime
>> to manipulate EFI variables is not going to help with that.
>>
>> But from a robustness point of view, I agree - running vendor code at
>> the OS's privilege level at runtime that was only tested with Windows
>> is not great for stability, and it would be nice if we could leverage
>> the principle of least privilege and only permit it to access the
>> things that it actually needs to perform the task that we've asked it
>> to. This is why I asked for the ability to mark PRM services as
>> unprivileged, given that they typically only run some code and perhaps
>> poke some memory (either RAM or MMIO registers) that the OS never
>> accesses directly.
>>
>> Question is though whether on x86, sandboxing is feasible: can VMs
>> call into SMM? Because that is where 95% of the EFI variable services
>> logic resides - the code running directly under the OS does very
>> little other than marshalling the arguments and passing them on.
>
>Last time I looked at the calls into SMM (which was quite a while ago), they were fairly recognizable sequences that would nicely cause VM exits. So the VM would exit and we would invoke SMM on its behalf.
>
>But it’s very very very common for VMX/SVM to be unavailable.
>
>Has anyone tried running EFI at CPL3?
>
>P.S. Forget about relying on AC to make EFI work. I doubt we can trust EFI to leave AC set.
>

Yeah, AC is way too volatile.

This thread veered off topic, though. The point wasn't that EFI runtime calls weren't crap, but that LASS, SMEP, and SMAP add no value during the EFI runtime call *because we explicitly unmap user space anyway* (efi_mm) so there are no user space mappings to worry about, so disabling them during the execution of the EFI runtime call makes no difference at all — *as long as* the CR4 manipulation is done strictly inside the efi_mm switch.