Skip to content

Commit

Permalink
Merge branch 'Foxboron:master' into kms
Browse files Browse the repository at this point in the history
  • Loading branch information
scj643 authored Oct 23, 2024
2 parents 4c6525a + 53e074d commit 05641ad
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 48 deletions.
9 changes: 5 additions & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ jobs:
GOARCH: ${{ matrix.GOARCH }}
GOARM: ${{ matrix.GOARM }}
- name: Upload workflow artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: sbctl-binaries
name: sbctl-binaries-${{ matrix.GOOS }}-${{ matrix.GOARCH }}
path: sbctl-*
upload:
name: Upload release binaries
Expand All @@ -55,9 +55,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Download workflow artifacts
uses: actions/download-artifact@v2
uses: actions/download-artifact@v4
with:
name: sbctl-binaries
name: sbctl-binaries-${{ matrix.GOOS }}-${{ matrix.GOARCH }}
merge-multiple: true
- name: Upload release artifacts
run: gh release upload "$GITHUB_REF_NAME" sbctl-*
env:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
tags
releases/*
/sbctl
docs/*.5
docs/*.8
rootfs*
VERSION
13 changes: 12 additions & 1 deletion cmd/sbctl/enroll-keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"errors"
"fmt"
"os"
"slices"
"strings"

Expand All @@ -16,6 +17,7 @@ import (
"github.com/foxboron/sbctl/logging"
"github.com/foxboron/sbctl/lsm"
"github.com/foxboron/sbctl/stringset"
"github.com/landlock-lsm/go-landlock/landlock"
"github.com/spf13/afero"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -63,6 +65,15 @@ var (
RunE: func(cmd *cobra.Command, args []string) error {
state := cmd.Context().Value(stateDataKey{}).(*config.State)
if state.Config.Landlock {
if enrollKeysCmdOptions.Export.Value != "" {
wd, err := os.Getwd()
if err != nil {
return err
}
lsm.RestrictAdditionalPaths(
landlock.RWDirs(wd),
)
}
if err := lsm.Restrict(); err != nil {
return err
}
Expand Down Expand Up @@ -310,7 +321,7 @@ func RunEnrollKeys(state *config.State) error {
return err
}
}
if !enrollKeysCmdOptions.Force && !enrollKeysCmdOptions.TPMEventlogChecksums && !enrollKeysCmdOptions.MicrosoftKeys {
if !enrollKeysCmdOptions.Force && !enrollKeysCmdOptions.TPMEventlogChecksums && !enrollKeysCmdOptions.MicrosoftKeys && !enrollKeysCmdOptions.Append {
if err := sbctl.CheckEventlogOprom(state.Fs, systemEventlog); err != nil {
return err
}
Expand Down
99 changes: 62 additions & 37 deletions cmd/sbctl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,26 +83,8 @@ func main() {
rootCmd.AddCommand(cmd.Cmd)
}

var conf *config.Config

fs := afero.NewOsFs()

if config.HasOldConfig(fs, sbctl.DatabasePath) && !config.HasConfigurationFile(fs, "/etc/sbctl/sbctl.conf") {
logging.Error(fmt.Errorf("old configuration detected. Please use `sbctl setup --migrate`"))
conf = config.OldConfig(sbctl.DatabasePath)
} else if ok, _ := afero.Exists(fs, "/etc/sbctl/sbctl.conf"); ok {
b, err := os.ReadFile("/etc/sbctl/sbctl.conf")
if err != nil {
log.Fatal(err)
}
conf, err = config.NewConfig(b)
if err != nil {
log.Fatal(err)
}
} else {
conf = config.DefaultConfig()
}

baseFlags(rootCmd)

// We save tpmerr and print it when we can print debug messages
Expand All @@ -111,20 +93,62 @@ func main() {
defer rwc.Close()
}

state := &config.State{
Fs: fs,
TPM: func() transport.TPMCloser {
return rwc
},
Config: conf,
Efivarfs: efivarfs.NewFS().
CheckImmutable().
UnsetImmutable().
Open(),
}

// We need to set this after we have parsed stuff
rootCmd.PersistentPreRun = func(_ *cobra.Command, _ []string) {
rootCmd.PersistentPreRunE = func(cmd *cobra.Command, _ []string) error {
state := &config.State{
Fs: fs,
TPM: func() transport.TPMCloser {
return rwc
},
Efivarfs: efivarfs.NewFS().
CheckImmutable().
UnsetImmutable().
Open(),
}

var conf *config.Config

if cmdOptions.Config != "" {
b, err := os.ReadFile(cmdOptions.Config)
if err != nil {
return err
}
conf, err = config.NewConfig(b)
if err != nil {
return err
}

state.Config = conf

// TODO: Do we want to overwrite the provided configuration with out existing keys?
// something to figure out
// kh, err := backend.GetKeyHierarchy(fs, state)
// if err != nil {
// return err
// }
// state.Config.Keys = kh.GetConfig(state.Config.Keydir)
// state.Config.DbAdditions = sbctl.GetEnrolledVendorCerts()
} else {
if config.HasOldConfig(fs, sbctl.DatabasePath) && !config.HasConfigurationFile(fs, "/etc/sbctl/sbctl.conf") {
logging.Error(fmt.Errorf("old configuration detected. Please use `sbctl setup --migrate`"))
conf = config.OldConfig(sbctl.DatabasePath)
state.Config = conf
} else if ok, _ := afero.Exists(fs, "/etc/sbctl/sbctl.conf"); ok {
b, err := os.ReadFile("/etc/sbctl/sbctl.conf")
if err != nil {
log.Fatal(err)
}
conf, err = config.NewConfig(b)
if err != nil {
log.Fatal(err)
}
state.Config = conf
} else {
conf = config.DefaultConfig()
state.Config = conf
}
}

if cmdOptions.JsonOutput {
logging.PrintOff()
}
Expand All @@ -148,12 +172,13 @@ func main() {
if !state.HasTPM() {
slog.Debug("can't open tpm", slog.Any("err", tpmerr))
}
}

ctx := context.WithValue(context.Background(), stateDataKey{}, state)

if state.Config.Landlock {
lsm.LandlockRulesFromConfig(state.Config)
if state.Config.Landlock {
lsm.LandlockRulesFromConfig(state.Config)
}
ctx := context.WithValue(cmd.Context(), stateDataKey{}, state)
cmd.SetContext(ctx)
return nil
}

// This returns i the flag is not found with a specific error
Expand All @@ -163,7 +188,7 @@ func main() {
return ErrSilent
})

if err := rootCmd.ExecuteContext(ctx); err != nil {
if err := rootCmd.Execute(); err != nil {
if strings.HasPrefix(err.Error(), "unknown command") {
logging.Println(err.Error())
} else if errors.Is(err, os.ErrPermission) {
Expand Down
14 changes: 14 additions & 0 deletions cmd/sbctl/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,20 @@ var signCmd = &cobra.Command{
if err != nil {
return err
}
// Get output path from database for file if output not specified
if output == "" {
files, err := sbctl.ReadFileDatabase(state.Fs, state.Config.FilesDb)
if err != nil {
return err
}
for _, entry := range files {
if entry.File == file {
output = entry.OutputFile
break
}
}
}

if output == "" {
output = file
rules = append(rules, lsm.TruncFile(file).IgnoreIfMissing())
Expand Down
2 changes: 1 addition & 1 deletion cmd/sbctl/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func RunStatus(cmd *cobra.Command, args []string) error {
}

stat := NewStatus()
if _, err := state.Fs.Stat("/sys/firmware/efi/efivars"); os.IsNotExist(err) {
if _, err := state.Fs.Stat("/sys/firmware/efi/efivars/SetupMode-8be4df61-93ca-11d2-aa0d-00e098032b8c"); os.IsNotExist(err) {
return fmt.Errorf("system is not booted with UEFI")
}

Expand Down
13 changes: 11 additions & 2 deletions cmd/sbctl/status_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ var (
)

func TestStatusOff(t *testing.T) {
cmd := SetFS(efitest.SecureBootOff())
cmd := SetFS(
efitest.SecureBootOff(),
efitest.SetUpModeOn(),
)

if err := captureJsonOutput(&out, func() error {
return RunStatus(cmd, []string{})
Expand All @@ -28,7 +31,8 @@ func TestStatusOff(t *testing.T) {
}

func TestStatusOn(t *testing.T) {
cmd := SetFS(efitest.SecureBootOn())
cmd := SetFS(efitest.SecureBootOn(),
efitest.SetUpModeOff())

if err := captureJsonOutput(&out, func() error {
return RunStatus(cmd, []string{})
Expand All @@ -50,6 +54,7 @@ func TestFQ0001DateMethod(t *testing.T) {
fstest.MapFS{"/sys/devices/virtual/dmi/id/chassis_type": {Data: []byte("3\n")}},
fstest.MapFS{"/sys/devices/virtual/dmi/id/product_name": {Data: []byte("MS-7E07\n")}},
efitest.SecureBootOn(),
efitest.SetUpModeOff(),
)

if err := captureJsonOutput(&out, func() error {
Expand Down Expand Up @@ -81,6 +86,7 @@ func TestFQ0001DeviceMethod(t *testing.T) {
fstest.MapFS{"/sys/devices/virtual/dmi/id/chassis_type": {Data: []byte("3\n")}},
fstest.MapFS{"/sys/devices/virtual/dmi/id/product_name": {Data: []byte("MS-7C84\n")}},
efitest.SecureBootOn(),
efitest.SetUpModeOff(),
)

if err := captureJsonOutput(&out, func() error {
Expand Down Expand Up @@ -112,6 +118,7 @@ func TestFQ0001ExplicitlyUnaffected(t *testing.T) {
fstest.MapFS{"/sys/devices/virtual/dmi/id/chassis_type": {Data: []byte("3\n")}},
fstest.MapFS{"/sys/devices/virtual/dmi/id/product_name": {Data: []byte("MS-7C80\n")}},
efitest.SecureBootOn(),
efitest.SetUpModeOff(),
)

if err := captureJsonOutput(&out, func() error {
Expand Down Expand Up @@ -141,6 +148,7 @@ func TestFQ0001WrongChassis(t *testing.T) {
fstest.MapFS{"/sys/devices/virtual/dmi/id/chassis_type": {Data: []byte("5\n")}},
fstest.MapFS{"/sys/devices/virtual/dmi/id/product_name": {Data: []byte("MS-7E07\n")}},
efitest.SecureBootOn(),
efitest.SetUpModeOff(),
)

if err := captureJsonOutput(&out, func() error {
Expand Down Expand Up @@ -170,6 +178,7 @@ func TestFQ0001WrongVendor(t *testing.T) {
fstest.MapFS{"/sys/devices/virtual/dmi/id/chassis_type": {Data: []byte("3\n")}},
fstest.MapFS{"/sys/devices/virtual/dmi/id/product_name": {Data: []byte("MS-7E07\n")}},
efitest.SecureBootOn(),
efitest.SetUpModeOff(),
)

if err := captureJsonOutput(&out, func() error {
Expand Down
1 change: 1 addition & 0 deletions contrib/pacman/ZZ-sbctl.hook
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Target = efi/*
Target = usr/lib/modules/*/vmlinuz
Target = usr/lib/modules/*/extramodules/*
Target = usr/lib/**/efi/*.efi*
Target = usr/share/**/*.efi*

[Action]
Description = Signing EFI binaries...
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ toolchain go1.22.5
require (
github.com/fatih/color v1.17.0
github.com/foxboron/go-tpm-keyfiles v0.0.0-20240725205618-b7c5a84edf9d
github.com/foxboron/go-uefi v0.0.0-20240722190620-5d4f760099bd
github.com/foxboron/go-uefi v0.0.0-20241017190036-fab4fdf2f2f3
github.com/goccy/go-yaml v1.11.3
github.com/google/go-attestation v0.5.1
github.com/google/go-tpm v0.9.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,8 @@ github.com/fortytw2/leaktest v1.2.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHqu
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/foxboron/go-tpm-keyfiles v0.0.0-20240725205618-b7c5a84edf9d h1:odwhCo3olsbN0fkXxCSH3aYz2OhrkcH93oU2QKEcI9s=
github.com/foxboron/go-tpm-keyfiles v0.0.0-20240725205618-b7c5a84edf9d/go.mod h1:uAyTlAUxchYuiFjTHmuIEJ4nGSm7iOPaGcAyA81fJ80=
github.com/foxboron/go-uefi v0.0.0-20240722190620-5d4f760099bd h1:as2HfgSh+rJJgM9yCSAv+VpJt11hMPpYh6Jo9l45Ceo=
github.com/foxboron/go-uefi v0.0.0-20240722190620-5d4f760099bd/go.mod h1:ffg/fkDeOYicEQLoO2yFFGt00KUTYVXI+rfnc8il6vQ=
github.com/foxboron/go-uefi v0.0.0-20241017190036-fab4fdf2f2f3 h1:K8ADp66ulnZ0NhjzwVwE4E3g6Id5KMWu86l0vURusA8=
github.com/foxboron/go-uefi v0.0.0-20241017190036-fab4fdf2f2f3/go.mod h1:ffg/fkDeOYicEQLoO2yFFGt00KUTYVXI+rfnc8il6vQ=
github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006 h1:50sW4r0PcvlpG4PV8tYh2RVCapszJgaOLRCS2subvV4=
github.com/foxboron/swtpm_test v0.0.0-20230726224112-46aaafdf7006/go.mod h1:eIXCMsMYCaqq9m1KSSxXwQG11krpuNPGP3k0uaWrbas=
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
Expand Down
2 changes: 2 additions & 0 deletions quirks/fq0001.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ func HasFQ0001() bool {
{Name: "MS-7C80", NameSrc: &dmi.Table.ProductName, NameStrict: true, Version: "1.B0", VersionSrc: &dmi.Table.FirmwareVersion},
// MSI H310M PRO-C
{Name: "MS-7D02", NameSrc: &dmi.Table.ProductName, NameStrict: true, Version: "1.20", VersionSrc: &dmi.Table.FirmwareVersion},
// MSI MPG X670E CARBON WIFI
{Name: "MS-7D70", NameSrc: &dmi.Table.ProductName, NameStrict: true, Version: "1.K0", VersionSrc: &dmi.Table.FirmwareVersion},
}

affectedDateRanges := []affectedDateRange{
Expand Down
3 changes: 3 additions & 0 deletions tpm.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ func GetEventlogChecksums(vfs afero.Fs, eventlog string) (*signature.SignatureDa
for _, event := range events {
switch event.Type.String() {
case "EV_EFI_BOOT_SERVICES_DRIVER":
if sigdb.BytesExists(signature.CERT_SHA256_GUID, eventlogGUID, event.Digest) {
continue
}
if err = sigdb.Append(signature.CERT_SHA256_GUID, eventlogGUID, event.Digest); err != nil {
return nil, err
}
Expand Down

0 comments on commit 05641ad

Please sign in to comment.