Skip to content

Ensure landlock works for signing entries #344

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 5 additions & 6 deletions cmd/sbctl/list-bundles.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"github.com/foxboron/sbctl/config"
"github.com/foxboron/sbctl/hierarchy"
"github.com/foxboron/sbctl/logging"
"github.com/foxboron/sbctl/lsm"
"github.com/spf13/cobra"
)

Expand All @@ -29,11 +28,11 @@ var listBundlesCmd = &cobra.Command{

logging.Errorf("The bundle/uki support in sbctl is deprecated. Please move to dracut/mkinitcpio/ukify.")

if state.Config.Landlock {
if err := lsm.Restrict(); err != nil {
return err
}
}
// if state.Config.Landlock {
// if err := lsm.Restrict(); err != nil {
// return err
// }
// }

bundles := []JsonBundle{}
var isSigned bool
Expand Down
3 changes: 2 additions & 1 deletion cmd/sbctl/sign-all.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ var signAllCmd = &cobra.Command{
Short: "Sign all enrolled files with secure boot keys",
RunE: func(cmd *cobra.Command, args []string) error {
state := cmd.Context().Value(stateDataKey{}).(*config.State)
if state.Config.Landlock {
// Don't run landlock if we are making UKIs
if state.Config.Landlock && !generate {
if err := sbctl.LandlockFromFileDatabase(state); err != nil {
return err
}
Expand Down
18 changes: 12 additions & 6 deletions cmd/sbctl/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/foxboron/sbctl/logging"
"github.com/foxboron/sbctl/lsm"
"github.com/landlock-lsm/go-landlock/landlock"
"github.com/spf13/afero"
"github.com/spf13/cobra"
)

Expand All @@ -30,27 +31,32 @@ var signCmd = &cobra.Command{
os.Exit(1)
}

var rules []landlock.Rule

// Ensure we have absolute paths
file, err := filepath.Abs(args[0])
if err != nil {
return err
}
if output == "" {
output = file
rules = append(rules, lsm.TruncFile(file).IgnoreIfMissing())
} else {
output, err = filepath.Abs(output)
if err != nil {
return err
}
// Set input file to RO and output dir/file to RW
rules = append(rules, landlock.ROFiles(file).IgnoreIfMissing())
if ok, _ := afero.Exists(state.Fs, output); ok {
rules = append(rules, lsm.TruncFile(output))
} else {
rules = append(rules, landlock.RWDirs(filepath.Dir(output)))
}
}

if state.Config.Landlock {
lsm.RestrictAdditionalPaths(
// TODO: This doesn't work quite how I want it to
// setting RWFiles to the path gets EACCES
// but setting RWDirs on the dir is fine
landlock.RWDirs(filepath.Dir(output)),
)
lsm.RestrictAdditionalPaths(rules...)
if err := lsm.Restrict(); err != nil {
return err
}
Expand Down
33 changes: 18 additions & 15 deletions database.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/foxboron/sbctl/lsm"
"github.com/landlock-lsm/go-landlock/landlock"

ll "github.com/landlock-lsm/go-landlock/landlock/syscall"
"github.com/spf13/afero"
)

Expand Down Expand Up @@ -63,28 +62,32 @@ func SigningEntryIter(state *config.State, fn func(s *SigningEntry) error) error
return nil
}

const (
// We open the file with O_TRUNC
accessFile landlock.AccessFSSet = ll.AccessFSExecute | ll.AccessFSWriteFile | ll.AccessFSReadFile | ll.AccessFSTruncate
)

func LandlockFromFileDatabase(state *config.State) error {
var llrules []landlock.Rule
files, err := ReadFileDatabase(state.Fs, state.Config.FilesDb)
if err != nil {
return err
}
for _, entry := range files {
llrules = append(llrules,
landlock.PathAccess(accessFile, entry.File),
)
if entry.File == entry.OutputFile {
// If file is the same as output, set RW+Trunc on file
llrules = append(llrules,
lsm.TruncFile(entry.File).IgnoreIfMissing(),
)
}
if entry.File != entry.OutputFile {
// We do an RWDirs on the directory and a RWFiles on the file itself. it
// should be noted that the output file might not exist at this time
llrules = append(llrules, landlock.RWDirs(
filepath.Dir(entry.File),
),
landlock.RWFiles(entry.File).IgnoreIfMissing())
// Set input file to RO, ignore if missing so we can bubble a useable
// error to the user
llrules = append(llrules, landlock.ROFiles(entry.File).IgnoreIfMissing())

// Check if output file exists
// if it does we set RW on the file directly
// if it doesnt, we set RW on the directory
if ok, _ := afero.Exists(state.Fs, entry.OutputFile); ok {
llrules = append(llrules, lsm.TruncFile(entry.OutputFile))
} else {
llrules = append(llrules, landlock.RWDirs(filepath.Dir(entry.OutputFile)))
}
}
}
lsm.RestrictAdditionalPaths(llrules...)
Expand Down
9 changes: 9 additions & 0 deletions lsm/lsm.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,21 @@ import (

"github.com/foxboron/sbctl/config"
"github.com/landlock-lsm/go-landlock/landlock"

ll "github.com/landlock-lsm/go-landlock/landlock/syscall"
)

var (
rules []landlock.Rule

// Include file truncation
truncFile landlock.AccessFSSet = ll.AccessFSExecute | ll.AccessFSWriteFile | ll.AccessFSReadFile | ll.AccessFSTruncate
)

func TruncFile(p string) landlock.FSRule {
return landlock.PathAccess(truncFile, p)
}

func LandlockRulesFromConfig(conf *config.Config) {
rules = append(rules,
landlock.RODirs(
Expand Down
Loading