diff --git a/internal/agent/hooks/kcrypt_uki.go b/internal/agent/hooks/kcrypt_uki.go index bdd4d6c..015bfe0 100644 --- a/internal/agent/hooks/kcrypt_uki.go +++ b/internal/agent/hooks/kcrypt_uki.go @@ -1,6 +1,7 @@ package hook import ( + "fmt" "os" "strconv" "strings" @@ -96,10 +97,40 @@ func (k KcryptUKI) Run(c config.Config, _ v1.Spec) error { c.Logger.Infof("Done encrypting %s", p) } + _, _ = utils.SH("sync") + err = kcrypt.UnlockAll(true) if err != nil { return err } + // Close the unlocked partitions after dealing with them, otherwise we leave them open and they can be mounted by anyone + defer func() { + for _, p := range append([]string{"COS_OEM", "COS_PERSISTENT"}, c.Install.Encrypt...) { + c.Logger.Debugf("Closing unencrypted /dev/disk/by-label/%s", p) + out, err := utils.SH(fmt.Sprintf("cryptsetup close /dev/disk/by-label/%s", p)) + // There is a known error with cryptsetup that it can't close the device because of a semaphore + // doesnt seem to affect anything as the device is closed as expected so we ignore it if it matches the + // output of the error + if err != nil && !strings.Contains(out, "incorrect semaphore state") { + c.Logger.Errorf("could not close /dev/disk/by-label/%s: %s", p, out) + } + } + }() + + // Here it can take the oem partition a bit of time to appear after unlocking so we need to retry a couple of time with some waiting + // retry + backoff + for i := 0; i < 10; i++ { + c.Logger.Infof("Waiting for unlocked partition to appear") + _, _ = utils.SH("sync") + part, _ := utils.SH("blkid -L COS_OEM") + if part == "" { + c.Logger.Infof("Partition not found, waiting %d seconds before retrying", i) + time.Sleep(time.Duration(i) * time.Second) + continue + } + c.Logger.Infof("Partition found, continuing") + break + } err = machine.Mount("COS_OEM", constants.OEMDir) if err != nil { return err @@ -108,7 +139,7 @@ func (k KcryptUKI) Run(c config.Config, _ v1.Spec) error { if err != nil { return err } - err = machine.Umount(constants.OEMDir) //nolint:errcheck + err = machine.Umount(constants.OEMDir) if err != nil { return err }