Skip to content

Commit

Permalink
efi: Allow HostEnvironment.VarContext to take a parent context
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisccoulson committed Jul 8, 2024
1 parent aaba2c5 commit 1c78a22
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 13 deletions.
2 changes: 1 addition & 1 deletion efi/efi_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,7 @@ type mockVarReader struct {
}

func newMockVarReader(env HostEnvironment) *mockVarReader {
return &mockVarReader{ctx: env.VarContext()}
return &mockVarReader{ctx: env.VarContext(context.Background())}
}

func (r *mockVarReader) ReadVar(name string, guid efi.GUID) ([]byte, efi.VariableAttributes, error) {
Expand Down
21 changes: 18 additions & 3 deletions efi/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,13 @@ import (
type HostEnvironment interface {
// VarContext returns a context containing a VarsBackend, keyed by efi.VarsBackendKey,
// for interacting with EFI variables via go-efilib. This context can be passed to any
// go-efilib function that interacts with EFI variables.
VarContext() context.Context
// go-efilib function that interacts with EFI variables. Right now, go-efilib doesn't
// support any other uses of the context such as cancelation or deadlines. The efivarfs
// backend will support this eventually for variable writes because it currently implements
// a retry loop that has a potential to race with other processes. Cancelation and / or
// deadlines for sections of code that performs multiple reads using efivarfs may be useful
// in the future because the kernel rate-limits reads per-user.
VarContext(parent context.Context) context.Context

// ReadEventLog reads the TCG event log
ReadEventLog() (*tcglog.Log, error)
Expand Down Expand Up @@ -261,7 +266,17 @@ type variableSetCollector struct {
}

func newVariableSetCollector(env HostEnvironment) *variableSetCollector {
varsCtx := env.VarContext()
// We pass the TODO context here for now, as the context just essentially
// a container for holding the variable backend, so there's no need for
// the caller to override it.
//
// In the future, the efivarfs backend will make use of cancellation and / or
// deadlines it because it runs a retry loop that can race with other processes,
// although this package is doing no writing. Cancellation and / or deadlines
// may also still be useful in the read path especially where a section of code
// performs multiple reads via efivarfs - these reads are rate-limitted per-user
// in the kernel.
varsCtx := env.VarContext(context.TODO())
return &variableSetCollector{
varsCtx: varsCtx,
seen: map[initialVarReaderKey]struct{}{initialVarReaderKey{}: struct{}{}}, // add the current environment
Expand Down
4 changes: 3 additions & 1 deletion efi/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
package efi

import (
"context"

efi "github.com/canonical/go-efilib"
"github.com/canonical/tcglog-parser"
"github.com/snapcore/secboot/efi/internal"
Expand Down Expand Up @@ -192,7 +194,7 @@ func MockSnapdenvTesting(testing bool) (restore func()) {

func NewInitialVarReader(host HostEnvironment) *initialVarReader {
return &initialVarReader{
varsCtx: host.VarContext(),
varsCtx: host.VarContext(context.TODO()),
overrides: make(map[efi.VariableDescriptor]varContents)}
}

Expand Down
4 changes: 2 additions & 2 deletions efi/internal/default_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ var (
type defaultEnvImpl struct{}

// VarContext implements [HostEnvironment.VarContext].
func (e defaultEnvImpl) VarContext() context.Context {
return efi.DefaultVarContext
func (e defaultEnvImpl) VarContext(parent context.Context) context.Context {
return efi.WithDefaultVarsBackend(parent)
}

// ReadEventLog implements [HostEnvironment.ReadEventLog].
Expand Down
7 changes: 6 additions & 1 deletion efi/internal/default_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
package internal_test

import (
"context"
_ "embed"
"io"
"os"
Expand All @@ -39,7 +40,11 @@ type defaultEnvSuite struct{}
var _ = Suite(&defaultEnvSuite{})

func (s *defaultEnvSuite) TestVarContext(c *C) {
c.Check(DefaultEnv.VarContext(), Equals, efi.DefaultVarContext)
ctx := DefaultEnv.VarContext(context.Background())
c.Assert(ctx, NotNil)

expected := efi.WithDefaultVarsBackend(context.Background())
c.Check(ctx.Value(efi.VarsBackendKey{}), Equals, expected.Value(efi.VarsBackendKey{}))
}

func (s *defaultEnvSuite) testReadEventLog(c *C, opts *efitest.LogOptions) {
Expand Down
9 changes: 7 additions & 2 deletions efi/internal/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,13 @@ import (
type HostEnvironment interface {
// VarContext returns a context containing a VarsBackend, keyed by efi.VarsBackendKey,
// for interacting with EFI variables via go-efilib. This context can be passed to any
// go-efilib function that interacts with EFI variables.
VarContext() context.Context
// go-efilib function that interacts with EFI variables. Right now, go-efilib doesn't
// support any other uses of the context such as cancelation or deadlines. The efivarfs
// backend will support this eventually for variable writes because it currently implements
// a retry loop that has a potential to race with other processes. Cancelation and / or
// deadlines for sections of code that performs multiple reads using efivarfs may be useful
// in the future because the kernel rate-limits reads per-user.
VarContext(parent context.Context) context.Context

// ReadEventLog reads the TCG event log
ReadEventLog() (*tcglog.Log, error)
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/snapcore/secboot
go 1.18

require (
github.com/canonical/go-efilib v1.0.0
github.com/canonical/go-efilib v1.2.0
github.com/canonical/go-sp800.108-kdf v0.0.0-20210315104021-ead800bbf9a0
github.com/canonical/go-sp800.90a-drbg v0.0.0-20210314144037-6eeb1040d6c3
github.com/canonical/go-tpm2 v1.3.0
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ github.com/canonical/go-efilib v0.9.10-0.20240618094320-cc6dd01c07dc h1:U2xZoSBO
github.com/canonical/go-efilib v0.9.10-0.20240618094320-cc6dd01c07dc/go.mod h1:n0Ttsy1JuHAvqaFbZBs6PAzoiiJdfkHsAmDOEbexYEQ=
github.com/canonical/go-efilib v1.0.0 h1:da3shbdfbJgIUzq4qspkNdWccV5lNMi0ZeYksVCoCvg=
github.com/canonical/go-efilib v1.0.0/go.mod h1:n0Ttsy1JuHAvqaFbZBs6PAzoiiJdfkHsAmDOEbexYEQ=
github.com/canonical/go-efilib v1.1.0 h1:14CRXLfczZFthTfp2MQBLRz91F2zx8F5jP/YOlJaeDk=
github.com/canonical/go-efilib v1.1.0/go.mod h1:n0Ttsy1JuHAvqaFbZBs6PAzoiiJdfkHsAmDOEbexYEQ=
github.com/canonical/go-efilib v1.2.0 h1:+fvJdkj3oVyURFtfk8gSft6pdKyVzzdzNn9GC1kMJw8=
github.com/canonical/go-efilib v1.2.0/go.mod h1:n0Ttsy1JuHAvqaFbZBs6PAzoiiJdfkHsAmDOEbexYEQ=
github.com/canonical/go-sp800.108-kdf v0.0.0-20210314145419-a3359f2d21b9/go.mod h1:Zrs3YjJr+w51u0R/dyLh/oWt/EcBVdLPCVFYC4daW5s=
github.com/canonical/go-sp800.108-kdf v0.0.0-20210315104021-ead800bbf9a0 h1:ZE2XMRFHcwlib3uU9is37+pKkkMloVoEPWmgQ6GK1yo=
github.com/canonical/go-sp800.108-kdf v0.0.0-20210315104021-ead800bbf9a0/go.mod h1:Zrs3YjJr+w51u0R/dyLh/oWt/EcBVdLPCVFYC4daW5s=
Expand Down
4 changes: 2 additions & 2 deletions internal/efitest/hostenv.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ func NewMockHostEnvironment(vars MockVars, log *tcglog.Log) *MockHostEnvironment
}

// VarContext implements [github.com/snapcore/secboot/efi.HostEnvironment.VarContext]/
func (e *MockHostEnvironment) VarContext() context.Context {
return context.WithValue(context.Background(), efi.VarsBackendKey{}, e.Vars)
func (e *MockHostEnvironment) VarContext(parent context.Context) context.Context {
return context.WithValue(parent, efi.VarsBackendKey{}, e.Vars)
}

// ReadEventLog implements [github.com/snapcore/secboot/efi.HostEnvironment.ReadEventLog].
Expand Down

0 comments on commit 1c78a22

Please sign in to comment.