From 21ebeeb18569086934c03721d3522b81ebdf859d Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Sat, 21 Oct 2023 23:16:30 -0500 Subject: hscript: bootloader: Take 100% control of efivarfs We're the executor, we can just commandeer the entire thing, host system included. There is very low likelihood of damage to a host system because we are use umount instead of making the host r/w. The only thing that could break is `systemctl reboot --firmware`, or a host-side upgrade of GRUB that somehow changes the path of the EFI stub. Both of these are almost impossible to encounter on a host that is actually running the executor. However, encountering a broken read-only efivarfs seems to be VERY common in the Installation Environment. Fixes: ab212730bd ("hscript: bootloader: Set rdwr on 'real' efivarfs") --- hscript/meta.cc | 30 ++++++------------------------ 1 file changed, 6 insertions(+), 24 deletions(-) diff --git a/hscript/meta.cc b/hscript/meta.cc index c4a4070..e8bddd8 100644 --- a/hscript/meta.cc +++ b/hscript/meta.cc @@ -18,8 +18,6 @@ #ifdef HAS_INSTALL_ENV # include # include -# include /* SYS_mount_setattr */ -# include /* MOUNT_ATTR_RDONLY, struct mount_attr */ # include "util/filesystem.hh" #endif /* HAS_INSTALL_ENV */ #include /* access - used by tz code even in RT env */ @@ -861,31 +859,17 @@ bool Bootloader::execute() const { const auto efipath{script->targetDirectory() + "/sys/firmware/efi/efivars"}; bool efivarfs = false; - bool umount = false; if(fs::exists(efipath)) { + /* if it isn't already mounted, that's fine */ + umount(efipath.c_str()); + /* we have to umount all efivarfs ro mounts to make any rw */ + umount("/sys/firmware/efi/efivars"); if(mount("efivarfs", efipath.c_str(), "efivarfs", MS_NOEXEC | MS_NODEV | MS_NOSUID | MS_RELATIME, nullptr) != 0) { - if(errno == EBUSY) { - struct mount_attr attr = {}; - attr.attr_clr = MS_RDONLY; - /* set rdwr on parent mount first - * if this fails we can still try the target mount */ - syscall(SYS_mount_setattr, -1, "/sys/firmware/efi/efivars", - 0, &attr, sizeof(attr)); - if(syscall(SYS_mount_setattr, -1, efipath.c_str(), 0, - &attr, sizeof(attr)) != 0) { - output_error(pos, "bootloader: failed to make NVRAM read/write", - ::strerror(errno)); - } else { - efivarfs = true; - } - } else { - output_error(pos, "bootloader: failed to mount efivarfs", - ::strerror(errno)); - } + output_error(pos, "bootloader: failed to mount efivarfs", + ::strerror(errno)); } else { efivarfs = true; - umount = true; /* We mounted it ourselves. */ } } @@ -906,8 +890,6 @@ bool Bootloader::execute() const { return false; } - /* done, back to r/o */ - if(umount) ::umount(efipath.c_str()); goto updateboot; #endif /* HAS_INSTALL_ENV */ } -- cgit v1.2.3-60-g2f50