Documentation
¶
Overview ¶
Package efibootmgr contains a boot management library
Index ¶
- func DelVariable(efivars EFIVariables, guid efi.GUID, name string) error
- func GetEfiArchitecture() string
- func GetVariableNames(efiVars EFIVariables, 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 ResealKey(assets *TrustedAssets, km *KernelManager, esp, shimSource, vendor string) error
- func TrustCurrentBoot(assets *TrustedAssets, esp string) error
- func VariablesSupported(efiVars EFIVariables) bool
- func WriteShimFallback(w io.Writer, entries []BootEntry) error
- func WriteShimFallbackToFile(path string, entries []BootEntry) error
- type BootEntry
- type BootEntryVariable
- type BootManager
- func (bm *BootManager) DeleteEntry(bootNum int) error
- func (bm *BootManager) FindBootEntryVariable(entry BootEntry, relativeTo string) (BootEntryVariable, error)
- func (bm *BootManager) FindOrCreateEntry(entry BootEntry, relativeTo string) (int, error)
- func (bm *BootManager) NextFreeEntry() (int, error)
- func (bm *BootManager) PrependAndSetBootOrder(head []int) error
- func (bm *BootManager) RegisterBootEntryVariable(entryVar BootEntryVariable) error
- func (bm *BootManager) SetBootNext(bootNum int) error
- type BootVarNotFoundError
- type EFIVariables
- type FS
- type File
- type Kernel
- type KernelEntry
- type KernelManager
- func (km *KernelManager) CommitToBootLoader() error
- func (km *KernelManager) GetLatestKernelEntry() (KernelEntry, error)
- func (km *KernelManager) InstallKernels() error
- func (km *KernelManager) IsCurrentBootLatest() (bool, error)
- func (km *KernelManager) RegisterNewKernelEFIs() error
- func (km *KernelManager) RemoveObsoleteKernels() error
- func (km *KernelManager) SetLatestKernelToBootNext() error
- type LoadChain
- type MockEFIVariables
- func (m MockEFIVariables) GetVariable(guid efi.GUID, name string) (data []byte, attrs efi.VariableAttributes, err error)
- func (m MockEFIVariables) JSON() ([]byte, error)
- func (m MockEFIVariables) ListVariables() (out []efi.VariableDescriptor, err error)
- func (m MockEFIVariables) NewFileDevicePath(filepath string, mode efi_linux.FilePathToDevicePathMode) (efi.DevicePath, error)
- func (m *MockEFIVariables) SetVariable(guid efi.GUID, name string, data []byte, attrs efi.VariableAttributes) error
- type RealEFIVariables
- func (vars RealEFIVariables) GetVariable(guid efi.GUID, name string) (data []byte, attrs efi.VariableAttributes, err error)
- func (vars RealEFIVariables) ListVariables() ([]efi.VariableDescriptor, error)
- func (vars RealEFIVariables) NewFileDevicePath(filepath string, mode efi_linux.FilePathToDevicePathMode) (efi.DevicePath, error)
- func (vars 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
func DelVariable(efivars EFIVariables, guid efi.GUID, name string) error
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 GetVariableNames ¶ added in v0.1.0
func GetVariableNames(efiVars EFIVariables, filterGUID efi.GUID) (names []string, err error)
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 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 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(efiVars EFIVariables) 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
func NewBootEntryVariable ¶ added in v0.6.0
func NewBootEntryVariable(entry BootEntry, bootNum int, dp efi.DevicePath) (BootEntryVariable, error)
NewBootEntryVariable creates a BootEntryVariable derived from a BootEntry, given a boot number and device path.
type BootManager ¶
type BootManager struct {
// contains filtered or unexported fields
}
BootManager manages the boot device selection menu entries (Boot0000...BootFFFF).
func NewBootManagerForVariables ¶ added in v0.4.0
func NewBootManagerForVariables(efivars EFIVariables) (BootManager, error)
NewBootManagerForVariables returns a boot manager for the given EFIVariables manager
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) FindBootEntryVariable ¶ added in v0.6.0
func (bm *BootManager) FindBootEntryVariable(entry BootEntry, relativeTo string) (BootEntryVariable, error)
FindBootEntryVariable finds a matching BootEntryVariable from the boot device selection menu associated to the input BootEntry in a relative directory.
The argument relativeTo specifies the directory entry.Filename is in.
If a BootEntryVariable cannot be found, returns BootVarNotFoundError.
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 invalidBootNumber 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.
func (*BootManager) RegisterBootEntryVariable ¶ added in v0.6.0
func (bm *BootManager) RegisterBootEntryVariable(entryVar BootEntryVariable) error
RegisterBootEntryVariable registers a system boot variable to the bm.efivars and bm.entries.
It returns an error should there be an issue registering the system variable.
func (*BootManager) SetBootNext ¶ added in v0.6.0
func (bm *BootManager) SetBootNext(bootNum int) error
SetBootNext sets the system BootNext variable to the encoded value of the input boot number.
Returns an error in the event that the variable cannot be set.
type BootVarNotFoundError ¶ added in v0.6.0
func (BootVarNotFoundError) Error ¶ added in v0.6.0
func (e BootVarNotFoundError) Error() string
func (BootVarNotFoundError) Unwrap ¶ added in v0.6.0
func (e BootVarNotFoundError) Unwrap() error
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.FilePathToDevicePathMode) (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 Kernel ¶ added in v0.6.0
type Kernel struct {
Version version.Version
FilePath string
}
func (*Kernel) GetKernelName ¶ added in v0.6.0
type KernelEntry ¶ added in v0.6.0
type KernelEntry struct {
// contains filtered or unexported fields
}
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, bootManager *BootManager) (*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) GetLatestKernelEntry ¶ added in v0.6.0
func (km *KernelManager) GetLatestKernelEntry() (KernelEntry, error)
Returns the KernelEntry with the largest version in km.kernelEntries
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) IsCurrentBootLatest ¶ added in v0.6.0
func (km *KernelManager) IsCurrentBootLatest() (bool, error)
func (*KernelManager) RegisterNewKernelEFIs ¶ added in v0.6.0
func (km *KernelManager) RegisterNewKernelEFIs() error
RegisterNewKernelEFIs creates EFI variables for each new kernel installed via InstallKernels, adding them to the BootManager and creating the variables on the host machine.
func (*KernelManager) RemoveObsoleteKernels ¶
func (km *KernelManager) RemoveObsoleteKernels() error
RemoveObsoleteKernels removes old kernels in the ESP vendor directory
func (*KernelManager) SetLatestKernelToBootNext ¶ added in v0.6.0
func (km *KernelManager) SetLatestKernelToBootNext() error
SetLatestKernelToBootNext sets the latest kernel to be BootNext.
Returns an error if the entry does not yet exist as a BootEntryVariable or if there is an error setting BootNext.
type LoadChain ¶ added in v0.6.0
type LoadChain struct {
// Next is a list of alternative chains that can be loaded
// following the boot file.
Next []*LoadChain
// contains filtered or unexported fields
}
func NewLoadChain ¶ added in v0.6.0
func (LoadChain) Open ¶ added in v0.6.0
func (i LoadChain) Open() (imageReader secboot_efi.ImageReader, err error)
type MockEFIVariables ¶ added in v0.4.0
type MockEFIVariables struct {
// contains filtered or unexported fields
}
MockEFIVariables implements an in-memory variable store.
func (MockEFIVariables) GetVariable ¶ added in v0.4.0
func (m MockEFIVariables) GetVariable(guid efi.GUID, name string) (data []byte, attrs efi.VariableAttributes, err error)
GetVariable implements EFIVariables
func (MockEFIVariables) JSON ¶ added in v0.4.0
func (m MockEFIVariables) JSON() ([]byte, error)
JSON renders the MockEFIVariables as an Azure JSON config
func (MockEFIVariables) ListVariables ¶ added in v0.4.0
func (m MockEFIVariables) ListVariables() (out []efi.VariableDescriptor, err error)
ListVariables implements EFIVariables
func (MockEFIVariables) NewFileDevicePath ¶ added in v0.4.0
func (m MockEFIVariables) NewFileDevicePath(filepath string, mode efi_linux.FilePathToDevicePathMode) (efi.DevicePath, error)
NewFileDevicePath implements EFIVariables
func (*MockEFIVariables) SetVariable ¶ added in v0.4.0
func (m *MockEFIVariables) SetVariable(guid efi.GUID, name string, data []byte, attrs efi.VariableAttributes) error
SetVariable implements EFIVariables
type RealEFIVariables ¶
type RealEFIVariables struct{}
RealEFIVariables provides the real implementation of efivars
func (RealEFIVariables) GetVariable ¶
func (vars 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 (vars RealEFIVariables) ListVariables() ([]efi.VariableDescriptor, error)
ListVariables proxy
func (RealEFIVariables) NewFileDevicePath ¶ added in v0.1.0
func (vars RealEFIVariables) NewFileDevicePath(filepath string, mode efi_linux.FilePathToDevicePathMode) (efi.DevicePath, error)
NewFileDevicePath proxy
func (RealEFIVariables) SetVariable ¶
func (vars 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.