Skip to content

Commit

Permalink
Merge pull request #359 from chrisccoulson/preinstall-use-internal-tp…
Browse files Browse the repository at this point in the history
…m2-device

internal/efi: Use internal/tpm2_device package.

Other code in secboot makes use of this recently introduced package,
so the code in internal/efi should use it too.
  • Loading branch information
chrisccoulson authored Jan 21, 2025
2 parents 1bfd65a + 01dc667 commit c01c21d
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 76 deletions.
28 changes: 3 additions & 25 deletions internal/efi/default_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ package efi
import (
"bytes"
"context"
"errors"
"fmt"
"io"
"os"
Expand All @@ -31,13 +30,12 @@ import (

efi "github.com/canonical/go-efilib"
"github.com/canonical/go-tpm2"
"github.com/canonical/go-tpm2/linux"
"github.com/canonical/tcglog-parser"
"github.com/snapcore/secboot/internal/tpm2_device"
)

var (
linuxDefaultTPM2Device = linux.DefaultTPM2Device
linuxRawDeviceResourceManagedDevice = (*linux.RawDevice).ResourceManagedDevice
tpm2_deviceDefaultDevice = tpm2_device.DefaultDevice

eventLogPath = "/sys/kernel/security/tpm0/binary_bios_measurements" // Path of the TCG event log for the default TPM, in binary form
sysfsPath = "/sys"
Expand All @@ -63,27 +61,7 @@ func (defaultEnvImpl) ReadEventLog() (*tcglog.Log, error) {

// TPMDevice implements [HostEnvironment.TPMDevice].
func (defaultEnvImpl) TPMDevice() (tpm2.TPMDevice, error) {
device, err := linuxDefaultTPM2Device()
switch {
case errors.Is(err, linux.ErrNoTPMDevices) || errors.Is(err, linux.ErrDefaultNotTPM2Device):
return nil, ErrNoTPM2Device
case err != nil:
return nil, err
}

rmDevice, err := linuxRawDeviceResourceManagedDevice(device)
switch {
case errors.Is(err, linux.ErrNoResourceManagedDevice):
// Return the raw device. This can only be open once, so can block and may block other users.
return device, nil
case err != nil:
return nil, err
default:
// Return the resource managed device. There is no limit as to how may of these can be opened,
// although note that they can't be opened if the raw device is opened so this can still block
// if something else has the raw device open and might block other raw device users.
return rmDevice, nil
}
return tpm2_deviceDefaultDevice(tpm2_device.DeviceModeTryResourceManaged)
}

// DetectVirtMode implements [HostEnvironment.DetectVirtMode].
Expand Down
63 changes: 32 additions & 31 deletions internal/efi/default_env_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ import (

efi "github.com/canonical/go-efilib"
"github.com/canonical/go-tpm2"
"github.com/canonical/go-tpm2/linux"
"github.com/canonical/go-tpm2/ppi"
"github.com/canonical/tcglog-parser"
. "github.com/snapcore/secboot/internal/efi"
"github.com/snapcore/secboot/internal/efitest"
"github.com/snapcore/secboot/internal/testutil"
"github.com/snapcore/secboot/internal/tpm2_device"
snapd_testutil "github.com/snapcore/snapd/testutil"

. "gopkg.in/check.v1"
Expand Down Expand Up @@ -107,55 +108,55 @@ func (s *defaultEnvSuite) TestReadEventLog2(c *C) {
})
}

func (s *defaultEnvSuite) TestTPMDeviceRM(c *C) {
rawDev := new(linux.RawDevice)
restore := MockLinuxDefaultTPM2Device(rawDev, nil)
defer restore()
type mockTpmDevice struct {
mode tpm2_device.DeviceMode
}

rmDev := new(linux.RMDevice)
restore = MockLinuxRawDeviceResourceManagedDevice(c, rawDev, rmDev, nil)
defer restore()
func (*mockTpmDevice) Open() (tpm2.Transport, error) {
return nil, errors.New("not supported")
}

dev, err := DefaultEnv.TPMDevice()
c.Check(err, IsNil)
c.Check(dev, Equals, rmDev)
func (*mockTpmDevice) String() string {
return "mock TPM device"
}

func (s *defaultEnvSuite) TestTPMDeviceRaw(c *C) {
rawDev := new(linux.RawDevice)
restore := MockLinuxDefaultTPM2Device(rawDev, nil)
defer restore()
func (d *mockTpmDevice) Mode() tpm2_device.DeviceMode {
return d.mode
}

restore = MockLinuxRawDeviceResourceManagedDevice(c, rawDev, nil, linux.ErrNoResourceManagedDevice)
func (*mockTpmDevice) PPI() (ppi.PPI, error) {
return nil, tpm2_device.ErrNoPPI
}

func (s *defaultEnvSuite) TestTPMDevice(c *C) {
expectedDev := &mockTpmDevice{mode: tpm2_device.DeviceModeResourceManaged}
restore := MockDefaultTPM2Device(func(mode tpm2_device.DeviceMode) (tpm2_device.TPMDevice, error) {
c.Assert(mode, Equals, tpm2_device.DeviceModeTryResourceManaged)
return expectedDev, nil
})
defer restore()

dev, err := DefaultEnv.TPMDevice()
c.Check(err, IsNil)
c.Check(dev, Equals, rawDev)
c.Check(dev, DeepEquals, expectedDev)
}

func (s *defaultEnvSuite) TestTPMDeviceNoDevicesErr(c *C) {
restore := MockLinuxDefaultTPM2Device(nil, linux.ErrNoTPMDevices)
restore := MockDefaultTPM2Device(func(mode tpm2_device.DeviceMode) (tpm2_device.TPMDevice, error) {
c.Check(mode, Equals, tpm2_device.DeviceModeTryResourceManaged)
return nil, tpm2_device.ErrNoTPM2Device
})
defer restore()

_, err := DefaultEnv.TPMDevice()
c.Check(err, Equals, ErrNoTPM2Device)
}

func (s *defaultEnvSuite) TestTPMDeviceNoDevicesOtherErr(c *C) {
restore := MockLinuxDefaultTPM2Device(nil, errors.New("some error"))
defer restore()

_, err := DefaultEnv.TPMDevice()
c.Check(err, ErrorMatches, `some error`)
}

func (s *defaultEnvSuite) TestTPMDeviceRMOtherErr(c *C) {
rawDev := new(linux.RawDevice)
restore := MockLinuxDefaultTPM2Device(rawDev, nil)
defer restore()

restore = MockLinuxRawDeviceResourceManagedDevice(c, rawDev, nil, errors.New("some error"))
restore := MockDefaultTPM2Device(func(mode tpm2_device.DeviceMode) (tpm2_device.TPMDevice, error) {
c.Check(mode, Equals, tpm2_device.DeviceModeTryResourceManaged)
return nil, errors.New("some error")
})
defer restore()

_, err := DefaultEnv.TPMDevice()
Expand Down
3 changes: 2 additions & 1 deletion internal/efi/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (

"github.com/canonical/go-tpm2"
"github.com/canonical/tcglog-parser"
"github.com/snapcore/secboot/internal/tpm2_device"
)

// XXX: Some of the interfaces here are really public, but they are here because they are shared by
Expand Down Expand Up @@ -97,7 +98,7 @@ const VirtModeNone = "none"
var (
// ErrNoTPM2Device is returned from HostEnvironment.TPMDevice if no TPM2
// device is available.
ErrNoTPM2Device = errors.New("no TPM2 device is available")
ErrNoTPM2Device = tpm2_device.ErrNoTPM2Device

// ErrNoDeviceAttribute is returned from SysfsDevice.Attribute if the supplied attribute
// does not exist.
Expand Down
24 changes: 5 additions & 19 deletions internal/efi/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
package efi

import (
"github.com/canonical/go-tpm2/linux"
. "gopkg.in/check.v1"
"github.com/snapcore/secboot/internal/tpm2_device"
)

func MockEventLogPath(path string) (restore func()) {
Expand All @@ -32,24 +31,11 @@ func MockEventLogPath(path string) (restore func()) {
}
}

func MockLinuxDefaultTPM2Device(dev *linux.RawDevice, err error) (restore func()) {
orig := linuxDefaultTPM2Device
linuxDefaultTPM2Device = func() (*linux.RawDevice, error) {
return dev, err
}
return func() {
linuxDefaultTPM2Device = orig
}
}

func MockLinuxRawDeviceResourceManagedDevice(c *C, expectedDev *linux.RawDevice, dev *linux.RMDevice, err error) (restore func()) {
orig := linuxRawDeviceResourceManagedDevice
linuxRawDeviceResourceManagedDevice = func(device *linux.RawDevice) (*linux.RMDevice, error) {
c.Check(device, Equals, expectedDev)
return dev, err
}
func MockDefaultTPM2Device(fn func(tpm2_device.DeviceMode) (tpm2_device.TPMDevice, error)) (restore func()) {
orig := tpm2_deviceDefaultDevice
tpm2_deviceDefaultDevice = fn
return func() {
linuxRawDeviceResourceManagedDevice = orig
tpm2_deviceDefaultDevice = orig
}
}

Expand Down

0 comments on commit c01c21d

Please sign in to comment.