NAME
    Linux::Landlock - A higher level interface to the Linux Landlock API

DESCRIPTION
    Landlock is a sandboxing feature specific to Linux that allows a process
    to restrict its own access to the file system. Once set, restrictions
    cannot be undone and they are inherited by all future child processes.

    Since the restrictions are set at runtime, from within the process
    itself, you can take into account dynamic information from your
    configuration. For example, a server that is supposed to serve files
    from a specific directory can restrict itself to that directory and its
    subdirectories to mitigate any bugs allowing directory traversal
    attacks. This is much less intrusive than chroot and does not require
    root privileges.

    This module provides an object-oriented interface to the Linux Landlock
    API. It uses the lower-level interface provided by
    Linux::Landlock::Direct.

    See <https://docs.kernel.org/userspace-api/landlock.html> for more
    information about Landlock.

METHODS
SYNOPSIS
          use Linux::Landlock;

          my $ruleset = Linux::Landlock->new(); # this can die
          $ruleset->add_path_rule('/etc/fstab', qw(read_file));
          $ruleset->add_net_rule(22222, qw(bind_tcp));
          $ruleset->apply();

          print -r '/etc/fstab' ? "allowed\n" : "not allowed\n"; # allowed ...
          IO::File->new('/etc/fstab', 'r') and print "succeeded: $!\n"; # ... and opening works
          print -r '/etc/passwd' ? "allowed\n" : "not allowed\n"; # allowed ...
          IO::File->new('/etc/passwd', 'r') or print "failed\n"; # ... but opening fails because of Landlock

          system('/usr/bin/cat /etc/fstab') and print "failed: $!\n"; # this fails, because we cannot execute cat

          IO::Socket::INET->new(LocalPort => 33333, Proto => 'tcp') or print "failed: $!\n"; # failed
          IO::Socket::INET->new(LocalPort => 22222, Proto => 'tcp') and print "succeeded\n"; # succeeded

    new([handled_fs_actions => \@fs_actions, handled_net_actions =>
    \@net_actions, die_on_unsupported => 1|0])
     Create a new Linux::Landlock instance.

     "handled_fs_actions" and "handled_net_actions" restrict the set of
     actions that can be used in rules and that will be prevented if not
     allowed by any rule. By default, all actions supported by the kernel
     and known to this module are covered. This should usually not be
     changed.

     If "die_on_unsupported" is set to a true value, the module will die if
     an unsupported access right is requested. Otherwise, access rights will
     be set on a best-effort basis, as intended by the upstream Landlock API
     design. This option should usually not be used.

    apply()
     Apply the ruleset to the current process and all future children. Dies
     on error.

    get_abi_version()
     Int, returns the ABI version of the Landlock kernel module. Can be
     called as a static method. A version < 1 means that Landlock is not
     available.

    add_path_beneath_rule($path, @allowed)
     Add a rule to the ruleset that allows the specified access to the given
     path. $path can be a file or a directory. @allowed is a list of access
     rights to allow.

     Possible access rights are:

         execute
         write_file
         read_file
         read_dir
         remove_dir
         remove_file
         make_char
         make_dir
         make_reg
         make_sock
         make_fifo
         make_block
         make_sym
         refer
         truncate

     See <https://docs.kernel.org/userspace-api/landlock.html> for all
     possible access rights.

     This method dies on error. Errors are: non-existing or non-accessible
     paths and empty rules. If "die_on_unsupported" is used, it will also
     die if the rules are not supported by the current kernel.

     Beware: While the API accepts a path or user space file descriptor, the
     rule is actually applied to the kernel internal file system object.
     This means that you will lose access if a path or directory you allowed
     access to is renamed or replaced.

    add_net_port_rule($port, @allowed)
     Add a rule to the ruleset that allows the specified access to the given
     port. $port is allowed port, @allowed is a list of allowed operations.

     Possible operations are:

         bind_tcp
         connect_tcp

    allow_perl_inc_access()
     A convenience method that adds rules to allow reading files and
     directories in all directories in @INC. This will not allow access to
     ".", even if it is in @INC.

LIMITATIONS
    This module requires a Linux system supporting the Landlock
    functionality. As of 2024, this is the case for almost all
    distributions, however, the version of the available Landlock ABI
    varies.

    Notably, the "TRUNCATE" access right is only supported by the kernel
    since ABI version 3 (kernel version 6.2 or newer, unless backported).

    Network functionality is only available since ABI version 4.

    Also keep in mind, that some Perl, or even libc, functions might
    implicitly rely on file system access that could have been restricted by
    Landlock.

AUTHOR
    Marc Ballarin, <ballarin.marc@gmx.de>

COPYRIGHT AND LICENSE
    Copyright (C) 2024 by Marc Ballarin

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

