Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
26455c7
feat(hii): keyword set of STRING questions
xaionaro Nov 11, 2026
709eb97
test(qemu): STRING keywords in shell-keyword-kinds
xaionaro Nov 11, 2026
bb4f196
fix(hii): read no variable of a HiiDB with a PASSWORD of an undeclare…
xaionaro Nov 11, 2026
02319dd
test(qemu): check a password of an undeclared VarStoreId
xaionaro Nov 11, 2026
425599d
feat(hii): show STRING questions of name/value storage from the snapshot
xaionaro Nov 11, 2026
9c5e54a
test(qemu): show STRING questions of name/value storage
xaionaro Nov 11, 2026
7e35328
feat(hii): export each package list by its own handle
xaionaro Nov 6, 2026
38fdbd5
feat(hii): snapshot, compare and restore the stores of a FormSet
xaionaro Nov 6, 2026
25420b4
feat(hii): get a question's value from its driver's Callback()
xaionaro Nov 6, 2026
ae9a0b2
feat(hii): set a question's value through its driver's Callback()
xaionaro Nov 6, 2026
ba449da
feat(hii): list the EFI variables that a driver's Callback()s changed
xaionaro Nov 6, 2026
5dfae26
feat(variables): encode and decode load options and their device paths
xaionaro Nov 6, 2026
0ade79b
feat(esp): name a disk's ESP by the Hard Drive node firmware matches
xaionaro Nov 6, 2026
a3fd392
feat(staged-set): record a set staged for the next boot
xaionaro Nov 6, 2026
e8667ba
feat(staged-set): stage a set for the next boot from Linux
xaionaro Nov 9, 2026
7b958c6
feat(staged-set): apply a staged set before the OS starts
xaionaro Nov 9, 2026
c2f45b6
feat(staged-set): stage and apply beside a setup password with the flag
xaionaro Nov 7, 2026
63cc2c6
feat(staged-set): show a staged question's request or outcome in get
xaionaro Nov 7, 2026
2f02277
test(qemu): pin the FAT modules of the x86_64 and aarch64 kernels
xaionaro Nov 7, 2026
c58ee81
test(qemu): fail the guest's setup on a module that does not load
xaionaro Nov 7, 2026
567702c
test(qemu): stage a set from Linux and apply it before the OS
xaionaro Nov 7, 2026
7bf023d
feat(esp): find the EFI system partition among Windows' volumes
xaionaro Nov 7, 2026
b94e47c
feat(staged-set): stage a set for the next boot from Windows
xaionaro Nov 7, 2026
718501d
feat(staged-set): stage through a mounted ESP on Windows with --esp
xaionaro Nov 7, 2026
079ef57
docs(readme): sets staged for the next boot from Linux and Windows
xaionaro Nov 7, 2026
3d2faa6
fix: refuse --hii-source and --efivar-memory outside the Linux build
xaionaro Nov 11, 2026
32aad68
test(qemu): HiiDB source flags refused in the Shell, followed on Linux
xaionaro Nov 11, 2026
0360e35
feat(variable): check AUTH_3 signed writes against the stored variable
xaionaro Nov 11, 2026
d9701f8
feat(variable): show AUTH_3 metadata in variable info
xaionaro Nov 11, 2026
e8c0a08
test(qemu): check AUTH_3 signed writes against seeded variables
xaionaro Nov 11, 2026
14ef96c
fix(hii): offer no question that a true FormSet DISABLE_IF disables
xaionaro Nov 11, 2026
74ad762
test(qemu): hii-form-set-disable-if and shell-form-set-disable-if
xaionaro Nov 11, 2026
af5f462
fix: refuse --hii-source and --efivar-memory where Linux ignores them
xaionaro Nov 11, 2026
7caf157
test(qemu): HiiDB source flags refused where Linux reads no HiiDB
xaionaro Nov 11, 2026
a059444
fix(hii): refer to the question of a READ or WRITE as THIS
xaionaro Nov 11, 2026
4363ace
feat(hii): evaluate QUESTION_REF2
xaionaro Nov 11, 2026
3d60ee5
fix(hii): fail on THIS of a missing question, as on QUESTION_REF1
xaionaro Nov 11, 2026
384fcb2
feat(hii): evaluate QUESTION_REF3 without a DevicePath
xaionaro Nov 11, 2026
ff9d611
feat(hii): evaluate RULE_REF
xaionaro Nov 11, 2026
321d568
fix(hii): name what EFI_IFR_VERSION needs where it is not evaluated
xaionaro Nov 11, 2026
cbd138a
fix(hii): refuse where driver code changes a password's bytes
xaionaro Nov 11, 2026
06aff4a
feat(hii): state VarStore bytes for conditions with --assume-var-store
xaionaro Nov 11, 2026
de6aa6b
feat(hii)!: remove --access-level, which --assume-var-store replaces
xaionaro Nov 11, 2026
8311334
docs: say that driver code changing password bytes refuses
xaionaro Nov 12, 2026
534d9f6
feat(variables): show and read device paths as text
xaionaro Nov 7, 2026
e84b285
feat(variables): set and clear load option attributes
xaionaro Nov 7, 2026
9acaf5b
feat(variables): create load options and set console device paths
xaionaro Nov 7, 2026
8f29b3e
feat(variables): create hot keys
xaionaro Nov 7, 2026
49d7177
fix(make): accept rustup's cargo that is not the same file as rustup
xaionaro Nov 11, 2026
77400f7
fix(qemu): build the secboot firmware's BaseTools with current compilers
xaionaro Nov 11, 2026
46bfe84
fix(hii): read characters that UEFI rules out of strings as U+FFFD
xaionaro Nov 12, 2026
fbe485d
fix(hii): show and match texts without their control codes
xaionaro Nov 12, 2026
451e19c
fix(hii): read SCSU characters that UEFI rules out as U+FFFD
xaionaro Nov 12, 2026
cf8f3bb
ci: run each system's tests as a check of its own
xaionaro Nov 12, 2026
3327abf
build(make): lint that CI runs every check
xaionaro Nov 12, 2026
4acc4cd
ci: say that the QEMU builds take about 2.5 minutes
xaionaro Nov 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 86 additions & 46 deletions .github/workflows/checks.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# The checks of the Makefile; the QEMU boots, which need KVM and apt packages, and
# the unit tests on macOS and Windows in jobs of their own.
# The checks of the Makefile in a job per kind: lint, which reads the source of every system on
# one host, and the unit tests and the QEMU tests, which run make -k <check> for each system in
# a matrix entry named after its operating system and architecture.
name: ci

on:
Expand All @@ -17,57 +18,55 @@ concurrency:
cancel-in-progress: true

jobs:
# The image of test-e2e-qemu too: one image, one migration.
lint-and-test:
# The Ubuntu release of the other Linux jobs too, ubuntu-26.04-arm on arm64: one release, one migration.
lint:
runs-on: ubuntu-26.04
timeout-minutes: 60
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

# gcc's 32-bit libraries, which test-i686 links with.
- run: |
sudo apt-get update
sudo apt-get install --yes gcc-multilib

- run: make setup

# After setup: the key covers installed toolchains.
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2

# Every check but the boots.
- run: make -k lint test test-i686
- run: make -k lint

# The unit tests of the macOS build on both of its targets; lint-and-test lints them.
test-macos:
# The unit tests of each system on a runner of that system: test runs those of the host's
# build, and test-i686 those of the 32-bit glibc build on x86_64 Linux. The Windows build's
# firmware calls run against fakes.
test:
name: test (${{ matrix.system }})
strategy:
fail-fast: false
matrix:
runner: [macos-latest, macos-15-intel]
include:
- system: linux-x86_64
runner: ubuntu-26.04
check: test
- system: linux-i686
runner: ubuntu-26.04
check: test-i686
- system: linux-aarch64
runner: ubuntu-26.04-arm
check: test
- system: macos-aarch64
runner: macos-26
check: test
- system: macos-x86_64
runner: macos-15-intel
check: test
- system: windows-x86_64
runner: windows-2025
check: test
- system: windows-aarch64
runner: windows-11-arm
check: test
runs-on: ${{ matrix.runner }}
timeout-minutes: 60
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

# GNU make 4 as gmake: Apple's make 3.81 ignores the Makefile's .SHELLFLAGS (3.82).
- run: brew install make

- run: gmake setup

# After setup: the key covers installed toolchains.
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2

- run: gmake -k test

# The unit tests of the Windows build on x86_64, whose firmware calls run against
# fakes; lint-and-test lints both of its targets.
test-windows:
runs-on: windows-2025
timeout-minutes: 60
# Git for Windows' bash, which the Makefile's recipes and scripts need.
# Git for Windows' bash on Windows, which the Makefile's recipes and scripts need.
defaults:
run:
shell: bash
Expand All @@ -76,19 +75,56 @@ jobs:
with:
persist-credentials: false

# gcc's 32-bit libraries, which test-i686 links with.
- if: matrix.check == 'test-i686'
run: |
sudo apt-get update
sudo apt-get install --yes gcc-multilib

# GNU make 4, ahead of Apple's make 3.81 on PATH, which ignores the Makefile's
# .SHELLFLAGS (3.82).
- if: runner.os == 'macOS'
run: |
brew install make
echo "$(brew --prefix make)/libexec/gnubin" >>"$GITHUB_PATH"

# GNU make, which the image lacks.
- run: choco install make --yes --no-progress
- if: runner.os == 'Windows'
run: choco install make --yes --no-progress

- run: make setup

# After setup: the key covers installed toolchains.
# After setup: the key covers installed toolchains. The system tells apart the entries
# of one runner image.
- uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2
with:
key: ${{ matrix.system }}

- run: make -k test
- run: make -k "$CHECK"
env:
CHECK: ${{ matrix.check }}

# Each system that the QEMU tests boot, Linux or the UEFI Shell, on each architecture.
# QEMU 9.0 and newer fault unaligned loads from Device memory as arm64 does, which the
# aarch64 guests check; Ubuntu 24.04 has QEMU 8.2.
test-e2e-qemu:
name: test-e2e-qemu (${{ matrix.system }})
strategy:
fail-fast: false
matrix:
include:
- system: linux-x86_64
check: test-e2e-qemu-x86_64
- system: linux-i686
check: test-e2e-qemu-i686
- system: linux-aarch64
check: test-e2e-qemu-aarch64
- system: uefi-shell-x86_64
check: test-e2e-qemu-shell-x86_64
- system: uefi-shell-i686
check: test-e2e-qemu-shell-i686
- system: uefi-shell-aarch64
check: test-e2e-qemu-shell-aarch64
runs-on: ubuntu-26.04
timeout-minutes: 120
steps:
Expand All @@ -109,27 +145,31 @@ jobs:
sudo udevadm trigger --name-match=kvm

# No rust-cache: its cleanup takes run.sh's initramfs/tests for a cargo
# profile and logs errors; the builds take about a minute without it.
# profile and logs errors; the builds take about 2.5 minutes without it.
- run: make setup

# The guests' packages, each architecture's DriverSample.efi and Secure Boot firmware,
# keyed also on the apt packages, the pinned iasl and the runner image (this file) that
# build them. Saved only on success, as run.sh reuses DriverSample.efi and the firmware
# unchecked.
# The system's guest packages, DriverSample.efi and Secure Boot firmware, keyed also on
# the apt packages, the pinned iasl and the runner image (this file) that build them. Per
# system, not per architecture: the Linux scenarios also boot the guests of
# guest-packages-<arch>-unfixed*, which a key that the UEFI Shell entry saved first would
# lack until the key changes. Saved only on success, as run.sh reuses DriverSample.efi and
# the firmware unchecked.
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
target/qemu-test/packages
target/qemu-test/*/driver-sample
target/qemu-test/*/secboot-firmware
key: qemu-inputs-${{ hashFiles('tests/qemu/guest-packages-*', 'tests/qemu/build-driver-sample.sh', 'tests/qemu/build-secboot-firmware.sh', 'tests/qemu/host-packages', 'tests/qemu/ubuntu-packages', '.github/workflows/checks.yml') }}
key: qemu-inputs-${{ matrix.system }}-${{ hashFiles('tests/qemu/guest-packages-*', 'tests/qemu/build-driver-sample.sh', 'tests/qemu/build-secboot-firmware.sh', 'tests/qemu/host-packages', 'tests/qemu/ubuntu-packages', '.github/workflows/checks.yml') }}

- run: make -k test-e2e-qemu
- run: make -k "$CHECK"
env:
CHECK: ${{ matrix.check }}

- if: failure()
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
with:
name: qemu-test-logs
name: qemu-test-logs-${{ matrix.system }}
path: |
target/qemu-test/*/*/*/*.log
target/qemu-test/*/*/executables
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ der = { version = "0.7", features = ["alloc", "pem", "std"] }
rand_core = { version = "0.6", default-features = false }
# The RNG of RSA blinding on every target, seeded once from the platform's source.
rand_chacha = { version = "0.3", default-features = false }
# BootOptionCrc, the CRC-32 of the Boot#### variable that a Key#### hot key starts, and the
# CRC32s of the GPT on which the Linux and Windows builds find the ESP.
crc32fast = "1.5.2"

# The Linux and Windows builds stage a set for the next boot under a random nonce.
[target.'cfg(any(target_os = "linux", target_os = "windows"))'.dependencies]
rand = { version = "0.8", features = ["small_rng"] }

# Only the Linux build uses these: efivarfs, the HiiDB in sysfs, iLO through
# ilorest_chif.so, and the CLI's logging.
Expand All @@ -52,7 +59,6 @@ libc = "0.2"
nix = { version = "0.27", features = ["fs", "ioctl", "mount"] }
libloading = "0.8"
httparse = "1.8"
rand = { version = "0.8", features = ["small_rng"] }
proc-mounts = "0.3"
env_logger = "0.10"

Expand Down
22 changes: 16 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

# The checks of uefisettings. They need GNU make and bash, rustup while
# RUST_TOOLCHAIN is set, as it is by default, for test-i686 an x86 host with
# gcc's 32-bit libraries, which README.md names, and for test-e2e-qemu an
# The checks of uefisettings. They need GNU make 3.82 or newer and bash, rustup
# while RUST_TOOLCHAIN is set, as it is by default, for test-i686 an x86 host
# with gcc's 32-bit libraries, which README.md names, and for test-e2e-qemu an
# x86_64 host with /dev/kvm and what tests/qemu/README.md lists:
# make every check of CHECKS, stopping at the first that fails
# make -k every check of CHECKS, even after one fails
Expand All @@ -39,6 +39,10 @@

SHELL := bash
.SHELLFLAGS := -euo pipefail -c
# GNU make 3.81, macOS's make, ignores .SHELLFLAGS, which came with .ONESHELL in 3.82.
ifeq ($(filter oneshell,$(.FEATURES)),)
$(error GNU make 3.82 or newer runs the checks, e.g. Homebrew's gmake on macOS)
endif

# The Rust release that the checks run on: newer releases bring lints that the
# code does not satisfy yet. make setup installs it; while RUST_TOOLCHAIN is set,
Expand All @@ -65,15 +69,16 @@ unexport CARGO_ENCODED_RUSTFLAGS
TARGETS := x86_64-unknown-linux-gnu,aarch64-unknown-linux-gnu,i686-unknown-linux-gnu,x86_64-unknown-linux-musl,x86_64-unknown-uefi,i686-unknown-linux-musl,i686-unknown-uefi,aarch64-unknown-linux-musl,aarch64-unknown-uefi,x86_64-apple-darwin,aarch64-apple-darwin,x86_64-pc-windows-msvc,aarch64-pc-windows-msvc
comma := ,

# CI runs lint test test-i686 and test-e2e-qemu, and test on macOS and Windows: a
# new check joins LINTS or QEMU_TESTS or CI runs it too.
LINTS := fmt clippy-x86_64 clippy-aarch64 clippy-i686 clippy-uefi clippy-macos clippy-windows doc
# CI runs LINTS as one check, lint: a new check joins LINTS, or ci-jobs fails until the workflow names it.
LINTS := fmt clippy-x86_64 clippy-aarch64 clippy-i686 clippy-uefi clippy-macos clippy-windows doc ci-jobs
QEMU_LINUX_TESTS := test-e2e-qemu-x86_64 test-e2e-qemu-i686 test-e2e-qemu-aarch64
QEMU_SHELL_TESTS := test-e2e-qemu-shell-x86_64 test-e2e-qemu-shell-i686 test-e2e-qemu-shell-aarch64
QEMU_TESTS := $(QEMU_LINUX_TESTS) $(QEMU_SHELL_TESTS)
# The scenarios of tests/qemu/scenarios.tsv: those named shell-* boot the UEFI Shell.
SCENARIOS := $(shell awk -F '\t' '$$1 ~ /^[a-z]/ { print $$1 }' tests/qemu/scenarios.tsv)
CHECKS := $(LINTS) test test-i686 test-e2e-qemu
# The checks that CI runs as make -k <check>, each in a job or job entry of its own.
CI_CHECKS := lint $(filter-out $(LINTS) test-e2e-qemu,$(CHECKS)) $(QEMU_TESTS)

.PHONY: check lint help setup toolchain $(CHECKS) $(QEMU_TESTS)

Expand Down Expand Up @@ -135,6 +140,11 @@ clippy-windows: toolchain
cargo clippy --locked -p uefisettings --lib --bins --all-targets --target x86_64-pc-windows-msvc \
--target aarch64-pc-windows-msvc -- -D warnings

# The workflow names every check of CI_CHECKS and no other, as scripts/check-ci-jobs.sh reads
# it; which systems run a check is the workflow's alone. Needs no toolchain.
ci-jobs:
scripts/check-ci-jobs.sh .github/workflows/checks.yml $(CI_CHECKS)

test: toolchain
scripts/assert-tests-ran.sh cargo test --locked

Expand Down
Loading
Loading