SYD-LOCK(1)

# NAME

*syd-lock* - Run a program under _landlock_(7)

# SYNOPSIS

*syd-lock* _[-bchrvwASUV]_ _[-C level]_ _[-E errata]_ _[-F flag]_... _[-l category[,category...]{+|-}path|port[-port]]..._  _{command [args...]}_

# DESCRIPTION

*syd-lock* utility runs a program under _landlock_(7). The program is
confined by the given _landlock_(7) categories. Supported categories are
_read_, _write_, _exec_, _ioctl_, _create_, _delete_, _rename_,
_symlink_, _truncate_, _readdir_, _mkdir_, _rmdir_, _mkbdev_, _mkcdev_,
_mkfifo_, _bind_, and _connect_. Categories other than _bind_ and
_connect_ must specify paths to be confined. Both absolute and relative
paths are permitted. Path must not contain magic symbolic links or
parent ("..") components. Path is permitted to contain regular symbolic
links. These regular symbolic symlinks are permitted to resolve to
targets with parent ("..") components in them. Categories _bind_ and
_connect_ must specify a network port or closed port range separated by
dash. Zero is a valid port number to confine binds and connects to
ephemeral ports. _bind_ category also supports absolute UNIX domain
socket paths to confine their creation via _mknod_(2). For full details
and specific behavior of each _landlock_(7) category, refer to the
*Sandboxing* and *Lock Sandboxing* sections of the _syd_(7) manual page.

# OPTIONS

|[ *-h*
:< Display help.
|[ *-v*
:< Be verbose. Print _landlock_(7) status to _stderr_(3) before running the program.
|[ *-V*
:< Print _landlock_(7) ABI version on _stdout_(3).
|[ *-A*
:< Print _landlock_(7) ABI version on _stdout_(3) and exit with it as exit code. Use for scripting.
|[ *-l* _cat[,cat...]{+|-}path|port[-port]_
:< Add or remove a _landlock_(7) rule with categories and an associated resource (path or port), may be repeated.
|[
:< Join categories and resource by either a "*+*" (plus) for add or a "*-*" (minus) for remove.
|[
:< Resource must be a path for all categories except _bind_ and _connect_.
|[
:< Resource must be a port or a dash-delimited closed port range for _bind_ and _connect_.
|[
:< Resource may also be a UNIX domain socket path for _bind_ to confine _mknod_(2) with *S_IFSOCK*.
|[
:< Both absolute and relative paths are permitted for all categories except _bind_ which requires an absolute path.
|[
:< Paths are stored as hash sets and ports as fixed bit sets to make stacking options simple and predictable.
|[ *-C* _level_
:< Set _landlock_(7) compatibility level. Must be one of _hard-requirement_, _soft-requirement_, and _best-effort_.
|[
:< Default is _hard-requirement_ to adhere to the principle of secure defaults.
|[
:< Level can be given shortly as _hard_ (or _h_), _soft_ (or _s_) and _best_ (or _b_).
|[ *-E* _errata_
:< Query supported _landlock_(7) errata fixes. Use _-E list_ to print list of known erratas.
|[
:< The argument may be a name or number. Use a number to query undefined erratas.
|[
:< Multiple erratas may be specified split by commas.
|[ *-F* _flags_
:< Set _landlock_restrict_self_(2) flags. Use _-F list_ to print a list of flags.
|[
:< See the FLAGS section for information on flags and their functionality.
|[ *-S*
:< Enable scoped signals introduced with _landlock_(7) ABI 6.
|[ *-U*
:< Enable scoped UNIX abstract sockets introduced with _landlock_(7) ABI 6.
|[ *-r* _path_
:< Specify a read-only path, may be repeated. Equivalent to _-l read,readdir,exec,ioctl+path_.
|[ *-w* _path_
:< Specify a read-write path, may be repeated. Equivalent to _-l all+path_.
|[ *-b* _port[-port]_
:< Specify a port for _bind_(2), may be repeated. Equivalent to _-l bind+port_.
|[ *-c* _port[-port]_
:< Specify a port for _connect_(2), may be repeated. Equivalent to _-l connect+port_.

# CONFIGURATION

_landlock_(7) categories and their associated resources (paths or ports)
are given with the _-l_ option. This option accepts a comma separated
list of categories, followed by either a "_+_" (plus) or a "_-_" (minus)
symbol indicating to add or remove the given rule. Rulesets store paths
as hash sets and ports as fixed bit sets to allow for simple and
predictable stacking of multiple _-l_ options. Use _-V_ option to check
for _landlock_(7) support in the Linux kernel. The specific support
level may be determined by the exit code. Use _-A_ option to check for
_landlock_(7) ABI version.

## ABI

_landlock_(7) ABI versioning makes it possible to adjust the security
policy according to kernel capabilities. *syd-lock* has support for
_landlock_(7) ABI 7 which is new in Linux-6.15. See the *HISTORY*
section for information on when each _landlock_(7) ABI was introduced to
the Linux kernel.

## SETS

As of version 3.38.0, multiple categories may be specified split by
commas and the following sets are defined to simplify sandbox profile
composition. Names are intentionally chosen to be consistent with
OpenBSD's _pledge_(2):

|[ *all*
:< All filesystem access rights
|[ *all-x*
:< All filesystem access rights except *exec*
|[ *rpath*
:< read, readdir
|[ *wpath*
:< write, truncate
|[ *cpath*
:< create, delete, rename
|[ *dpath*
:< mkbdev, mkcdev
|[ *spath*
:< mkfifo, symlink
|[ *tpath*
:< mkdir, rmdir
|[ *inet*
:< bind, connect

## COMPATIBILITY LEVELS

As of version 3.35.0, _landlock_(7) compatibility level may be set using
the _-C_ option to one of the following levels: _hard-requirement_, or
just _hard_ or _h_, _soft-requirement_, or just _short_ or _s_, and
_best-effort_, or just _best_ or _b_. Default is _hard-requirement_ to
adhere to the principle of secure defaults. In this level the requested
_landlock_(7) restrictions are taken into account only if they are
supported by the running system; if any requested feature is not
supported, the operation returns a compatibility error and the sandbox
is not entered. File _open_(2) errors during sandbox setup, including
the ENOENT ("No such file or directory") _errno_(3), return a fatal
error in this level. In _soft-requirement_ level the requested
restrictions are taken into account if they are supported by the running
system, or the entire sandboxing request is silently ignored otherwise;
no compatibility error is returned. In _best-effort_ level the requested
restrictions are taken into account if they are supported by the running
system, and any unsupported restrictions are silently ignored; no
compatibility error is returned. In _soft-requirement_ and _best-effort_
levels file _open_(2) errors with the ENOENT ("No such file or
directory") _errno_(3) are silently ignored. Other file _open_(2) errors
are fatal.

## FLAGS

As of version 3.38.0, _landlock_(7) flags may be set using the _-F_
option. Flags may be specified using their names or numerical values.
Multiple flags may be set at once by specifying them as a
comma-separated list. Flags are supported beginning with _landlock_(7)
ABI 7 which is new in Linux-6.15. List of supported flags are given
below. Setting a flag on an unsupported ABI is a NO-OP unless otherwise
noted.

[[ *log_same_exec_off*
:< *1*: Disables logging of denied accesses originating
   from the thread creating the _landlock_(7) domain, as well as its
   children, as long as they continue running the same executable code
   (i.e., without an intervening _execve_(2) call). This is intended for
   programs that execute unknown code without invoking _execve_(2), such as
   script interpreters. Programs that only sandbox themselves should not
   set this flag, so users can be notified of unauthorized access attempts
   via system logs. This flag requires _landlock_(7) ABI 7 support which is
   new in Linux-6.15.
|[ *log_new_exec_on*
:< *2*: Enables logging of denied accesses after an _execve_(2) call, providing
   visibility into unauthorized access attempts by newly executed programs
   within the created _landlock_(7) domain. This flag is recommended only
   when all potential executables in the domain are expected to comply with
   the access restrictions, as excessive audit log entries could make it
   more difficult to identify critical events. This flag requires
   _landlock_(7) ABI 7 support which is new in Linux-6.15.
|[ *log_subdomains_off*
:< *4*: Disables logging of denied accesses originating from nested
   _landlock_(7) domains created by the caller or its descendants. This
   flag should be set according to runtime configuration, not hardcoded, to
   avoid suppressing important security events. It is useful for container
   runtimes or sandboxing tools that may launch programs which themselves
   create _landlock_(7) domains and could otherwise generate excessive
   logs. Unlike *log_same_exec_off*, this flag only affects future
   nested domains, not the one being created. This flag requires
   _landlock_(7) ABI 7 support which is new in Linux-6.15.

# SECURITY

As of version 3.35.0, the default _landlock_(7) compatibility level has been
changed from _best-effort_ to _hard-requirement_, and _ENOENT_ (_No
such file or directory_) errors are made fatal unless level is set to
_best-effort_. This adheres to the principle of secure defaults and
above all avoids the silent and dangerous trap where a non-existing file
or directory which had been denied access (and skipped) at startup is
created after and _landlock_(7) ends up allowing access to the newly
created file or directory. For more information, see:
https://landlock.io/rust-landlock/landlock/trait.Compatible.html

As of version 3.46.0, path must not contain magic symbolic links or
parent ("..") components. Path is permitted to contain regular symbolic
links. These regular symbolic symlinks are permitted to resolve to
targets with parent ("..") components in them. _bind_ category requires
absolute UNIX socket paths. Path may be relative for other categories in
which case it is resolved relative to the directory where _syd-lock_(1)
was executed.

Consider combining _syd-lock_(1) use with _syd-mdwe_(1) to get W^X
memory protections. See _syd-mdwe_(1) manual page for more information.

# HISTORY

- 1st _landlock_(7) ABI was introduced with Linux-5.13.
- 2nd _landlock_(7) ABI was introduced with Linux-5.19.
- 3rd _landlock_(7) ABI was introduced with Linux 6.2.
- 4th _landlock_(7) ABI was introduced with Linux 6.7.
- 5th _landlock_(7) ABI was introduced with Linux 6.10.
- 6th _landlock_(7) ABI was introduced with Linux 6.12.
- 7th _landlock_(7) ABI was introduced with Linux 6.15.

Refer to the following links for more information:

- https://git.kernel.org/stable/c/17ae69aba89dbfa2139b7f8024b757ab3cc42f59
- https://git.kernel.org/stable/c/cb44e4f061e16be65b8a16505e121490c66d30d0
- https://git.kernel.org/stable/c/299e2b1967578b1442128ba8b3e86ed3427d3651
- https://git.kernel.org/stable/c/136cc1e1f5be75f57f1e0404b94ee1c8792cb07d
- https://git.kernel.org/stable/c/2fc0e7892c10734c1b7c613ef04836d57d4676d5
- https://git.kernel.org/stable/c/e1b061b444fb01c237838f0d8238653afe6a8094
- https://git.kernel.org/stable/c/72885116069abdd05c245707c3989fc605632970

# EXIT STATUS

*syd-lock* exits with the same code as the child process on clean exit.
On unclean termination, exit code is set to 128 plus signal number. In
case executing the child process fails _syd-lock_(1) exits with the
_errno_(3) number. _syd-lock -A_ exits with the _landlock_(7) ABI
version as exit code.

_syd-lock -E_ exits with one of the following exit codes:

|[ *0*
:< All erratas are available.
|[ *1*
:< Some erratas are not available.
|[ *2*
:< No erratas are available.

_syd-lock -V_ exits with one of the following exit codes based on
support for the latest _landlock_(7) ABI:

|[ *0*
:< Fully enforced
|[ *1*
:< Partially enforced
|[ *2*
:< Not enforced
|[ *127*
:< Not supported

*syd-lock* exits with *22* (EINVAL) for invalid CLI arguments.

# EXAMPLES

```
$ syd-lock wget -O/dev/null chesswob.org
$ syd-lock -l read,exec+/ wget -O/dev/null chesswob.org
/dev/null: Permission denied
$ syd-lock -l read,exec+/ -l write+/dev/null wget -O/dev/null chesswob.org
Prepended http:// to 'chesswob.org'
--2025-04-30 16:24:35--  http://chesswob.org/
Resolving chesswob.org (chesswob.org)... 95.216.39.164, fe80::468a:5bff:fe88:2141
Connecting to chesswob.org (chesswob.org)|95.216.39.164|:80... failed: Permission denied.
Connecting to chesswob.org (chesswob.org)|fe80::468a:5bff:fe88:2141|:80... failed: Permission denied.
Retrying.

^C
$ syd-lock -l read,exec+/ -l write+/dev/null -l connect+80 -l connect+443 wget -O/dev/null chesswob.org
Prepended http:// to 'chesswob.org'
--2025-04-30 16:25:59--  http://chesswob.org/
Resolving chesswob.org (chesswob.org)... 95.216.39.164, fe80::468a:5bff:fe88:2141
Connecting to chesswob.org (chesswob.org)|95.216.39.164|:80... connected.
HTTP request sent, awaiting response... 302 Moved Temporarily
Location: https://www.chesswob.org/ [following]
--2025-04-30 16:25:59--  https://www.chesswob.org/
Loaded CA certificate '/etc/ssl/certs/ca-certificates.crt'
Resolving www.chesswob.org (www.chesswob.org)... 95.216.39.164, fe80::468a:5bff:fe88:2141
Connecting to www.chesswob.org (www.chesswob.org)|95.216.39.164|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 148827 (145K) [text/html]
Saving to: ‘/dev/null’

/dev/null                         100%[=============================================================>] 145.34K  --.-KB/s    in 0.01s

2025-04-30 16:25:59 (11.9 MB/s) - ‘/dev/null’ saved [148827/148827]
$
```

# SEE ALSO

_landlock_(7), _syd_(1), _syd_(2), _syd_(5), _syd_(7), _syd-mdwe_(1),
_syd-ofd_(1), _syd-pds_(1), _syd-sec_(1), _syd_tsc_(1)

*syd* homepage: https://sydbox.exherbo.org/

Landlock homepage: https://landlock.io/

Landlock documentation: https://docs.kernel.org/userspace-api/landlock.html

Landlock admin guide: https://docs.kernel.org/admin-guide/LSM/landlock.html

# AUTHORS

Maintained by Ali Polatel. Up-to-date sources can be found at
https://gitlab.exherbo.org/sydbox/sydbox.git and bugs/patches can be
submitted to https://gitlab.exherbo.org/groups/sydbox/-/issues. Discuss
in #sydbox on Libera Chat or in #sydbox:mailstation.de on Matrix.
