linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Mickaël Salaün" <mic@digikod.net>
To: Randy Dunlap <rdunlap@infradead.org>, linux-kernel@vger.kernel.org
Cc: "Al Viro" <viro@zeniv.linux.org.uk>,
	"Andy Lutomirski" <luto@amacapital.net>,
	"Arnd Bergmann" <arnd@arndb.de>,
	"Casey Schaufler" <casey@schaufler-ca.com>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"James Morris" <jmorris@namei.org>, "Jann Horn" <jann@thejh.net>,
	"Jonathan Corbet" <corbet@lwn.net>,
	"Kees Cook" <keescook@chromium.org>,
	"Michael Kerrisk" <mtk.manpages@gmail.com>,
	"Mickaël Salaün" <mickael.salaun@ssi.gouv.fr>,
	"Serge E . Hallyn" <serge@hallyn.com>,
	"Shuah Khan" <shuah@kernel.org>,
	"Vincent Dagonneau" <vincent.dagonneau@ssi.gouv.fr>,
	kernel-hardening@lists.openwall.com, linux-api@vger.kernel.org,
	linux-arch@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-fsdevel@vger.kernel.org, linux-kselftest@vger.kernel.org,
	linux-security-module@vger.kernel.org, x86@kernel.org
Subject: Re: [RFC PATCH v14 10/10] landlock: Add user and kernel documentation
Date: Mon, 2 Mar 2020 11:03:55 +0100	[thread overview]
Message-ID: <e22709f2-af4f-9316-d83e-b794f083595c@digikod.net> (raw)
In-Reply-To: <cc8da381-d3dc-3c0a-5afd-96824362b636@infradead.org>


On 29/02/2020 18:23, Randy Dunlap wrote:
> Hi,
> Here are a few corrections for you to consider.
> 
> 
> On 2/24/20 8:02 AM, Mickaël Salaün wrote:
>> This documentation can be built with the Sphinx framework.
>>
>> Another location might be more appropriate, though.
>>
>> Signed-off-by: Mickaël Salaün <mic@digikod.net>
>> Reviewed-by: Vincent Dagonneau <vincent.dagonneau@ssi.gouv.fr>
>> Cc: Andy Lutomirski <luto@amacapital.net>
>> Cc: James Morris <jmorris@namei.org>
>> Cc: Kees Cook <keescook@chromium.org>
>> Cc: Serge E. Hallyn <serge@hallyn.com>
>> ---
>>
>> Changes since v13:
>> * Rewrote the documentation according to the major revamp.
>>
>> Previous version:
>> https://lore.kernel.org/lkml/20191104172146.30797-8-mic@digikod.net/
>> ---
>>  Documentation/security/index.rst           |   1 +
>>  Documentation/security/landlock/index.rst  |  18 ++
>>  Documentation/security/landlock/kernel.rst |  44 ++++
>>  Documentation/security/landlock/user.rst   | 233 +++++++++++++++++++++
>>  4 files changed, 296 insertions(+)
>>  create mode 100644 Documentation/security/landlock/index.rst
>>  create mode 100644 Documentation/security/landlock/kernel.rst
>>  create mode 100644 Documentation/security/landlock/user.rst
>>
>> diff --git a/Documentation/security/landlock/index.rst b/Documentation/security/landlock/index.rst
>> new file mode 100644
>> index 000000000000..dbd33b96ce60
>> --- /dev/null
>> +++ b/Documentation/security/landlock/index.rst
>> @@ -0,0 +1,18 @@
>> +=========================================
>> +Landlock LSM: unprivileged access control
>> +=========================================
>> +
>> +:Author: Mickaël Salaün
>> +
>> +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 empower any
> 
>                                                                        empowers
> 
>> +process, including unprivileged ones, to securely restrict themselves.
>> +
>> +.. toctree::
>> +
>> +    user
>> +    kernel
>> diff --git a/Documentation/security/landlock/kernel.rst b/Documentation/security/landlock/kernel.rst
>> new file mode 100644
>> index 000000000000..b87769909029
>> --- /dev/null
>> +++ b/Documentation/security/landlock/kernel.rst
>> @@ -0,0 +1,44 @@
>> +==============================
>> +Landlock: kernel documentation
>> +==============================
>> +
>> +Landlock's goal is to create scoped access-control (i.e. sandboxing).  To
>> +harden a whole system, this feature should be available to any process,
>> +including unprivileged ones.  Because such process may be compromised or
>> +backdoored (i.e. untrusted), Landlock's features must be safe to use from the
>> +kernel and other processes point of view.  Landlock's interface must therefore
>> +expose a minimal attack surface.
>> +
>> +Landlock is designed to be usable by unprivileged processes while following the
>> +system security policy enforced by other access control mechanisms (e.g. DAC,
>> +LSM).  Indeed, a Landlock rule shall not interfere with other access-controls
>> +enforced on the system, only add more restrictions.
>> +
>> +Any user can enforce Landlock rulesets on their processes.  They are merged and
>> +evaluated according to the inherited ones in a way that ensure that only more
> 
>                                                            ensures
> 
>> +constraints can be added.
>> +
>> +
>> +Guiding principles for safe access controls
>> +===========================================
>> +
>> +* A Landlock rule shall be focused on access control on kernel objects instead
>> +  of syscall filtering (i.e. syscall arguments), which is the purpose of
>> +  seccomp-bpf.
>> +* To avoid multiple kind of side-channel attacks (e.g. leak of security
> 
>                        kinds
> 
>> +  policies, CPU-based attacks), Landlock rules shall not be able to
>> +  programmatically communicate with user space.
>> +* Kernel access check shall not slow down access request from unsandboxed
>> +  processes.
>> +* Computation related to Landlock operations (e.g. enforce a ruleset) shall
>> +  only impact the processes requesting them.
>> +
>> +
>> +Landlock rulesets and domains
>> +=============================
>> +
>> +A domain is a read-only ruleset tied to a set of subjects (i.e. tasks).  A
>> +domain can transition to a new one which is the intersection of the constraints
>> +from the current and a new ruleset.  The definition of a subject is implicit
>> +for a task sandboxing itself, which makes the reasoning much easier and helps
>> +avoid pitfalls.
>> diff --git a/Documentation/security/landlock/user.rst b/Documentation/security/landlock/user.rst
>> new file mode 100644
>> index 000000000000..cbd7f61fca8c
>> --- /dev/null
>> +++ b/Documentation/security/landlock/user.rst
>> @@ -0,0 +1,233 @@
>> +=================================
>> +Landlock: userspace documentation
>> +=================================
>> +
>> +Landlock rules
>> +==============
>> +
>> +A Landlock rule enables to describe an action on an object.  An object is
>> +currently a file hierarchy, and the related filesystem actions are defined in
>> +`Access rights`_.  A set of rules are aggregated in a ruleset, which can then
> 
>                                      is
> 
>> +restricts the thread enforcing it, and its future children.
> 
>    restrict
> 
>> +
>> +
>> +Defining and enforcing a security policy
>> +----------------------------------------
>> +
>> +Before defining a security policy, an application should first probe for the
>> +features supported by the running kernel, which is important to be compatible
>> +with older kernels.  This can be done thanks to the `landlock` syscall (cf.
>> +:ref:`syscall`).
>> +
>> +.. code-block:: c
>> +
>> +    struct landlock_attr_features attr_features;
>> +
>> +    if (landlock(LANDLOCK_CMD_GET_FEATURES, LANDLOCK_OPT_GET_FEATURES,
>> +            sizeof(attr_features), &attr_features)) {
>> +        perror("Failed to probe the Landlock supported features");
>> +        return 1;
>> +    }
>> +
>> +Then, we need to create the ruleset that will contains our rules.  For this
> 
>                                                  contain
> 
>> +example, the ruleset will contains rules which only allow read actions, but
> 
>                              contain
> 
>> +write actions will be denied.  The ruleset then needs to handle both of these
>> +kind of actions.  To have a backward compatibility, these actions should be
>> +ANDed with the supported ones.
>> +
>> +.. code-block:: c
>> +
>> +    int ruleset_fd;
>> +    struct landlock_attr_ruleset ruleset = {
>> +        .handled_access_fs =
>> +            LANDLOCK_ACCESS_FS_READ |
>> +            LANDLOCK_ACCESS_FS_READDIR |
>> +            LANDLOCK_ACCESS_FS_EXECUTE |
>> +            LANDLOCK_ACCESS_FS_WRITE |
>> +            LANDLOCK_ACCESS_FS_TRUNCATE |
>> +            LANDLOCK_ACCESS_FS_CHMOD |
>> +            LANDLOCK_ACCESS_FS_CHOWN |
>> +            LANDLOCK_ACCESS_FS_CHGRP |
>> +            LANDLOCK_ACCESS_FS_LINK_TO |
>> +            LANDLOCK_ACCESS_FS_RENAME_FROM |
>> +            LANDLOCK_ACCESS_FS_RENAME_TO |
>> +            LANDLOCK_ACCESS_FS_RMDIR |
>> +            LANDLOCK_ACCESS_FS_UNLINK |
>> +            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.handled_access_fs &= attr_features.access_fs;
>> +    ruleset_fd = landlock(LANDLOCK_CMD_CREATE_RULESET,
>> +                    LANDLOCK_OPT_CREATE_RULESET, sizeof(ruleset), &ruleset);
>> +    if (ruleset_fd < 0) {
>> +        perror("Failed to create a ruleset");
>> +        return 1;
>> +    }
>> +
>> +We can now add a new rule to this ruleset thanks to the returned file
>> +descriptor referring to this ruleset.  The rule will only enable to read the
>> +file hierarchy ``/usr``.  Without other rule, write actions would then be
> 
>                              Without other rules,
> or
>                              Without another rule,
> 
>> +denied by the ruleset.  To add ``/usr`` to the ruleset, we open it with the
>> +``O_PATH`` flag and fill the &struct landlock_attr_path_beneath with this file
>> +descriptor.
>> +
>> +.. code-block:: c
>> +
>> +    int err;
>> +    struct landlock_attr_path_beneath path_beneath = {
>> +        .ruleset_fd = ruleset_fd,
>> +        .allowed_access =
>> +            LANDLOCK_ACCESS_FS_READ |
>> +            LANDLOCK_ACCESS_FS_READDIR |
>> +            LANDLOCK_ACCESS_FS_EXECUTE,
>> +    };
>> +
>> +    path_beneath.allowed_access &= attr_features.access_fs;
>> +    path_beneath.parent_fd = open("/usr", O_PATH | O_CLOEXEC);
>> +    if (path_beneath.parent_fd < 0) {
>> +        perror("Failed to open file");
>> +        close(ruleset_fd);
>> +        return 1;
>> +    }
>> +    err = landlock(LANDLOCK_CMD_ADD_RULE, LANDLOCK_OPT_ADD_RULE_PATH_BENEATH,
>> +            sizeof(path_beneath), &path_beneath);
>> +    close(path_beneath.parent_fd);
>> +    if (err) {
>> +        perror("Failed to update ruleset");
>> +        close(ruleset_fd);
>> +        return 1;
>> +    }
>> +
>> +We now have a ruleset with one rule allowing read access to ``/usr`` while
>> +denying all accesses featured in ``attr_features.access_fs`` to everything else
>> +on the filesystem.  The next step is to restrict the current thread from
>> +gaining more privileges (e.g. thanks to a SUID binary).
>> +
>> +.. code-block:: c
>> +
>> +    if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
>> +        perror("Failed to restrict privileges");
>> +        close(ruleset_fd);
>> +        return 1;
>> +    }
>> +
>> +The current thread is now ready to sandbox itself with the ruleset.
>> +
>> +.. code-block:: c
>> +
>> +    struct landlock_attr_enforce attr_enforce = {
>> +        .ruleset_fd = ruleset_fd,
>> +    };
>> +
>> +    if (landlock(LANDLOCK_CMD_ENFORCE_RULESET, LANDLOCK_OPT_ENFORCE_RULESET,
>> +            sizeof(attr_enforce), &attr_enforce)) {
>> +        perror("Failed to enforce ruleset");
>> +        close(ruleset_fd);
>> +        return 1;
>> +    }
>> +    close(ruleset_fd);
>> +
>> +If this last system call succeeds, the current thread is now restricted and
> 
>    If this last landlock system call succeeds,
> 
> [because close() is the last system call]
> 
>> +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,
> 
>                                                    preferably:         policy;
> 
>> +only adding more restrictions is allowed.  These threads are now in a new
>> +Landlock domain, merge of their parent one (if any) with the new ruleset.
>> +
>> +A full working code can be found in `samples/landlock/sandboxer.c`_.
> 
>    Full working code
> 
>> +
>> +
>> +Inheritance
>> +-----------
>> +
>> +Every new thread resulting from a :manpage:`clone(2)` inherits Landlock program
>> +restrictions from its parent.  This is similar to the seccomp inheritance (cf.
>> +:doc:`/userspace-api/seccomp_filter`) or any other LSM dealing with task's
>> +:manpage:`credentials(7)`.  For instance, one process' thread may apply
> 
>                                                  process's
> 
>> +Landlock rules to itself, but they will not be automatically applied to other
>> +sibling threads (unlike POSIX thread credential changes, cf.
>> +:manpage:`nptl(7)`).
> 
> [snip]
> 
> thanks for the documentation.
> 

Done. Thanks for this attentive review!

  reply	other threads:[~2020-03-02 10:03 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-24 16:02 [RFC PATCH v14 00/10] Landlock LSM Mickaël Salaün
2020-02-24 16:02 ` [RFC PATCH v14 01/10] landlock: Add object and rule management Mickaël Salaün
2020-02-25 20:49   ` Jann Horn
2020-02-26 15:31     ` Mickaël Salaün
2020-02-26 20:24       ` Jann Horn
2020-02-27 16:46         ` Mickaël Salaün
2020-02-24 16:02 ` [RFC PATCH v14 02/10] landlock: Add ruleset and domain management Mickaël Salaün
2020-02-24 16:02 ` [RFC PATCH v14 03/10] landlock: Set up the security framework and manage credentials Mickaël Salaün
2020-02-24 16:02 ` [RFC PATCH v14 04/10] landlock: Add ptrace restrictions Mickaël Salaün
2020-02-24 16:02 ` [RFC PATCH v14 05/10] fs,landlock: Support filesystem access-control Mickaël Salaün
2020-02-26 20:29   ` Jann Horn
2020-02-27 16:50     ` Mickaël Salaün
2020-02-27 16:51       ` Jann Horn
2020-02-24 16:02 ` [RFC PATCH v14 06/10] landlock: Add syscall implementation Mickaël Salaün
2020-03-17 16:47   ` Al Viro
2020-03-17 17:51     ` Mickaël Salaün
2020-02-24 16:02 ` [RFC PATCH v14 07/10] arch: Wire up landlock() syscall Mickaël Salaün
2020-02-24 16:02 ` [RFC PATCH v14 08/10] selftests/landlock: Add initial tests Mickaël Salaün
2020-02-24 16:02 ` [RFC PATCH v14 09/10] samples/landlock: Add a sandbox manager example Mickaël Salaün
2020-02-24 16:02 ` [RFC PATCH v14 10/10] landlock: Add user and kernel documentation Mickaël Salaün
2020-02-29 17:23   ` Randy Dunlap
2020-03-02 10:03     ` Mickaël Salaün [this message]
2020-02-25 18:49 ` [RFC PATCH v14 00/10] Landlock LSM J Freyensee
2020-02-26 15:34   ` Mickaël Salaün
     [not found] ` <20200227042002.3032-1-hdanton@sina.com>
2020-02-27 17:01   ` [RFC PATCH v14 01/10] landlock: Add object and rule management Mickaël Salaün
2020-03-09 23:44 ` [RFC PATCH v14 00/10] Landlock LSM Jann Horn
2020-03-11 23:38   ` Mickaël Salaün
2020-03-17 16:19     ` Jann Horn
2020-03-17 17:50       ` Mickaël Salaün
2020-03-17 19:45         ` Jann Horn
2020-03-18 12:06           ` Mickaël Salaün
2020-03-18 23:33             ` Jann Horn
2020-03-19 16:58               ` Mickaël Salaün
2020-03-19 21:17                 ` Jann Horn
2020-03-30 18:26                   ` Mickaël Salaün

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e22709f2-af4f-9316-d83e-b794f083595c@digikod.net \
    --to=mic@digikod.net \
    --cc=arnd@arndb.de \
    --cc=casey@schaufler-ca.com \
    --cc=corbet@lwn.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=jann@thejh.net \
    --cc=jmorris@namei.org \
    --cc=keescook@chromium.org \
    --cc=kernel-hardening@lists.openwall.com \
    --cc=linux-api@vger.kernel.org \
    --cc=linux-arch@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=luto@amacapital.net \
    --cc=mickael.salaun@ssi.gouv.fr \
    --cc=mtk.manpages@gmail.com \
    --cc=rdunlap@infradead.org \
    --cc=serge@hallyn.com \
    --cc=shuah@kernel.org \
    --cc=vincent.dagonneau@ssi.gouv.fr \
    --cc=viro@zeniv.linux.org.uk \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).