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
       create safe security sandboxes as new security layers  in  addition  to
       the  existing system-wide access-controls.  This kind of sandbox is ex-
       pected to help mitigate the security impact of bugs, and unexpected  or
       malicious 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 ag-
       gregated 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.

       LANDLOCK_ACCESS_FS_READ_FILE
              Open a file with read access.

       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.

   Layers of file path access rights
       Each  time  a thread enforces a ruleset on itself, it updates its Land-
       lock domain with a new layer of  policy.   Indeed,  this  complementary
       policy  is  composed  with  the  potentially other rulesets already re-
       stricting this thread.  A sandboxed thread can  then  safely  add  more
       constraints to itself 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
       access as well as all the other system access controls (e.g.,  filesys-
       tem 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
       destination hierarchy is then composed of  the  exact  same  files,  on
       which Landlock rules can be tied, either via the source or the destina-
       tion path.  These rules restrict access when they are encountered on  a
       path,  which means that they can restrict access to multiple file hier-
       archies 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
       layers 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 Over-
       layFS layers 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  hierarchy,  and  vice  versa.   Landlock users should then only
       think about file hierarchies they want to allow access  to,  regardless
       of the underlying 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  ap-
       plication,  which will automatically be composed between themselves ac-
       cording to their runtime 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
       another 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.

VERSIONS
       Landlock was added in Linux 5.13.

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.

       It is currently not possible to restrict some file-related actions  ac-
       cessible  through  these  system  call families: chdir(2), truncate(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 re-
       strict 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 ac-
       tions, but write actions will be denied.  The  ruleset  then  needs  to
       handle  both  of these kinds of actions.  See below 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;

           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 this ruleset thanks to the  returned  file
       descriptor referring to this ruleset.  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 descriptor.

           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 re-
       strictions 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 ⟨https://git.kernel.org/pub/scm/
       linux/kernel/git/stable/linux.git/tree/samples/landlock/sandboxer.c⟩

SEE ALSO
       landlock_create_ruleset(2),     landlock_add_rule(2),      landlock_re-
       strict_self(2)https://landlock.io/⟩

Linux man-pages 6.03              2023-02-05                       Landlock(7)

Generated by dwww version 1.15 on Sun Jun 23 20:32:54 CEST 2024.