Documentation ¶
Overview ¶
Package efibootmgr contains a boot management library
Index ¶
- func DelVariable(guid efi.GUID, name string) error
- func GetEfiArchitecture() string
- func GetVariable(guid efi.GUID, name string) (data []byte, attrs efi.VariableAttributes, err error)
- func GetVariableNames(filterGUID efi.GUID) (names []string, err error)
- func InstallShim(esp string, source string, vendor string) (bool, error)
- func MaybeUpdateFile(dst string, src string) (updated bool, err error)
- func NewFileDevicePath(filepath string, mode efi_linux.FileDevicePathMode) (efi.DevicePath, error)
- func ResealKey(assets *TrustedAssets, km *KernelManager, esp, shimSource, vendor string) error
- func SetVariable(guid efi.GUID, name string, data []byte, attrs efi.VariableAttributes) error
- func TrustCurrentBoot(assets *TrustedAssets, esp string) error
- func VariablesSupported() bool
- func WriteShimFallback(w io.Writer, entries []BootEntry) error
- func WriteShimFallbackToFile(path string, entries []BootEntry) error
- type BootEntry
- type BootEntryVariable
- type BootManager
- type EFIVariables
- type FS
- type File
- type KernelManager
- type RealEFIVariables
- func (RealEFIVariables) GetVariable(guid efi.GUID, name string) (data []byte, attrs efi.VariableAttributes, err error)
- func (RealEFIVariables) ListVariables() ([]efi.VariableDescriptor, error)
- func (RealEFIVariables) NewFileDevicePath(filepath string, mode efi_linux.FileDevicePathMode) (efi.DevicePath, error)
- func (RealEFIVariables) SetVariable(guid efi.GUID, name string, data []byte, attrs efi.VariableAttributes) error
- type TrustedAssets
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func DelVariable ¶ added in v0.1.0
DelVariable deletes the non-authenticated variable with the specified name.
func GetEfiArchitecture ¶
func GetEfiArchitecture() string
GetEfiArchitecture returns the EFI architecture for the target system
func GetVariable ¶ added in v0.1.0
GetVariable returns the payload and attributes of the variable with the specified name.
func GetVariableNames ¶ added in v0.1.0
GetVariableNames returns the names of every variable with the specified GUID.
func InstallShim ¶
InstallShim installs the shim into the given ESP for the given vendor It returns true if it installed the shim.
func MaybeUpdateFile ¶
MaybeUpdateFile copies src to dest if they are different It returns true if the destination file was successfully updated. If the return value is false, the state of the destination is unspecified. It might not exist, exist with partial data or exist with old data, amongst others.
func NewFileDevicePath ¶ added in v0.1.0
func NewFileDevicePath(filepath string, mode efi_linux.FileDevicePathMode) (efi.DevicePath, error)
NewFileDevicePath constructs a EFI device path for the specified file path.
func ResealKey ¶ added in v0.1.0
func ResealKey(assets *TrustedAssets, km *KernelManager, esp, shimSource, vendor string) error
ResealKey updates the PCR profile for the disk encryption key to incorporate the boot assets installed directly by the package manager and those assets copied by this package to the ESP.
func SetVariable ¶ added in v0.1.0
SetVariable updates the payload of the variable with the specified name.
func TrustCurrentBoot ¶ added in v0.1.1
func TrustCurrentBoot(assets *TrustedAssets, esp string) error
TrustCurrentBoot adds the assets used in the current boot to the list of boot assets trusted for adding to PCR profiles with ResealKey. It works by mapping EV_EFI_BOOT_SERVICES_APPLICATION events from the TCG log to files stored in the ESP.
func VariablesSupported ¶ added in v0.1.0
func VariablesSupported() bool
VariablesSupported indicates whether variables can be accessed.
func WriteShimFallback ¶
WriteShimFallback writes out a BOOT*.CSV for the shim fallback loader to the specified writer. The output of this function is unencoded, use a transformed UTF-16 writer.
func WriteShimFallbackToFile ¶
WriteShimFallbackToFile opens the specified path in UTF-16LE and then calls WriteShimFallback
Types ¶
type BootEntryVariable ¶
type BootEntryVariable struct { BootNumber int // number of the Boot variable, for example, for Boot0004 this is 4 Data []byte // the data of the variable Attributes efi.VariableAttributes // any attributes set on the variable LoadOption *efi.LoadOption // the data of the variable parsed as a load option, if it is a valid load option }
BootEntryVariable defines a boot entry variable
type BootManager ¶
type BootManager struct {
// contains filtered or unexported fields
}
BootManager manages the boot device selection menu entries (Boot0000...BootFFFF).
func NewBootManagerFromSystem ¶
func NewBootManagerFromSystem() (BootManager, error)
NewBootManagerFromSystem returns a new BootManager object, initialized with the system state.
func (*BootManager) DeleteEntry ¶
func (bm *BootManager) DeleteEntry(bootNum int) error
DeleteEntry deletes an entry and updates the cached boot order.
The boot order still needs to be committed afterwards. It is not written back immediately, as there will usually be multiple places to update boot order, and we can coalesce those writes. We still have to update the boot order though, such that when we delete an entry and then create a new one with the same number we don't accidentally have the new one in the order.
func (*BootManager) FindOrCreateEntry ¶
func (bm *BootManager) FindOrCreateEntry(entry BootEntry, relativeTo string) (int, error)
FindOrCreateEntry finds a matching entry in the boot device selection menu, or creates one if it is missing.
It returns the number of the entry created, or -1 on failure, with error set.
The argument relativeTo specifies the directory entry.Filename is in.
func (*BootManager) NextFreeEntry ¶
func (bm *BootManager) NextFreeEntry() (int, error)
NextFreeEntry returns the number of the next free Boot variable.
func (*BootManager) PrependAndSetBootOrder ¶
func (bm *BootManager) PrependAndSetBootOrder(head []int) error
PrependAndSetBootOrder commits a new boot order or returns an error.
The boot order specified is prepended to the existing one, and the order is deduplicated before committing.
type EFIVariables ¶
type EFIVariables interface { ListVariables() ([]efi.VariableDescriptor, error) GetVariable(guid efi.GUID, name string) (data []byte, attrs efi.VariableAttributes, err error) SetVariable(guid efi.GUID, name string, data []byte, attrs efi.VariableAttributes) error NewFileDevicePath(filepath string, mode efi_linux.FileDevicePathMode) (efi.DevicePath, error) }
EFIVariables abstracts away the host-specific bits of the efivars module
type FS ¶
type FS interface { // Create behaves like os.Create() Create(path string) (File, error) // MkdirAll behaves like os.MkdirAll() MkdirAll(path string, perm os.FileMode) error // Open behaves like os.Open() Open(path string) (File, error) // ReadDir behaves like os.ReadDir() ReadDir(path string) ([]os.DirEntry, error) // Readlink behaves like os.Readlink() Readlink(path string) (string, error) // Remove behaves like os.Remove() Remove(path string) error // Rename behaves like os.Rename() Rename(oldname, newname string) error // Stat behaves like os.Stat() Stat(path string) (os.FileInfo, error) // TempFile behaves like ioutil.TempFile() TempFile(dir, prefix string) (File, error) }
FS abstracts away the filesystem.
So we really wanted to use afero because it does all the magic for us, but it doubles our binary size, so that seems a tad much.
type File ¶ added in v0.1.0
type File interface { io.Closer io.Writer io.Reader io.ReaderAt io.Seeker Name() string Stat() (os.FileInfo, error) }
File abstracts an open file.
type KernelManager ¶
type KernelManager struct {
// contains filtered or unexported fields
}
KernelManager manages kernels in an SP vendor directory.
It will update or install shim, copy in any new kernels, remove old kernels, and configure boot in shim and BDS.
func NewKernelManager ¶
func NewKernelManager(esp, sourceDir, vendor string) (*KernelManager, error)
NewKernelManager returns a new kernel manager managing kernels in the host system
func (*KernelManager) CommitToBootLoader ¶
func (km *KernelManager) CommitToBootLoader() error
CommitToBootLoader updates the firmware BDS entries and shim's boot.csv
func (*KernelManager) InstallKernels ¶
func (km *KernelManager) InstallKernels() error
InstallKernels installs the kernels to the ESP and builds up the boot entries to commit using CommitToBootLoader()
func (*KernelManager) RemoveObsoleteKernels ¶
func (km *KernelManager) RemoveObsoleteKernels() error
RemoveObsoleteKernels removes old kernels in the ESP vendor directory
type RealEFIVariables ¶
type RealEFIVariables struct{}
RealEFIVariables provides the real implementation of efivars
func (RealEFIVariables) GetVariable ¶
func (RealEFIVariables) GetVariable(guid efi.GUID, name string) (data []byte, attrs efi.VariableAttributes, err error)
GetVariable proxy
func (RealEFIVariables) ListVariables ¶ added in v0.1.0
func (RealEFIVariables) ListVariables() ([]efi.VariableDescriptor, error)
ListVariables proxy
func (RealEFIVariables) NewFileDevicePath ¶ added in v0.1.0
func (RealEFIVariables) NewFileDevicePath(filepath string, mode efi_linux.FileDevicePathMode) (efi.DevicePath, error)
NewFileDevicePath proxy
func (RealEFIVariables) SetVariable ¶
func (RealEFIVariables) SetVariable(guid efi.GUID, name string, data []byte, attrs efi.VariableAttributes) error
SetVariable proxy
type TrustedAssets ¶ added in v0.1.0
type TrustedAssets struct {
// contains filtered or unexported fields
}
TrustedAssets keeps a record of boot asset hashes that are trusted for the purpose of computing PCR profiles. New hashes are added by adding a directory that is trusted using TrustNewFromDir - the directory will be one inside the encrypted container, writable by root and managed by the package manager).
Boot assets may be copied outside of a trusted directory, eg, to the ESP. Assets loaded from outside of a trusted directory in order to compute a PCR profile must be checked against one of the trusted hashes, to avoid tricking the resealing code into adding a malicious asset to a PCR profile.
Snapd achieves the same thing by keeping a cache of trusted assets inside the encrypted data partition. This avoids having to do that.
Note that the hashes are not constructed by hashing the file contents in a single pass, as this would require keeping entire PE images in memory after verifying their hashes in order to avoid TOCTOU type bugs. Files are hashed by producing a hash tree with a 4k block size. If a file's size is not a multiple of 4k, the last block is padded with zeros.
The hash tree is not stored anywhere - only the root hash is stored. In order to verify that a file's contents are trusted, the leaf hashes are constructed when the file is read and then closed (see hashedFile) and the rest of the hash tree is reconstructed by calling checkLeafHashes. In order to verify any blocks, the entire file has to eventually be read in order to reconstruct the entire hash tree. This is a tradeoff between having to read an entire file in order to verify a few blocks, and not having to read an entire file in order to verify a few blocks, but having to store the entire hash tree somewhere.
Use newCheckedHashedFile to have a file checked against the set of trusted boot assets.
func ReadTrustedAssets ¶ added in v0.1.0
func ReadTrustedAssets() (*TrustedAssets, error)
ReadTrustedAssets loads the list of previously trusted hashes from disk.
func (*TrustedAssets) RemoveObsolete ¶ added in v0.1.0
func (t *TrustedAssets) RemoveObsolete()
RemoveObsolete drops all asset hashes that haven't been added in this context via a call to TrustNewFromDir. This should be called after newly trusted assets have been properly committed and obsolete assets have been removed.
func (*TrustedAssets) Save ¶ added in v0.1.0
func (t *TrustedAssets) Save() (err error)
Save persists the list of trusted hashes to disk.
func (*TrustedAssets) TrustNewFromDir ¶ added in v0.1.0
func (t *TrustedAssets) TrustNewFromDir(path string) error
TrustNewFromDir adds hashes of the files under the specified path to the list of trusted hashes for the purpose of computing PCR profiles. The path should be within the encrypted container, writable only by root and managed by the package manager.