dwww Home | Manual pages | Find package

Landlock(7)             Miscellaneous Information Manual            Landlock(7)

NAME
       Landlock - unprivileged access-control

DESCRIPTION
       Landlock  is  an access-control system that enables any processes to se-
       curely restrict themselves and their future children.  Because  Landlock
       is a stackable Linux Security Module (LSM), it makes it possible to cre-
       ate  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, and unexpected or mali-
       cious behaviors in applications.

       A Landlock security policy is a set of access rights (e.g., open a  file
       in  read-only,  make a directory, etc.)  tied to a file hierarchy.  Such
       policy can be configured and enforced by processes for themselves  using
       three system calls:

       •  landlock_create_ruleset(2) creates a new ruleset;

       •  landlock_add_rule(2) adds a new rule to a ruleset;

       •  landlock_restrict_self(2) enforces a ruleset on the calling thread.

       To  be  able  to use these system calls, the running kernel must support
       Landlock and it must be enabled at boot time.

   Landlock rules
       A Landlock rule describes an action on an object.   An  object  is  cur-
       rently  a file hierarchy, and the related filesystem actions are defined
       with access rights (see landlock_add_rule(2)).  A set of rules is aggre-
       gated in a ruleset, which can then restrict the thread enforcing it, and
       its future children.

   Filesystem actions
       These flags enable to restrict a sandboxed process to a set  of  actions
       on  files and directories.  Files or directories opened before the sand-
       boxing are not subject to these restrictions.  See  landlock_add_rule(2)
       and landlock_create_ruleset(2) for more context.

       A file can only receive these access rights:

       LANDLOCK_ACCESS_FS_EXECUTE
              Execute a file.

       LANDLOCK_ACCESS_FS_WRITE_FILE
              Open a file with write access.

              When  opening files for writing, you will often additionally need
              the LANDLOCK_ACCESS_FS_TRUNCATE right.  In many cases, these sys-
              tem calls truncate existing files when  overwriting  them  (e.g.,
              creat(2)).

       LANDLOCK_ACCESS_FS_READ_FILE
              Open a file with read access.

       LANDLOCK_ACCESS_FS_TRUNCATE
              Truncate  a  file  with  truncate(2),  ftruncate(2), creat(2), or
              open(2) with O_TRUNC.  Whether an opened file  can  be  truncated
              with  ftruncate(2)  is determined during open(2), in the same way
              as read and write permissions are checked  during  open(2)  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.

       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:

       LANDLOCK_ACCESS_FS_READ_DIR
              Open a directory or list its content.

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

       LANDLOCK_ACCESS_FS_REMOVE_DIR
              Remove an empty directory or rename one.

       LANDLOCK_ACCESS_FS_REMOVE_FILE
              Unlink (or rename) a file.

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

       LANDLOCK_ACCESS_FS_MAKE_DIR
              Create (or rename) a directory.

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

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

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

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

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

       LANDLOCK_ACCESS_FS_REFER
              Link or rename a file from or to a different directory (i.e., re-
              parent a file hierarchy).

              This access right is available since the second  version  of  the
              Landlock ABI.

              This  is  the only access right which is denied by default by any
              ruleset, even if the right is not specified as handled at ruleset
              creation time.  The only way to make a ruleset grant  this  right
              is  to  explicitly  allow it for a specific directory by adding a
              matching rule to the ruleset.

              In particular, when using the first Landlock ABI  version,  Land-
              lock  will always deny attempts to reparent files between differ-
              ent directories.

              In addition to the source and destination directories having  the
              LANDLOCK_ACCESS_FS_REFER  access right, the attempted link or re-
              name operation must meet the following constraints:

              •  The reparented file may not gain more  access  rights  in  the
                 destination directory than it previously had in the source di-
                 rectory.   If  this  is attempted, the operation results in an
                 EXDEV error.

              •  When linking or renaming, the LANDLOCK_ACCESS_FS_MAKE_*  right
                 for  the respective file type must be granted for the destina-
                 tion directory.  Otherwise, the operation results in an EACCES
                 error.

              •  When renaming, the LANDLOCK_ACCESS_FS_REMOVE_* right  for  the
                 respective file type must be granted for the source directory.
                 Otherwise, the operation results in an EACCES error.

              If multiple requirements are not met, the EACCES error code takes
              precedence over EXDEV.

   Layers of file path access rights
       Each time a thread enforces a ruleset on itself, it updates its Landlock
       domain with a new layer of policy.  Indeed, this complementary policy is
       composed  with  the  potentially other rulesets already restricting this
       thread.  A sandboxed thread can then safely add more constraints to  it-
       self with a new enforced ruleset.

       One  policy  layer  grants  access to a file path if at least one of its
       rules encountered on the path grants the access.  A sandboxed thread can
       only access a file path if all its enforced policy layers grant the  ac-
       cess  as  well as all the other system access controls (e.g., filesystem
       DAC, other LSM policies, etc.).

   Bind mounts and OverlayFS
       Landlock enables restricting access to  file  hierarchies,  which  means
       that  these  access  rights  can  be  propagated  with  bind mounts (cf.
       mount_namespaces(7)) but not with OverlayFS.

       A bind mount mirrors a source file hierarchy to a destination.  The des-
       tination hierarchy is then composed of the exact same  files,  on  which
       Landlock  rules  can  be  tied, either via the source or the destination
       path.  These rules restrict access when they are encountered on a  path,
       which  means  that they can restrict access to multiple file hierarchies
       at the same time, whether these  hierarchies  are  the  result  of  bind
       mounts or not.

       An OverlayFS mount point consists of upper and lower layers.  These lay-
       ers  are combined in a merge directory, result of the mount point.  This
       merge hierarchy may include files from the upper and lower  layers,  but
       modifications performed on the merge hierarchy only reflect on the upper
       layer.  From a Landlock policy point of view, each of the OverlayFS lay-
       ers  and  merge  hierarchies  is  standalone and contains its own set of
       files and directories, which is different from a bind mount.   A  policy
       restricting an OverlayFS layer will not restrict the resulted merged hi-
       erarchy,  and  vice  versa.  Landlock users should then only think about
       file hierarchies they want to allow access to, regardless of the  under-
       lying filesystem.

   Inheritance
       Every  new thread resulting from a clone(2) inherits Landlock domain re-
       strictions from its parent.  This is similar to the  seccomp(2)  inheri-
       tance  or  any  other  LSM  dealing with tasks' credentials(7).  For in-
       stance, one process's thread may apply Landlock  rules  to  itself,  but
       they  will not be automatically applied to other sibling threads (unlike
       POSIX thread credential changes, cf.  nptl(7)).

       When a thread sandboxes itself, we have the guarantee that  the  related
       security  policy  will  stay  enforced on all this thread's descendants.
       This allows creating standalone and modular security policies per appli-
       cation, which will automatically be composed between themselves  accord-
       ing to their run-time parent policies.

   Ptrace restrictions
       A sandboxed process has less privileges than a non-sandboxed process and
       must  then  be  subject to additional restrictions when manipulating an-
       other process.  To be allowed to use ptrace(2) and related syscalls on a
       target process, a sandboxed process should have a subset of  the  target
       process  rules,  which  means  the tracee must be in a sub-domain of the
       tracer.

   Truncating files
       The operations covered by LANDLOCK_ACCESS_FS_WRITE_FILE and LANDLOCK_AC-
       CESS_FS_TRUNCATE both change the contents of a file and sometimes  over-
       lap  in non-intuitive ways.  It is recommended to always specify both of
       these together.

       A particularly surprising example is creat(2).  The name  suggests  that
       this  system  call  requires the rights to create and write files.  How-
       ever, it also requires the truncate right if an existing file under  the
       same name is already present.

       It should also be noted that truncating files does not require the LAND-
       LOCK_ACCESS_FS_WRITE_FILE  right.   Apart  from  the  truncate(2) system
       call,  this  can  also  be  done  through   open(2)   with   the   flags
       O_RDONLY | O_TRUNC.

       When opening a file, the availability of the LANDLOCK_ACCESS_FS_TRUNCATE
       right  is  associated with the newly created file descriptor and will be
       used for subsequent truncation attempts using ftruncate(2).  The  behav-
       ior  is  similar to opening a file for reading or writing, where permis-
       sions are checked during open(2), but not during the subsequent  read(2)
       and write(2) calls.

       As  a consequence, it is possible to have multiple open file descriptors
       for the same file, where one grants the right to truncate the  file  and
       the  other  does not.  It is also possible to pass such file descriptors
       between processes, keeping their Landlock properties,  even  when  these
       processes do not have an enforced Landlock ruleset.

VERSIONS
       Landlock was introduced in Linux 5.13.

       To  determine  which Landlock features are available, users should query
       the Landlock ABI version:
       ┌─────┬────────┬───────────────────────────────────────────────────────┐
       │ ABI Kernel Newly introduced access rights                        │
       ├─────┼────────┼───────────────────────────────────────────────────────┤
       │  1  │  5.13  │ LANDLOCK_ACCESS_FS_EXECUTE                            │
       │     │        │ LANDLOCK_ACCESS_FS_WRITE_FILE                         │
       │     │        │ LANDLOCK_ACCESS_FS_READ_FILE                          │
       │     │        │ LANDLOCK_ACCESS_FS_READ_DIR                           │
       │     │        │ LANDLOCK_ACCESS_FS_REMOVE_DIR                         │
       │     │        │ LANDLOCK_ACCESS_FS_REMOVE_FILE                        │
       │     │        │ LANDLOCK_ACCESS_FS_MAKE_CHAR                          │
       │     │        │ LANDLOCK_ACCESS_FS_MAKE_DIR                           │
       │     │        │ LANDLOCK_ACCESS_FS_MAKE_REG                           │
       │     │        │ LANDLOCK_ACCESS_FS_MAKE_SOCK                          │
       │     │        │ LANDLOCK_ACCESS_FS_MAKE_FIFO                          │
       │     │        │ LANDLOCK_ACCESS_FS_MAKE_BLOCK                         │
       │     │        │ LANDLOCK_ACCESS_FS_MAKE_SYM                           │
       ├─────┼────────┼───────────────────────────────────────────────────────┤
       │  2  │  5.19  │ LANDLOCK_ACCESS_FS_REFER                              │
       ├─────┼────────┼───────────────────────────────────────────────────────┤
       │  3  │  6.2   │ LANDLOCK_ACCESS_FS_TRUNCATE                           │
       └─────┴────────┴───────────────────────────────────────────────────────┘

       Users should use the Landlock ABI version rather than the kernel version
       to determine which features are available.  The mainline kernel versions
       listed here are only  included  for  orientation.   Kernels  from  other
       sources  may  contain backported features, and their version numbers may
       not match.

       To query the running kernel's Landlock ABI version,  programs  may  pass
       the LANDLOCK_CREATE_RULESET_VERSION flag to landlock_create_ruleset(2).

       When  building fallback mechanisms for compatibility with older kernels,
       users are advised to consider the special semantics of the  LANDLOCK_AC-
       CESS_FS_REFER  access  right: In ABI v1, linking and moving of files be-
       tween different directories is always forbidden, so programs relying  on
       such operations are only compatible with Landlock ABI v2 and higher.

NOTES
       Landlock  is enabled by CONFIG_SECURITY_LANDLOCK.  The lsm=lsm1,...,lsmN
       command line parameter controls the sequence of  the  initialization  of
       Linux  Security  Modules.  It must contain the string landlock to enable
       Landlock.  If the command line parameter is not specified, the  initial-
       ization falls back to the value of the deprecated security= command line
       parameter  and  further  to  the value of CONFIG_LSM.  We can check that
       Landlock is enabled by looking for landlock: Up and running.  in  kernel
       logs.

CAVEATS
       It  is  currently not possible to restrict some file-related actions ac-
       cessible  through  these  system  call  families:   chdir(2),   stat(2),
       flock(2), chmod(2), chown(2), setxattr(2), utime(2), ioctl(2), fcntl(2),
       access(2).  Future Landlock evolutions will enable to restrict them.

EXAMPLES
       We first need to create the ruleset that will contain our rules.

       For  this  example,  the ruleset will contain rules that only allow read
       actions, but write actions will be denied.  The ruleset  then  needs  to
       handle  both of these kinds of actions.  See the DESCRIPTION section for
       the description of filesystem actions.

           struct landlock_ruleset_attr attr = {0};
           int ruleset_fd;

           attr.handled_access_fs =
                   LANDLOCK_ACCESS_FS_EXECUTE |
                   LANDLOCK_ACCESS_FS_WRITE_FILE |
                   LANDLOCK_ACCESS_FS_READ_FILE |
                   LANDLOCK_ACCESS_FS_READ_DIR |
                   LANDLOCK_ACCESS_FS_REMOVE_DIR |
                   LANDLOCK_ACCESS_FS_REMOVE_FILE |
                   LANDLOCK_ACCESS_FS_MAKE_CHAR |
                   LANDLOCK_ACCESS_FS_MAKE_DIR |
                   LANDLOCK_ACCESS_FS_MAKE_REG |
                   LANDLOCK_ACCESS_FS_MAKE_SOCK |
                   LANDLOCK_ACCESS_FS_MAKE_FIFO |
                   LANDLOCK_ACCESS_FS_MAKE_BLOCK |
                   LANDLOCK_ACCESS_FS_MAKE_SYM |
                   LANDLOCK_ACCESS_FS_REFER |
                   LANDLOCK_ACCESS_FS_TRUNCATE;

       To be compatible with older Linux  versions,  we  detect  the  available
       Landlock  ABI  version,  and  only  use  the  available subset of access
       rights:

           /*
            * Table of available file system access rights by ABI version,
            * numbers hardcoded to keep the example short.
            */
           __u64 landlock_fs_access_rights[] = {
               (LANDLOCK_ACCESS_FS_MAKE_SYM << 1) - 1,  /* v1                 */
               (LANDLOCK_ACCESS_FS_REFER    << 1) - 1,  /* v2: add "refer"    */
               (LANDLOCK_ACCESS_FS_TRUNCATE << 1) - 1,  /* v3: add "truncate" */
           };

           int abi = landlock_create_ruleset(NULL, 0,
                                             LANDLOCK_CREATE_RULESET_VERSION);
           if (abi == -1) {
               /*
                * Kernel too old, not compiled with Landlock,
                * or Landlock was not enabled at boot time.
                */
               perror("Unable to use Landlock");
               return;  /* Graceful fallback: Do nothing. */
           }
           abi = MIN(abi, 3);

           /* Only use the available rights in the ruleset. */
           attr.handled_access_fs &= landlock_fs_access_rights[abi - 1];

       The available access rights for each ABI version are listed in the  VER-
       SIONS section.

       If  our program needed to create hard links or rename files between dif-
       ferent directories (LANDLOCK_ACCESS_FS_REFER), we would require the fol-
       lowing change to the backwards compatibility logic: Directory  reparent-
       ing is not possible in a process restricted with Landlock ABI version 1.
       Therefore,  if  the  program  needed to do file reparenting, and if only
       Landlock ABI version 1 was available, we could not restrict the process.

       Now that the ruleset attributes are determined, we create  the  Landlock
       ruleset  and  acquire  a  file descriptor as a handle to it, using land-
       lock_create_ruleset(2):

           ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0);
           if (ruleset_fd == -1) {
               perror("Failed to create a ruleset");
               exit(EXIT_FAILURE);
           }

       We can now add a new rule to the ruleset through the ruleset's file  de-
       scriptor.   The  requested  access rights must be a subset of the access
       rights which were specified in attr.handled_access_fs  at  ruleset  cre-
       ation time.

       In  this  example,  the  rule will only allow reading the file hierarchy
       /usr.  Without another rule, write actions would then be denied  by  the
       ruleset.   To  add  /usr to the ruleset, we open it with the O_PATH flag
       and fill the struct landlock_path_beneath_attr with this  file  descrip-
       tor.

           struct landlock_path_beneath_attr path_beneath = {0};
           int err;

           path_beneath.allowed_access =
                   LANDLOCK_ACCESS_FS_EXECUTE |
                   LANDLOCK_ACCESS_FS_READ_FILE |
                   LANDLOCK_ACCESS_FS_READ_DIR;

           path_beneath.parent_fd = open("/usr", O_PATH | O_CLOEXEC);
           if (path_beneath.parent_fd == -1) {
               perror("Failed to open file");
               close(ruleset_fd);
               exit(EXIT_FAILURE);
           }
           err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
                                   &path_beneath, 0);
           close(path_beneath.parent_fd);
           if (err) {
               perror("Failed to update ruleset");
               close(ruleset_fd);
               exit(EXIT_FAILURE);
           }

       We  now  have a ruleset with one rule allowing read access to /usr while
       denying all other handled accesses for the filesystem.  The next step is
       to restrict the current  thread  from  gaining  more  privileges  (e.g.,
       thanks to a set-user-ID binary).

           if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
               perror("Failed to restrict privileges");
               close(ruleset_fd);
               exit(EXIT_FAILURE);
           }

       The current thread is now ready to sandbox itself with the ruleset.

           if (landlock_restrict_self(ruleset_fd, 0)) {
               perror("Failed to enforce ruleset");
               close(ruleset_fd);
               exit(EXIT_FAILURE);
           }
           close(ruleset_fd);

       If  the  landlock_restrict_self(2)  system  call  succeeds,  the current
       thread is now restricted and this policy will be  enforced  on  all  its
       subsequently  created  children  as  well.  Once a thread is landlocked,
       there is no way to remove its security policy; only adding more restric-
       tions is allowed.  These threads are now in a new Landlock domain, merge
       of their parent one (if any) with the new ruleset.

       Full working code can be found in  ]8;;https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/samples/landlock/sandboxer.c\https://git.kernel.org/pub/scm/linux/
       kernel/git/stable/linux.git/tree/samples/landlock/sandboxer.c]8;;\

SEE ALSO
       landlock_create_ruleset(2),      landlock_add_rule(2),      landlock_re-
       strict_self(2)

       ]8;;https://landlock.io/\https://landlock.io/]8;;\

Linux man-pages 6.9.1              2024-05-02                       Landlock(7)

Generated by dwww version 1.16 on Tue Dec 16 04:50:40 CET 2025.