commit | 1504959fd717557a13e20ac7da360e166d6e6a13 | [log] [tgz] |
---|---|---|
author | Nicholas Bishop <nicholasbishop@google.com> | Tue Sep 13 14:45:58 2022 |
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | Tue Sep 20 16:15:41 2022 |
tree | f2cb8eb5c4217bb737ead2f029823482bf301d05 | |
parent | ed1f1124093eae9f14500f95e60dd706493312bc [diff] |
libcrdy: Use explicit page allocation for big buffers Add `ScopedPageAllocation`, which uses the UEFI page allocator to allocate memory, and use it to allocate the workbuf and kernel buffer that are passed to vboot. Background: The vboot fwlib entrypoint requires two big buffers: one for the workbuf from which it makes smaller allocations, and one for the kernel data. Prior to this commit we used a `Vec` for both. The Rust allocator we are using to allocate the memory for `Vec` is provided by uefi-rs, which allocates this memory using the UEFI pool allocator, and requests a memory type of LOADER_DATA. Using LOADER_DATA is fine for the workbuf, but we should use LOADER_CODE for the kernel data since it's executable. It's not possible to specify that through the Rust allocator interface, so we need to directly call UEFI allocation methods. Technically we could use either the pool allocator or the page allocator, but since the size of the buffers we want to allocate are page-aligned anyway, we might as well use the page allocator. This commit implements `ScopedPageAllocation` which uses the UEFI page allocator internally rather than the pool allocator, and allows the caller to specify details of how the memory is allocated. BUG=b:246550243 TEST=cargo xtask check && cargo xtask update-disk TEST=cargo xtask qemu TEST=cargo xtask qemu --ia32 Change-Id: Iafd2e4b19dca0dd88256fe0ed2a82c0472a6b0b7 Reviewed-on: https://chromium-review.googlesource.com/c/crdyboot/+/3899155 Auto-Submit: Nicholas Bishop <nicholasbishop@google.com> Reviewed-by: Jeffery Miller <jefferymiller@google.com> Tested-by: Nicholas Bishop <nicholasbishop@google.com> Commit-Queue: Jeffery Miller <jefferymiller@google.com>
Pronounced CUR-dee-boot.
Crdyboot is a UEFI bootloader for ChromeOS Flex. It is not yet in use.
Crdyboot acts as a bridge between UEFI firmware and the Chromebook style of booting. It uses vboot to select and validate an appropriate kernel partition, then launches that kernel using the Linux EFI stub.
The project is organized as a Rust workspace containing several packages:
vboot
package is a thin wrapper around the C vboot library. It also exposes a DiskIo
trait through which it can read and write blocks to a disk. This package is no_std
, and can be built for both the UEFI targets and the host target. Building for the host allows tests to be run on the host.libcrdy
package is where most of the bootloader is implemented. It implements the DiskIo
trait using the uefi crate, and uses the vboot
package to load and verify a kernel. It then boots into that kernel using the EFI stub. This package is also no_std
and can also be built for both UEFI targets and the host target for testing purposes.crdyboot
package provides the actual bootloader executable. It contains the embedded key used to verify the kernel data, the SBAT data used for revocation, and sets up logging and allocation. Then it uses libcrdy
to load, verify, and run the kernel.xtask
package contains a host executable that provides the various xtask
commands shown below. It's like a fancy Makefile for running various dev and test operations.enroller
subdirectory contains a small UEFI application that enrolls a test key in the PK
, KEK
, and db
variables. This is used to set up the test VM, and can also be used on real hardware (see the “Testing on real hardware” section).Install Rust: https://rustup.rs
Install tools used for image signing and running in a VM:
sudo apt install efitools gdisk ovmf ovmf-ia32 qemu-system-x86 sbsigntool
After installing qemu, add your user to the kvm
group. You will need to log out and back in for this to take effect:
sudo adduser ${USER} kvm
Before running any other commands in the repository, run this setup command:
cargo xtask setup <reven-verity-image-path>
This will copy the reven image to a local directory and run various setup commands. The image must have rootfs verification enabled (i.e. build_image
must be run without -r
or --no-enable-rootfs-verification
). Any kind of image (base
, dev
, or test
) is allowed.
To check formatting, lint, test, and build crdyboot:
cargo xtask check
To just build crdyboot:
cargo xtask build
To copy the latest crdyboot build to the image:
cargo xtask update-disk
Then run it in QEMU:
cargo xtask qemu [--ia32] [--secure-boot]
Some additional build options can be set in crdyboot.toml
(in the root of the repo). This file will be created automatically if it doesn't already exist by copying xtask/default.toml
. The defaults are appropriate for development. In a release build, verbose logging and the test key should be turned off.
To test secure boot with real hardware you will need to enroll custom keys. Write workspace/enroller.bin
to a USB, and write workspace/disk.bin
to a second USB, e.g. using writedisk.
Boot the DUT and enter the boot setup. Find the secure boot settings and change it to setup mode. (The details will vary from one vendor to another.)
Plug in the enroller USB and reboot. Use the boot menu to select the USB and wait for it to complete.
Unplug the enroller USB and plug in the cloudready USB, then reboot. Use the boot menu to select the USB.
An older pure-Rust version can be found in the pure-rust-20210729
branch. Since then we have switched to building the C vboot library and loading/verifying the kernel through that library.