landlock-0.2.1.1: Haskell bindings for the Linux Landlock API
Copyright(c) Nicolas Trangez 2022
LicenseBSD-3-Clause
Maintainerikke@nicolast.be
Stabilityalpha
PortabilityLinux
Safe HaskellSafe-Inferred
LanguageHaskell2010

System.Landlock

Description

This library exposes Haskell bindings for the Linux kernel Landlock API.

The Linux kernel Landlock API provides unprivileged access control. The goal of Landlock is to enable to restrict ambient rights (e.g. global filesystem access) for a set of processes. Because Landlock is a stackable LSM, it makes possible to create safe security sandboxes as new security layers in addition to the existing system-wide access-controls. This kind of sandbox is expected to help mitigate the security impact of bugs or unexpected/malicious behaviors in user space applications. Landlock empowers any process, including unprivileged ones, to securely restrict themselves.

For more information, see the Landlock homepage, its kernel documentation and its manual page.

Synopsis

Core API

Use landlock to sandbox a process.

Example usage:

-- Retrieve the Landlock ABI version
abi <- abiVersion

-- Calculate access flag sets
-- Note: in production code, find the highest matching version or similar
let Just flags = lookup abi accessFsFlags
    readOnlyFlags = filter accessFsFlagIsReadOnly flags

-- Sandbox the process
landlock (RulesetAttr flags) [] [] $ \addRule -> do
    -- Allow read-only access to the /usr hierarchy
    withOpenPath "/usr" defaultOpenPathFlags{ directory = True } $ \fd ->
        addRule (pathBeneath fd readOnlyFlags) []

    -- Allow read access to my public key
    withOpenPath "/home/nicolas/.ssh/id_ed25519.pub" defaultOpenPathFlags $ \fd ->
        addRule (pathBeneath fd [AccessFsReadFile]) []

withFile "/home/nicolas/.ssh/id_ed25519.pub" ReadMode (\fd -> putStrLn "Success")
-- Success

withFile "/usr/bin/ghc" ReadMode (\fd -> putStrLn "Success")
-- Success

openFile "/home/nicolas/.ssh/id_ed25519" ReadMode
-- *** Exception: /home/nicolas/.ssh/id_ed25519: openFile: permission denied (Permission denied)

landlock Source #

Arguments

:: (MonadMask m, MonadIO m) 
=> RulesetAttr

Ruleset attribute passed to landlock_create_ruleset.

-> [CreateRulesetFlag]

Flags passed to landlock_create_ruleset. Since no flags but CreateRulesetVersion (LANDLOCK_CREATE_RULESET_VERSION) are defined, and this flag must not be used when creating an actual ruleset, this should be an empty list.

-> [RestrictSelfFlag]

Flags passed to landlock_restrict_self. Since no flags are defined, this should be an empty list.

-> ((Storable (Rule r) => Rule r -> [AddRuleFlag] -> m ()) -> m a)

Action that will be called before the Landlock sandbox is enforced. The provided function can be used to register sandboxing rules (internally using landlock_add_rule), given a Rule and a set of AddRuleFlags. However, since no flags are currently defined, this should be an empty list.

-> m a

Result of the given action.

Apply a Landlock sandbox to the current process.

The provided action can be used to register Landlock Rules on the given instance (see addRule).

Once this returns, the Landlock sandbox will be in effect (see landlock_restrict_self), and no privileged processes can be spawned (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) has been invoked).

Warning: calling this on a system without Landlock support, or with Landlock disabled, will result in an exception.

data RulesetAttr Source #

Ruleset attributes.

This represents a struct landlock_ruleset_attr as passed to landlock_create_ruleset.

Constructors

RulesetAttr 

Fields

Instances

Instances details
Show RulesetAttr Source # 
Instance details

Defined in System.Landlock

Eq RulesetAttr Source # 
Instance details

Defined in System.Landlock

Filesystem Access Flags

Filesystem access flags to sandbox filesystem access.

data AccessFsFlag #

Filesystem flags.

These flags enable to restrict a sandboxed process to a set of actions on files and directories. Files or directories opened before the sandboxing are not subject to these restrictions.

A file can only receive these access rights:

A directory can receive access rights related to files or directories. The following access right is applied to the directory itself, and the directories beneath it:

However, the following access rights only apply to the content of a directory, not the directory itself:

Warning: It is currently not possible to restrict some file-related actions acessible through these syscall families: chdir, stat, flock, chmod, chown, setxattr, utime, ioctl, fcntl, access. Future Landlock evolutions will enable to restrict them.

Constructors

AccessFsExecute

Execute a file (LANDLOCK_ACCESS_FS_EXECUTE).

AccessFsWriteFile

Open a file with write access (LANDLOCK_ACCESS_FS_WRITE_FILE).

Note that you might additionally need the LANDLOCK_ACCESS_FS_TRUNCATE right in order to overwrite files with open using O_TRUNC or creat.

AccessFsReadFile

Open a file with read access (LANDLOCK_ACCESS_FS_READ_FILE).

AccessFsReadDir

Open a directory or list its content (LANDLOCK_ACCESS_FS_READ_DIR).

AccessFsRemoveDir

Remove an empty directory or rename one (LANDLOCK_ACCESS_FS_REMOVE_DIR).

AccessFsRemoveFile

Unlink (or rename) a file (LANDLOCK_ACCESS_FS_REMOVE_FILE).

AccessFsMakeChar

Create (or rename or link) a character device (LANDLOCK_ACCESS_FS_MAKE_CHAR).

AccessFsMakeDir

Create (or rename) a directory (LANDLOCK_ACCESS_FS_MAKE_DIR).

AccessFsMakeReg

Create (or rename or link) a regular file (LANDLOCK_ACCESS_FS_MAKE_REG).

AccessFsMakeSock

Create (or rename or link) a UNIX domain socket (LANDLOCK_ACCESS_FS_MAKE_SOCK).

AccessFsMakeFifo

Create (or rename or link) a named pipe (LANDLOCK_ACCESS_FS_MAKE_FIFO).

AccessFsMakeBlock

Create (or rename or link) a block device (LANDLOCK_ACCESS_FS_MAKE_BLOCK).

AccessFsMakeSym

Create (or rename or link) a symbolic link (LANDLOCK_ACCESS_FS_MAKE_SYM).

AccessFsRefer

Link or rename a file from or to a different directory (i.e. reparent a file hierarchy). This access right is available since the second version of the Landlock ABI. This is also the only access right which is always considered handled by any ruleset in such a way that reparenting a file hierarchy is always denied by default. To avoid privilege escalation, it is not enough to add a rule with this access right. When linking or renaming a file, the destination directory hierarchy must also always have the same or a superset of restrictions of the source hierarchy. If it is not the case, or if the domain doesn't handle this access right, such actions are denied by default with errno set to EXDEV. Linking also requires a LANDLOCK_ACCESS_FS_MAKE_* access right on the destination directory, and renaming also requires a LANDLOCK_ACCESS_FS_REMOVE_* access right on the source's (file or directory) parent. Otherwise, such actions are denied with errno set to EACCES. The EACCES errno prevails over EXDEV to let user space efficiently deal with an unrecoverable error.

AccessFsTruncate

Truncate a file with truncate, ftruncate, creat, or open with O_TRUNC. Whether an opened file can be truncated with ftruncate is determined during open, in the same way as read and write permissions are checked during open using LANDLOCK_ACCESS_FS_READ_FILE and LANDLOCK_ACCESS_FS_WRITE_FILE. This access right is available since the third version of the Landlock ABI.

accessFsFlags :: [(Version, [AccessFsFlag])] #

All AccessFsFlag flags keyed by a Landlock ABI Version.

accessFsFlagIsReadOnly :: AccessFsFlag -> Bool #

Predicate for read-only AccessFsFlag flags.

Sandboxing Rules

Sandboxing rules to apply.

data Rule (a :: RuleType) #

A rule enforced by Landlock, to be registered using addRule.

Rules can be constructed using the relevant functions, like pathBeneath.

Instances

Instances details
Storable (Rule 'PathBeneath) 
Instance details

Defined in System.Landlock.Rules

Show (Rule a) 
Instance details

Defined in System.Landlock.Rules

Methods

showsPrec :: Int -> Rule a -> ShowS #

show :: Rule a -> String #

showList :: [Rule a] -> ShowS #

Eq (Rule a) 
Instance details

Defined in System.Landlock.Rules

Methods

(==) :: Rule a -> Rule a -> Bool #

(/=) :: Rule a -> Rule a -> Bool #

pathBeneath #

Arguments

:: Fd

File descriptor, preferably opened with O_PATH, which identifies the parent directory of a file hierarchy, or just a file.

-> [AccessFsFlag]

Allowed actions for this file hierarchy (cf. AccessFsFlag).

-> Rule 'PathBeneath 

Construct a path hierarchy rule definition.

This corresponds to a rule of type LANDLOCK_RULE_PATH_BENEATH, with attributes defined in a struct landlock_path_beneath_attr.

Utility Functions

Various utility functions.

isSupported :: IO Bool Source #

Check whether Landlock is supported and enabled on the running system.

This calls abiVersion, catching relevant exceptions to return False when applicable.

Landlock ABI Version

Retrieve and handle the kernel's Landlock ABI version.

abiVersion :: IO Version Source #

Retrieve the Landlock ABI version of the running system.

This invokes landlock_create_ruleset with the LANDLOCK_CREATE_RULESET_VERSION option.

Warning: calling this on a system without Landlock support, or with Landlock disabled, will result in an exception.

data Version #

Representation of a Landlock ABI version as reported by the kernel.

Instances

Instances details
Show Version 
Instance details

Defined in System.Landlock.Version

Eq Version 
Instance details

Defined in System.Landlock.Version

Methods

(==) :: Version -> Version -> Bool #

(/=) :: Version -> Version -> Bool #

Ord Version 
Instance details

Defined in System.Landlock.Version

getVersion :: Version -> Word #

Get the numerical version.

version1 :: Version #

ABI version 1.

version2 :: Version #

ABI version 2.

version3 :: Version #

ABI version 3.

Opening paths using O_PATH

When creating a pathBeneath rule, a file descriptor to a directory or file is needed. These can be safely opened using the O_PATH flag using the following functions.

withOpenPath #

Arguments

:: (MonadIO m, MonadMask m) 
=> FilePath

Path to open.

-> OpenPathFlags

Flag settings to pass.

-> (Fd -> m a)

Action to call with a file descriptor to the given path.

-> m a

Result of the invoked action.

Perform an action with a path opened using O_PATH.

The file descriptor provided to the action will be closed when the function returns.

This internally calls openat with AT_FDCWD and the O_PATH and O_RDONLY flags set, next to any flags specified in the OpenPathFlags argument.

withOpenPathAt #

Arguments

:: (MonadIO m, MonadMask m) 
=> Fd

dirfd argument to openat.

-> FilePath

Path to open.

-> OpenPathFlags

Flag settings to pass.

-> (Fd -> m a)

Action to call with a file descriptor to the given path.

-> m a

Result of the invoked action.

Perform an action with a path openated using O_PATH.

Like withOpenPath, exposing the openat dirfd argument.

The file descriptor provided to the action will be closed when the function returns.

This internally calls openat with the O_PATH and O_RDONLY flags set, next to any flags specified in the OpenPathFlags argument.

data OpenPathFlags #

Extra flags used by withOpenPathAt in the call to openat.

Instances

Instances details
Show OpenPathFlags 
Instance details

Defined in System.Landlock.OpenPath

Eq OpenPathFlags 
Instance details

Defined in System.Landlock.OpenPath