summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2023-10-21 23:16:30 -0500
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2023-10-21 23:16:30 -0500
commit21ebeeb18569086934c03721d3522b81ebdf859d (patch)
treef09f05459e3483d0b1f41165621aeb7cef458aa3
parentab212730bd17d6156edec350f3ff61aa0c7f9561 (diff)
downloadhorizon-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.cc30
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 */
}