diff options
author | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2023-10-21 23:16:30 -0500 |
---|---|---|
committer | A. Wilcox <AWilcox@Wilcox-Tech.com> | 2023-10-21 23:16:30 -0500 |
commit | 21ebeeb18569086934c03721d3522b81ebdf859d (patch) | |
tree | f09f05459e3483d0b1f41165621aeb7cef458aa3 | |
parent | ab212730bd17d6156edec350f3ff61aa0c7f9561 (diff) | |
download | horizon-21ebeeb18569086934c03721d3522b81ebdf859d.tar.gz horizon-21ebeeb18569086934c03721d3522b81ebdf859d.tar.bz2 horizon-21ebeeb18569086934c03721d3522b81ebdf859d.tar.xz horizon-21ebeeb18569086934c03721d3522b81ebdf859d.zip |
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")
-rw-r--r-- | hscript/meta.cc | 30 |
1 files 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 <cstring> # include <sys/mount.h> -# include <sys/syscall.h> /* SYS_mount_setattr */ -# include <linux/mount.h> /* MOUNT_ATTR_RDONLY, struct mount_attr */ # include "util/filesystem.hh" #endif /* HAS_INSTALL_ENV */ #include <unistd.h> /* 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 */ } |