puzzleos / stubby

UEFI bootloader stub

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

efi filename is passed to kernel when kernel.efi invoked from uefi shell without shim

smoser opened this issue · comments

When stubby uses a builtin command line, the command line presented to the kernel would contain only the arguments present in the file (working as expected). However, when a stubby kernel.efi with no builtin cmdline is executed from the EFI SHELL the command line given to the kernel will have the name of the kernel efi in it.

The problem here is that the string 'kernel.efi' (or whatever the name) is then subjected to the kernel parameters requirements. The string 'kernel.efi' did not look like an allowed argument, so it would be denied.

Here is an example of the failing case (insecure boot, secureboot would fail rather than emitting 'would be rejected' message). EFI shell here comes from ovmf from Ubuntu 20.04 - 0~20191122.bd85bf54-2ubuntu3.3:

BdsDxe: failed to load Boot0001 "UEFI QEMU DVD-ROM QM00005 " from PciRoot(0x0)/Pci(...): Not Found
...
BdsDxe: starting Boot0003 "EFI Internal Shell" from Fv(...)/FvFile(7C04A583-9E
3E-4F1C-AD65-E05268D0B4D1)
UEFI Interactive Shell v2.2
EDK II
UEFI v2.70 (EDK II, 0x00010000)
Mapping table
      FS0: Alias(s):F1:;BLK1:
          PciRoot(0x0)/Pci(0x2,0x0)
     BLK0: Alias(s):
          PciRoot(0x0)/Pci(0x1F,0x2)/Sata(0x2,0xFFFF,0x0)

Press ESC in 5 seconds to skip startup.nsh or any other key to continue.
...
Press ESC in 1 seconds to skip startup.nsh or any other key to continue.
Shell> setvar SecureBoot
8BE4DF61-93CA-11D2-AA0D-00E098032B8C - SecureBoot - 0001 Bytes
00 
Shell> fs0:
FS0:\> cd fs0:\efi\boot
FS0:\efi\boot\> kernel.efi root=atomix console=ttyS0
token not allowed: kernel.efi
Custom kernel would be rejected in secure mode

shim's load-options.c parse_load_options has lots of comments on this, and how to parse loadoptions.

The table below tries to summarize the scope of the problem as I understand it, where 'kernel.efi' is the name of the stubby kernel efi.

builtin cmdline shim loader good? result
non-empty empty * * ✔️ same as builtin
non-empty console=ttyS0 * * ✔️ rejected: args not allowed with builtin
empty console=ttyS0 * nvram ✔️ console=ttyS0
empty console=ttyS0 Y uefi-shell ✔️ console=ttyS0
empty console=ttyS0 N uefi-shell kernel.efi console=ttyS0 - rejected as kernel.efi is not white-listed
  • loader is either:
    • nvram: as loaded via boot-options (set by efibootmgr or bcfg)
    • uefi-shell: from a uefi shell either with a 'startup.nsh', another nsh script, or user typing
  • 'shim' : indicates if the shim is used to load stubby (shim.efi stubby.efi console=ttyS0) or not (stubby.efi console=ttyS0)

#18 does have a fix for this issue, but it included copying code from shim's load-options.c. shim is licensed under BSD-2-Clause-Patent and stubby is LGPL-2.1-or-later (much of stubby was copied from systemd).

2 things to point out

  • problem only occurs when shim is not used.
  • parser "does the right thing" in that it rejects loading as 'kernel.efi' is not allowed as a kernel argument. We would not want to take a fix that passed the efi filename on without checking it (that could result in an attack where the user renames 'kernel.efi' to init=bin/sh.efi or something.