grub-devel
[Top][All Lists]
Advanced

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

[DRAFT PATCH 0/1] Add Xen command line parsing


From: Aaron Rainbolt
Subject: [DRAFT PATCH 0/1] Add Xen command line parsing
Date: Fri, 4 Apr 2025 09:44:46 -0500

Sending this for preliminary review, this was originally developed downstream
for the Qubes OS project and I was requested to send the patch upstream. This
has been tested pretty well on Qubes OS R4.3, I haven't tested it in a more
"vanilla" environment yet as I cannot for the life of me get GRUB from git
master to compile right on Fedora 41 due to linker bugs.

The purpose of this patch is to allow the Xen hypervisor to pass extra data to
GRUB as a kernel command line, allowing the host to customize the boot process
of the guest. The command line from Xen is parsed and the data within it
exposed as environment variables. The grub.cfg script can then use those
environment variables as it sees fit.

The main reason for doing this is to allow implementing boot modes in Qubes OS
while also using in-VM kernels. For more context on Qubes boot modes, see [1].
In order for this to work with in-VM kernels, it is necessary for dom0 to pass
kernel parameters to the guest without modifying the guest's grub.cfg
manually. This patch allows this to happen, by allowing dom0 to pass kernel
parameters to GRUB, which then provides them as an environment variable. The
grub.cfg script within the VM can then append those variables to the kernel
command line.

The way this works is pretty simple:

* When booting in PVH mode, grab the command line passed by Xen and copy it
  into the `start_info` struct ointed to by `grub_xen_start_page_addr`. (In PV
  mode, this struct has the command line pre-populated by the hypervisor, in
  PVH mode it has to be manually populated.)
* Before parsing the GRUB configuration (or dropping to a rescue shell), parse
  the Xen command line:
  * Break apart the command line into words, using spaces as the separator.
    Quotes (both single and double) can be used to suppress splitting, and
    backslashes can be used to escape characters.
  * For each word:
    * If the word contains an `=`, split the word on the first `=` sign.
      Export an environment variable with the name set to the word portion on
      the left of the sign, and the value set to the word portion to the right
      of the sign.
    * Otherwise, export an environment variable with the name set to the word,
      and the value set to `1`.

I do have some concerns with how my code does this at the moment, which is
part of why this is a draft:

* `pvh_start_info->cmdline_paddr` is a physical address. I use `grub_strcpy`
  to copy its contents into `grub_xen_start_page_addr->cmd_line`, so this
  means my code assumes that paging is disabled, or the page(s) containing the
  command line source and destination are identity-mapped. I tested this in a
  PVH VM and it seems to work without issues, but seeming to work and actually
  working aren't necessarily the same thing, and I can't tell how paging works
  in GRUB in this particular area of things, so I'm unsure if this is safe.
* This patch assumes dom0 is fully trusted - it can clobber arbitrary
  environment variables in GRUB with whatever it wants. I'm unsure if Xen is
  used in any confidential computing situations, but if it is, this probably
  is unacceptable.
* Every single parameter passed from Xen to GRUB will end up an environment
  variable used when parsing the config file. THis means that if in the future
  there's ever a reason to pass parameters to GRUB on the Xen command line
  that do something other than set environment variables, there will be a
  (potentially mild) API breakage.
* All testing has only been done on Qubes OS, which patches both its Xen and
  its GRUB pretty heavily. I tried to test this on Fedora 41 with a vanilla
  Xen and GRUB, but no matter what I did I would end up getting a
  linker-related error when trying to make an i386-xen_pvh GRUB image. [2]

I'm very open to making large changes to this patch to make it acceptable for
integration into GRUB upstream. Consider this a prototype implementation that
simply proves that the concept I'm going for is possible. If there's a better
way to do the kind of thing I'm trying to do, I'd be more than happy to do it
that way instead.

Final copyright-related note, I am working on this patch as part of my
contracter work with ENCRYPTED SUPORT LLC (the main developers of Kicksecure).
I've already talked to them about it and they're fine with transferring
copyright for GNU contributions to the FSF when and if it is requested.

[1] https://github.com/QubesOS/qubes-issues/issues/9750 (includes notes about
    the testing done so far)
[2] Trying to build an unpatched, vanilla GRUB:

    $ ./configure TARGET_LDFLAGS=-static --target=i386-redhat-linux-gnu
      --with-platform=xen_pvh --disable-grub-mount --disable-werror
    $ make -j16
    $ # create grub-bootstrap.cfg and memdisk.tar
    $ ./grub-mkimage -O i386-xen_pvh -o grub-i386-xen_pvh.bin -c
      grub-bootstrap.cfg -m memdisk.tar -d grub-core grub-core/*.mod

      ./grub-mkimage: error: `grub-core/kernel.img' is miscompiled: its start
      address is 0x9000 instead of 0x100000: ld.gold bug?

    This issue occurs using the BFD and LLD linkers, gold ends up placing the
    start address at 0x9072.

Aaron Rainbolt (1):
  Add Xen command line parsing

 grub-core/Makefile.core.def   |   4 +-
 grub-core/kern/i386/xen/pvh.c |  16 +++
 grub-core/kern/main.c         |  12 ++
 grub-core/kern/xen/cmdline.c  | 223 ++++++++++++++++++++++++++++++++++
 include/grub/xen.h            |   2 +
 5 files changed, 256 insertions(+), 1 deletion(-)
 create mode 100644 grub-core/kern/xen/cmdline.c

--
2.43.0

Attachment: pgpF5oC51r97U.pgp
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]