From b5ef5a03b67a10017d184134eb95f4cb3867ba38 Mon Sep 17 00:00:00 2001 From: Seth Hoenig Date: Sat, 1 Apr 2023 20:34:44 -0500 Subject: [PATCH] lock: add OnlyAvailable locking mode This PR adds the OnlyAvailable locking mode for cases where we just want to attempt to lock (with errors) in cases where landlock is actually detected to be available. Useful for running on kernels where landlock may or may not be enabled and we don't really care. --- landlock.go | 12 ++++++++++-- landlock_default.go | 2 ++ landlock_linux.go | 14 +++++++++++--- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/landlock.go b/landlock.go index 653992d..50a6a03 100644 --- a/landlock.go +++ b/landlock.go @@ -19,10 +19,18 @@ const ( // systems where landlock is not supported. Mandatory Safety = iota - // OnlySupported will return an error on failure if running - // on a supported operating system, or no error otherwise + // OnlySupported will return an error on failure if running on a supported + // operating system (Linux), or no error otherwise. Unlike OnlyAvailable, + // this includes returning an error on systems where the Linux kernel was + // built without landlock support. OnlySupported + // OnlyAvailable will return an error on failure if running in an environment + // where landlock is detected and available, or no error otherwise. Unlike + // OnlySupported, OnlyAvailable does not cause an error on Linux systems built + // without landlock support. + OnlyAvailable + // Try mode will continue with no error on failure. Try ) diff --git a/landlock_default.go b/landlock_default.go index b4ad7e4..af0ae1c 100644 --- a/landlock_default.go +++ b/landlock_default.go @@ -24,6 +24,8 @@ func New(...*Path) Locker { func (l *locker) Lock(s Safety) error { switch s { + case OnlyAvailable: + return nil case OnlySupported: return nil case Try: diff --git a/landlock_linux.go b/landlock_linux.go index 3cdacb2..d06b42c 100644 --- a/landlock_linux.go +++ b/landlock_linux.go @@ -11,6 +11,11 @@ import ( "golang.org/x/sys/unix" ) +var ( + ErrLandlockNotAvailable = errors.New("landlock not available") + ErrLandlockFailedToLock = errors.New("landlock failed to lock") +) + type locker struct { paths *set.HashSet[*Path, string] } @@ -42,12 +47,15 @@ func New(paths ...*Path) Locker { } func (l *locker) Lock(s Safety) error { - if !available && s != Try { - return errors.New("landlock not available") + if !available { + if s == Try || s == OnlyAvailable { + return nil + } + return ErrLandlockNotAvailable } if err := l.lock(); err != nil && s != Try { - return fmt.Errorf("landlock failed to lock: %w", err) + return errors.Join(ErrLandlockFailedToLock, err) } return nil