From 1aca349c90df18f45397754cc729bcc4ada7fc87 Mon Sep 17 00:00:00 2001 From: Hugo Osvaldo Barrera Date: Mon, 28 Jun 2021 08:02:33 +0200 Subject: [PATCH] Attempt to trigger automounts to find the ESP The ESP may be an automount partition, so try touching a file in each candidate location so as to trigger an automounts. This is the same way systemd attempts to find it: https://github.com/systemd/systemd/blob/f565b86/src/shared/bootspec.c#L1014-L1018 I've also changed the function to return an error if no ESP is found. The previous behaviour (an empty string) just results in a crash later on. When no ESP is found, the `bundle` command will have no default for the `esp` flag. Passing an empty string to it as a default results in no value being show in the output of `--help`. This seemed like the most reasonable compromise instead of panicking. Fixes #78 --- bundles.go | 11 ++++++++--- cmd/sbctl/bundle.go | 11 +++++++++-- cmd/sbctl/list-bundles.go | 5 ++++- cmd/sbctl/verify.go | 5 ++++- sbctl.go | 21 +++++++++++++++++---- 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/bundles.go b/bundles.go index a05be1b..d00b5d9 100644 --- a/bundles.go +++ b/bundles.go @@ -74,15 +74,18 @@ func GetEfistub() string { return "" } -func NewBundle() *Bundle { - esp := GetESP() +func NewBundle() (bundle *Bundle, err error) { + esp, err := GetESP() + if err != nil { + return + } stub := GetEfistub() if stub == "" { panic("No EFISTUB file found. Please install systemd-boot or gummiboot!") } - return &Bundle{ + bundle = &Bundle{ Output: "", IntelMicrocode: "", AMDMicrocode: "", @@ -94,6 +97,8 @@ func NewBundle() *Bundle { EFIStub: stub, ESP: esp, } + + return } func GenerateBundle(bundle *Bundle) (bool, error) { diff --git a/cmd/sbctl/bundle.go b/cmd/sbctl/bundle.go index b509fc8..fc4fc72 100644 --- a/cmd/sbctl/bundle.go +++ b/cmd/sbctl/bundle.go @@ -40,7 +40,10 @@ var bundleCmd = &cobra.Command{ os.Exit(1) } } - bundle := sbctl.NewBundle() + bundle, err := sbctl.NewBundle() + if err != nil { + return err + } output, err := filepath.Abs(args[0]) if err != nil { return err @@ -81,7 +84,11 @@ var bundleCmd = &cobra.Command{ } func bundleCmdFlags(cmd *cobra.Command) { - esp := sbctl.GetESP() + esp, err := sbctl.GetESP() + if err != nil { + logging.Warn("Failed to find ESP: %s", err) + } + f := cmd.Flags() f.StringVarP(&amducode, "amducode", "a", "", "AMD microcode location") f.StringVarP(&intelucode, "intelucode", "i", "", "Intel microcode location") diff --git a/cmd/sbctl/list-bundles.go b/cmd/sbctl/list-bundles.go index fc80e11..6e83768 100644 --- a/cmd/sbctl/list-bundles.go +++ b/cmd/sbctl/list-bundles.go @@ -35,7 +35,10 @@ var listBundlesCmd = &cobra.Command{ isSigned = false logging.NotOk("Not Signed") } - esp := sbctl.GetESP() + esp, err := sbctl.GetESP() + if err != nil { + return err + } logging.Print("\tESP Location:\t%s\n", esp) logging.Print("\tOutput:\t\t└─%s\n", strings.TrimPrefix(s.Output, esp)) logging.Print("\tEFI Stub Image:\t └─%s\n", s.EFIStub) diff --git a/cmd/sbctl/verify.go b/cmd/sbctl/verify.go index 8cbf1a9..9fbc6de 100644 --- a/cmd/sbctl/verify.go +++ b/cmd/sbctl/verify.go @@ -18,7 +18,10 @@ var verifyCmd = &cobra.Command{ if err := sbctl.CanVerifyFiles(); err != nil { return err } - espPath := sbctl.GetESP() + espPath, err := sbctl.GetESP() + if err != nil { + return err + } logging.Print("Verifying file database and EFI images in %s...\n", espPath) if err := sbctl.SigningEntryIter(func(file *sbctl.SigningEntry) error { sbctl.AddChecked(file.OutputFile) diff --git a/sbctl.go b/sbctl.go index 79a5162..0f2790c 100644 --- a/sbctl.go +++ b/sbctl.go @@ -24,16 +24,29 @@ type LsblkRoot struct { Blockdevices []LsblkEntry `json:"blockdevices"` } +var espLocations = []string{ + "/boot", + "/boot/efi", + "/efi", +} +var ErrNoESP = errors.New("failed to find EFI system partition") + // Slightly more advanced check -func GetESP() string { +func GetESP() (string, error) { for _, env := range []string{"SYSTEMD_ESP_PATH", "ESP_PATH"} { envEspPath, found := os.LookupEnv(env) if found { - return envEspPath + return envEspPath, nil } } + for _, location := range espLocations { + // "Touch" a file inside all candiadate locations to trigger an + // automount if there's an automount partition. + os.Stat(fmt.Sprintf("%s/does-not-exist", location)) + } + out, err := exec.Command( "lsblk", "--json", @@ -80,10 +93,10 @@ func GetESP() string { continue } - return entryToCheck.Mountpoint + return entryToCheck.Mountpoint, nil } - return "" + return "", ErrNoESP } func Sign(file, output string, enroll bool) error {