From c687fd4d1ef4fed6f97fa94da7ff079495402826 Mon Sep 17 00:00:00 2001 From: Huijing Hei Date: Fri, 5 Sep 2025 19:59:47 +0800 Subject: [PATCH] efi: Do not update EFI variables if empty or readonly Fixes https://github.com/coreos/bootupd/issues/972 --- .github/workflows/ci.yml | 3 ++- src/efi.rs | 20 ++++++++++++++++++-- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b2d40de..e1cec9ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -88,7 +88,8 @@ jobs: set -xeuo pipefail sudo podman run --rm -ti --privileged -v /:/target --pid=host --security-opt label=disable \ -v /dev:/dev -v /var/lib/containers:/var/lib/containers \ - localhost/bootupd:latest bootc install to-filesystem --skip-fetch-check \ + localhost/bootupd:latest env BOOTC_BOOTLOADER_DEBUG=1 \ + bootc install to-filesystem --skip-fetch-check \ --acknowledge-destructive \ --disable-selinux --replace=alongside /target # Verify we injected static configs diff --git a/src/efi.rs b/src/efi.rs index 694b9826..c446edb5 100644 --- a/src/efi.rs +++ b/src/efi.rs @@ -18,7 +18,7 @@ use chrono::prelude::*; use fn_error_context::context; use openat_ext::OpenatDirExt; use os_release::OsRelease; -use rustix::fd::BorrowedFd; +use rustix::{fd::AsFd, fd::BorrowedFd, fs::StatVfsMountFlags}; use walkdir::WalkDir; use widestring::U16CString; @@ -47,6 +47,9 @@ pub(crate) const SHIM: &str = "shimx64.efi"; #[cfg(target_arch = "riscv64")] pub(crate) const SHIM: &str = "shimriscv64.efi"; +/// The mount path for uefi +const EFIVARFS: &str = "/sys/firmware/efi/efivars"; + /// Systemd boot loader info EFI variable names const LOADER_INFO_VAR_STR: &str = "LoaderInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"; const STUB_INFO_VAR_STR: &str = "StubInfo-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"; @@ -146,6 +149,19 @@ impl Efi { return Ok(()); } let sysroot = Dir::open_ambient_dir("/", cap_std::ambient_authority())?; + let efi = sysroot + .open_dir(EFIVARFS.strip_prefix("/").unwrap()) + .context("Opening efivars dir")?; + let st = rustix::fs::fstatvfs(efi.as_fd())?; + // Do nothing if efivars is readonly or empty + // See https://github.com/coreos/bootupd/issues/972 + if st.f_flag.contains(StatVfsMountFlags::RDONLY) + || std::fs::read_dir(EFIVARFS)?.next().is_none() + { + log::info!("Skipped EFI variables update: efivars not writable or empty"); + return Ok(()); + } + let product_name = get_product_name(&sysroot)?; log::debug!("Get product name: '{product_name}'"); assert!(product_name.len() > 0); @@ -182,7 +198,7 @@ fn string_from_utf16_bytes(slice: &[u8]) -> String { /// Read a nul-terminated UTF-16 string from an EFI variable. fn read_efi_var_utf16_string(name: &str) -> Option { - let efivars = Path::new("/sys/firmware/efi/efivars"); + let efivars = Path::new(EFIVARFS); if !efivars.exists() { log::trace!("No efivars mount at {:?}", efivars); return None;