History log of /linux-master/security/landlock/fs.c
Revision Date Author Comments
# 63817feb 07-Mar-2024 Mickaël Salaün <mic@digikod.net>

landlock: Use f_cred in security_file_open() hook

Use landlock_cred(file->f_cred)->domain instead of
landlock_get_current_domain() in security_file_open() hook
implementation.

This should not change the current behavior but could avoid potential
race conditions in case of current task's credentials change.

This will also ensure consistency with upcoming audit support relying on
file->f_cred.

Add and use a new get_fs_domain() helper to mask non-filesystem domains.

file->f_cred is set by path_openat()/alloc_empty_file()/init_file() just
before calling security_file_alloc().

Cc: Christian Brauner <brauner@kernel.org>
Cc: Günther Noack <gnoack@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: Paul Moore <paul@paul-moore.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Link: https://lore.kernel.org/r/20240307095203.1467189-1-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# b4007fd2 17-Jan-2024 Mickaël Salaün <mic@digikod.net>

landlock: Add support for KUnit tests

Add the SECURITY_LANDLOCK_KUNIT_TEST option to enable KUnit tests for
Landlock. The minimal required configuration is listed in the
security/landlock/.kunitconfig file.

Add an initial landlock_fs KUnit test suite with 7 test cases for
filesystem helpers. These are related to the LANDLOCK_ACCESS_FS_REFER
right.

There is one KUnit test case per:
* mutated state (e.g. test_scope_to_request_*) or,
* shared state between tests (e.g. test_is_eaccess_*).

Add macros to improve readability of tests (i.e. one per line). Test
cases are collocated with the tested functions to help maintenance and
improve documentation. This is why SECURITY_LANDLOCK_KUNIT_TEST cannot
be set as module.

This is a nice complement to Landlock's user space kselftests. We
expect new Landlock features to come with KUnit tests as well.

Thanks to UML support, we can run all KUnit tests for Landlock with:
./tools/testing/kunit/kunit.py run --kunitconfig security/landlock

[00:00:00] ======================= landlock_fs =======================
[00:00:00] [PASSED] test_no_more_access
[00:00:00] [PASSED] test_scope_to_request_with_exec_none
[00:00:00] [PASSED] test_scope_to_request_with_exec_some
[00:00:00] [PASSED] test_scope_to_request_without_access
[00:00:00] [PASSED] test_is_eacces_with_none
[00:00:00] [PASSED] test_is_eacces_with_refer
[00:00:00] [PASSED] test_is_eacces_with_write
[00:00:00] =================== [PASSED] landlock_fs ===================
[00:00:00] ============================================================
[00:00:00] Testing complete. Ran 7 tests: passed: 7

Cc: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
Reviewed-by: Günther Noack <gnoack@google.com>
Link: https://lore.kernel.org/r/20240118113632.1948478-1-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# d9818b3e 19-Feb-2024 Mickaël Salaün <mic@digikod.net>

landlock: Fix asymmetric private inodes referring

When linking or renaming a file, if only one of the source or
destination directory is backed by an S_PRIVATE inode, then the related
set of layer masks would be used as uninitialized by
is_access_to_paths_allowed(). This would result to indeterministic
access for one side instead of always being allowed.

This bug could only be triggered with a mounted filesystem containing
both S_PRIVATE and !S_PRIVATE inodes, which doesn't seem possible.

The collect_domain_accesses() calls return early if
is_nouser_or_private() returns false, which means that the directory's
superblock has SB_NOUSER or its inode has S_PRIVATE. Because rename or
link actions are only allowed on the same mounted filesystem, the
superblock is always the same for both source and destination
directories. However, it might be possible in theory to have an
S_PRIVATE parent source inode with an !S_PRIVATE parent destination
inode, or vice versa.

To make sure this case is not an issue, explicitly initialized both set
of layer masks to 0, which means to allow all actions on the related
side. If at least on side has !S_PRIVATE, then
collect_domain_accesses() and is_access_to_paths_allowed() check for the
required access rights.

Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Günther Noack <gnoack@google.com>
Cc: Jann Horn <jannh@google.com>
Cc: Shervin Oloumi <enlightened@chromium.org>
Cc: stable@vger.kernel.org
Fixes: b91c3e4ea756 ("landlock: Add support for file reparenting with LANDLOCK_ACCESS_FS_REFER")
Link: https://lore.kernel.org/r/20240219190345.2928627-1-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# 3406ebad 08-Dec-2023 Günther Noack <gnoack@google.com>

landlock: Remove remaining "inline" modifiers in .c files [v6.6]

For module-internal static functions, compilers are already in a good
position to decide whether to inline them or not.

Suggested-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Günther Noack <gnoack@google.com>
Link: https://lore.kernel.org/r/20231208155121.1943775-2-gnoack@google.com
[mic: Split patch for Linux 6.6]
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# da279087 08-Dec-2023 Günther Noack <gnoack@google.com>

landlock: Remove remaining "inline" modifiers in .c files [v6.1]

For module-internal static functions, compilers are already in a good
position to decide whether to inline them or not.

Suggested-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Günther Noack <gnoack@google.com>
Link: https://lore.kernel.org/r/20231208155121.1943775-2-gnoack@google.com
[mic: Split patch for Linux 6.1]
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# 8fd80721 08-Dec-2023 Günther Noack <gnoack@google.com>

landlock: Remove remaining "inline" modifiers in .c files [v5.15]

For module-internal static functions, compilers are already in a good
position to decide whether to inline them or not.

Suggested-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Günther Noack <gnoack@google.com>
Link: https://lore.kernel.org/r/20231208155121.1943775-2-gnoack@google.com
[mic: Split patch for Linux 5.15]
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# f3b8788c 12-Sep-2023 Casey Schaufler <casey@schaufler-ca.com>

LSM: Identify modules by more than name

Create a struct lsm_id to contain identifying information about Linux
Security Modules (LSMs). At inception this contains the name of the
module and an identifier associated with the security module. Change
the security_add_hooks() interface to use this structure. Change the
individual modules to maintain their own struct lsm_id and pass it to
security_add_hooks().

The values are for LSM identifiers are defined in a new UAPI
header file linux/lsm.h. Each existing LSM has been updated to
include it's LSMID in the lsm_id.

The LSM ID values are sequential, with the oldest module
LSM_ID_CAPABILITY being the lowest value and the existing modules
numbered in the order they were included in the main line kernel.
This is an arbitrary convention for assigning the values, but
none better presents itself. The value 0 is defined as being invalid.
The values 1-99 are reserved for any special case uses which may
arise in the future. This may include attributes of the LSM
infrastructure itself, possibly related to namespacing or network
attribute management. A special range is identified for such attributes
to help reduce confusion for developers unfamiliar with LSMs.

LSM attribute values are defined for the attributes presented by
modules that are available today. As with the LSM IDs, The value 0
is defined as being invalid. The values 1-99 are reserved for any
special case uses which may arise in the future.

Cc: linux-security-module <linux-security-module@vger.kernel.org>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Serge Hallyn <serge@hallyn.com>
Reviewed-by: Mickael Salaun <mic@digikod.net>
Reviewed-by: John Johansen <john.johansen@canonical.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Nacked-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
[PM: forward ported beyond v6.6 due merge window changes]
Signed-off-by: Paul Moore <paul@paul-moore.com>


# 7a11275c 25-Oct-2023 Konstantin Meskhidze <konstantin.meskhidze@huawei.com>

landlock: Refactor layer helpers

Add a new key_type argument to the landlock_init_layer_masks() helper.
Add a masks_array_size argument to the landlock_unmask_layers() helper.
These modifications support implementing new rule types in the next
Landlock versions.

Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
Link: https://lore.kernel.org/r/20231026014751.414649-7-konstantin.meskhidze@huawei.com
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# 0e741011 25-Oct-2023 Konstantin Meskhidze <konstantin.meskhidze@huawei.com>

landlock: Move and rename layer helpers

Move and rename landlock_unmask_layers() and landlock_init_layer_masks()
helpers to ruleset.c to share them with Landlock network implementation
in following commits.

Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
Link: https://lore.kernel.org/r/20231026014751.414649-6-konstantin.meskhidze@huawei.com
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# a4ac404b 25-Oct-2023 Konstantin Meskhidze <konstantin.meskhidze@huawei.com>

landlock: Refactor landlock_find_rule/insert_rule helpers

Add a new landlock_key union and landlock_id structure to support a
socket port rule type. A struct landlock_id identifies a unique entry
in a ruleset: either a kernel object (e.g. inode) or typed data (e.g.
TCP port). There is one red-black tree per key type.

Add is_object_pointer() and get_root() helpers. is_object_pointer()
returns true if key type is LANDLOCK_KEY_INODE. get_root() helper
returns a red-black tree root pointer according to a key type.

Refactor landlock_insert_rule() and landlock_find_rule() to support
coming network modifications. Adding or searching a rule in ruleset can
now be done thanks to a Landlock ID argument passed to these helpers.

Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
Link: https://lore.kernel.org/r/20231026014751.414649-4-konstantin.meskhidze@huawei.com
[mic: Fix commit message typo]
Co-developed-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# d7220364 25-Oct-2023 Mickaël Salaün <mic@digikod.net>

landlock: Allow FS topology changes for domains without such rule type

Allow mount point and root directory changes when there is no filesystem
rule tied to the current Landlock domain. This doesn't change anything
for now because a domain must have at least a (filesystem) rule, but
this will change when other rule types will come. For instance, a domain
only restricting the network should have no impact on filesystem
restrictions.

Add a new get_current_fs_domain() helper to quickly check filesystem
rule existence for all filesystem LSM hooks.

Remove unnecessary inlining.

Link: https://lore.kernel.org/r/20231026014751.414649-3-konstantin.meskhidze@huawei.com
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# 13fc6455 25-Oct-2023 Konstantin Meskhidze <konstantin.meskhidze@huawei.com>

landlock: Make ruleset's access masks more generic

Rename ruleset's access masks and modify it's type to access_masks_t
to support network type rules in following commits. Add filesystem
helper functions to add and get filesystem mask.

Signed-off-by: Konstantin Meskhidze <konstantin.meskhidze@huawei.com>
Link: https://lore.kernel.org/r/20231026014751.414649-2-konstantin.meskhidze@huawei.com
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# f22f9aaf 16-Mar-2023 Paul Moore <paul@paul-moore.com>

selinux: remove the runtime disable functionality

After working with the larger SELinux-based distros for several
years, we're finally at a place where we can disable the SELinux
runtime disable functionality. The existing kernel deprecation
notice explains the functionality and why we want to remove it:

The selinuxfs "disable" node allows SELinux to be disabled at
runtime prior to a policy being loaded into the kernel. If
disabled via this mechanism, SELinux will remain disabled until
the system is rebooted.

The preferred method of disabling SELinux is via the "selinux=0"
boot parameter, but the selinuxfs "disable" node was created to
make it easier for systems with primitive bootloaders that did not
allow for easy modification of the kernel command line.
Unfortunately, allowing for SELinux to be disabled at runtime makes
it difficult to secure the kernel's LSM hooks using the
"__ro_after_init" feature.

It is that last sentence, mentioning the '__ro_after_init' hardening,
which is the real motivation for this change, and if you look at the
diffstat you'll see that the impact of this patch reaches across all
the different LSMs, helping prevent tampering at the LSM hook level.

From a SELinux perspective, it is important to note that if you
continue to disable SELinux via "/etc/selinux/config" it may appear
that SELinux is disabled, but it is simply in an uninitialized state.
If you load a policy with `load_policy -i`, you will see SELinux
come alive just as if you had loaded the policy during early-boot.

It is also worth noting that the "/sys/fs/selinux/disable" file is
always writable now, regardless of the Kconfig settings, but writing
to the file has no effect on the system, other than to display an
error on the console if a non-zero/true value is written.

Finally, in the several years where we have been working on
deprecating this functionality, there has only been one instance of
someone mentioning any user visible breakage. In this particular
case it was an individual's kernel test system, and the workaround
documented in the deprecation notice ("selinux=0" on the kernel
command line) resolved the issue without problem.

Acked-by: Casey Schaufler <casey@schaufler-ca.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>


# b9f5ce27 18-Oct-2022 Günther Noack <gnoack3000@gmail.com>

landlock: Support file truncation

Introduce the LANDLOCK_ACCESS_FS_TRUNCATE flag for file truncation.

This flag hooks into the path_truncate, file_truncate and
file_alloc_security LSM hooks and covers file truncation using
truncate(2), ftruncate(2), open(2) with O_TRUNC, as well as creat().

This change also increments the Landlock ABI version, updates
corresponding selftests, and updates code documentation to document
the flag.

In security/security.c, allocate security blobs at pointer-aligned
offsets. This fixes the problem where one LSM's security blob can
shift another LSM's security blob to an unaligned address (reported
by Nathan Chancellor).

The following operations are restricted:

open(2): requires the LANDLOCK_ACCESS_FS_TRUNCATE right if a file gets
implicitly truncated as part of the open() (e.g. using O_TRUNC).

Notable special cases:
* open(..., O_RDONLY|O_TRUNC) can truncate files as well in Linux
* open() with O_TRUNC does *not* need the TRUNCATE right when it
creates a new file.

truncate(2) (on a path): requires the LANDLOCK_ACCESS_FS_TRUNCATE
right.

ftruncate(2) (on a file): requires that the file had the TRUNCATE
right when it was previously opened. File descriptors acquired by
other means than open(2) (e.g. memfd_create(2)) continue to support
truncation with ftruncate(2).

Cc: Nathan Chancellor <nathan@kernel.org>
Signed-off-by: Günther Noack <gnoack3000@gmail.com>
Acked-by: Paul Moore <paul@paul-moore.com> (LSM)
Link: https://lore.kernel.org/r/20221018182216.301684-5-gnoack3000@gmail.com
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# 52a13488 18-Oct-2022 Günther Noack <gnoack3000@gmail.com>

landlock: Document init_layer_masks() helper

Add kernel-doc to the init_layer_masks() function.

Signed-off-by: Günther Noack <gnoack3000@gmail.com>
Link: https://lore.kernel.org/r/20221018182216.301684-4-gnoack3000@gmail.com
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# 106794c4 18-Oct-2022 Günther Noack <gnoack3000@gmail.com>

landlock: Refactor check_access_path_dual() into is_access_to_paths_allowed()

Rename check_access_path_dual() to is_access_to_paths_allowed().

Make it return true iff the access is allowed.

Calculate the EXDEV/EACCES error code in the one place where it's needed.

Suggested-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Günther Noack <gnoack3000@gmail.com>
Link: https://lore.kernel.org/r/20221018182216.301684-3-gnoack3000@gmail.com
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# 16023b05 23-Sep-2022 Mickaël Salaün <mic@digikod.net>

landlock: Slightly improve documentation and fix spelling

Now that we have more than one ABI version, make limitation explanation
more consistent by replacing "ABI 1" with "ABI < 2". This also
indicates which ABIs support such past limitation.

Improve documentation consistency by not using contractions.

Fix spelling in fs.c .

Cc: Paul Moore <paul@paul-moore.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Reviewed-by: Günther Noack <gnoack3000@gmail.com>
Link: https://lore.kernel.org/r/20220923154207.3311629-3-mic@digikod.net


# 55e55920 31-Aug-2022 Mickaël Salaün <mic@digikod.net>

landlock: Fix file reparenting without explicit LANDLOCK_ACCESS_FS_REFER

This change fixes a mis-handling of the LANDLOCK_ACCESS_FS_REFER right
when multiple rulesets/domains are stacked. The expected behaviour was
that an additional ruleset can only restrict the set of permitted
operations, but in this particular case, it was potentially possible to
re-gain the LANDLOCK_ACCESS_FS_REFER right.

With the introduction of LANDLOCK_ACCESS_FS_REFER, we added the first
globally denied-by-default access right. Indeed, this lifted an initial
Landlock limitation to rename and link files, which was initially always
denied when the source or the destination were different directories.

This led to an inconsistent backward compatibility behavior which was
only taken into account if no domain layer were using the new
LANDLOCK_ACCESS_FS_REFER right. However, when restricting a thread with
a new ruleset handling LANDLOCK_ACCESS_FS_REFER, all inherited parent
rulesets/layers not explicitly handling LANDLOCK_ACCESS_FS_REFER would
behave as if they were handling this access right and with all their
rules allowing it. This means that renaming and linking files could
became allowed by these parent layers, but all the other required
accesses must also be granted: all layers must allow file removal or
creation, and renaming and linking operations cannot lead to privilege
escalation according to the Landlock policy. See detailed explanation
in commit b91c3e4ea756 ("landlock: Add support for file reparenting with
LANDLOCK_ACCESS_FS_REFER").

To say it another way, this bug may lift the renaming and linking
limitations of the initial Landlock version, and a same ruleset can
enforce different restrictions depending on previous or next enforced
ruleset (i.e. inconsistent behavior). The LANDLOCK_ACCESS_FS_REFER right
cannot give access to data not already allowed, but this doesn't follow
the contract of the first Landlock ABI. This fix puts back the
limitation for sandboxes that didn't opt-in for this additional right.

For instance, if a first ruleset allows LANDLOCK_ACCESS_FS_MAKE_REG on
/dst and LANDLOCK_ACCESS_FS_REMOVE_FILE on /src, renaming /src/file to
/dst/file is denied. However, without this fix, stacking a new ruleset
which allows LANDLOCK_ACCESS_FS_REFER on / would now permit the
sandboxed thread to rename /src/file to /dst/file .

This change fixes the (absolute) rule access rights, which now always
forbid LANDLOCK_ACCESS_FS_REFER except when it is explicitly allowed
when creating a rule.

Making all domain handle LANDLOCK_ACCESS_FS_REFER was an initial
approach but there is two downsides:
* it makes the code more complex because we still want to check that a
rule allowing LANDLOCK_ACCESS_FS_REFER is legitimate according to the
ruleset's handled access rights (i.e. ABI v1 != ABI v2);
* it would not allow to identify if the user created a ruleset
explicitly handling LANDLOCK_ACCESS_FS_REFER or not, which will be an
issue to audit Landlock.

Instead, this change adds an ACCESS_INITIALLY_DENIED list of
denied-by-default rights, which (only) contains
LANDLOCK_ACCESS_FS_REFER. All domains are treated as if they are also
handling this list, but without modifying their fs_access_masks field.

A side effect is that the errno code returned by rename(2) or link(2)
*may* be changed from EXDEV to EACCES according to the enforced
restrictions. Indeed, we now have the mechanic to identify if an access
is denied because of a required right (e.g. LANDLOCK_ACCESS_FS_MAKE_REG,
LANDLOCK_ACCESS_FS_REMOVE_FILE) or if it is denied because of missing
LANDLOCK_ACCESS_FS_REFER rights. This may result in different errno
codes than for the initial Landlock version, but this approach is more
consistent and better for rename/link compatibility reasons, and it
wasn't possible before (hence no backport to ABI v1). The
layout1.rename_file test reflects this change.

Add 4 layout1.refer_denied_by_default* test suites to check that the
behavior of a ruleset not handling LANDLOCK_ACCESS_FS_REFER (ABI v1) is
unchanged even if another layer handles LANDLOCK_ACCESS_FS_REFER (i.e.
ABI v1 precedence). Make sure rule's absolute access rights are correct
by testing with and without a matching path. Add test_rename() and
test_exchange() helpers.

Extend layout1.inval tests to check that a denied-by-default access
right is not necessarily part of a domain's handled access rights.

Test coverage for security/landlock is 95.3% of 599 lines according to
gcc/gcov-11.

Fixes: b91c3e4ea756 ("landlock: Add support for file reparenting with LANDLOCK_ACCESS_FS_REFER")
Reviewed-by: Paul Moore <paul@paul-moore.com>
Reviewed-by: Günther Noack <gnoack3000@gmail.com>
Link: https://lore.kernel.org/r/20220831203840.1370732-1-mic@digikod.net
Cc: stable@vger.kernel.org
[mic: Constify and slightly simplify test helpers]
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# b91c3e4e 06-May-2022 Mickaël Salaün <mic@digikod.net>

landlock: Add support for file reparenting with LANDLOCK_ACCESS_FS_REFER

Add a new LANDLOCK_ACCESS_FS_REFER access right to enable policy writers
to allow sandboxed processes to link and rename files from and to a
specific set of file hierarchies. This access right should be composed
with LANDLOCK_ACCESS_FS_MAKE_* for the destination of a link or rename,
and with LANDLOCK_ACCESS_FS_REMOVE_* for a source of a rename. This
lift a Landlock limitation that always denied changing the parent of an
inode.

Renaming or linking to the same directory is still always allowed,
whatever LANDLOCK_ACCESS_FS_REFER is used or not, because it is not
considered a threat to user data.

However, creating multiple links or renaming to a different parent
directory may lead to privilege escalations if not handled properly.
Indeed, we must be sure that the source doesn't gain more privileges by
being accessible from the destination. This is handled by making sure
that the source hierarchy (including the referenced file or directory
itself) restricts at least as much the destination hierarchy. If it is
not the case, an EXDEV error is returned, making it potentially possible
for user space to copy the file hierarchy instead of moving or linking
it.

Instead of creating different access rights for the source and the
destination, we choose to make it simple and consistent for users.
Indeed, considering the previous constraint, it would be weird to
require such destination access right to be also granted to the source
(to make it a superset). Moreover, RENAME_EXCHANGE would also add to
the confusion because of paths being both a source and a destination.

See the provided documentation for additional details.

New tests are provided with a following commit.

Reviewed-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506161102.525323-8-mic@digikod.net


# 100f59d9 06-May-2022 Mickaël Salaün <mic@digikod.net>

LSM: Remove double path_rename hook calls for RENAME_EXCHANGE

In order to be able to identify a file exchange with renameat2(2) and
RENAME_EXCHANGE, which will be useful for Landlock [1], propagate the
rename flags to LSMs. This may also improve performance because of the
switch from two set of LSM hook calls to only one, and because LSMs
using this hook may optimize the double check (e.g. only one lock,
reduce the number of path walks).

AppArmor, Landlock and Tomoyo are updated to leverage this change. This
should not change the current behavior (same check order), except
(different level of) speed boosts.

[1] https://lore.kernel.org/r/20220221212522.320243-1-mic@digikod.net

Cc: James Morris <jmorris@namei.org>
Cc: Kentaro Takeda <takedakn@nttdata.co.jp>
Cc: Serge E. Hallyn <serge@hallyn.com>
Acked-by: John Johansen <john.johansen@canonical.com>
Acked-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Reviewed-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506161102.525323-7-mic@digikod.net


# 9da82b20 06-May-2022 Mickaël Salaün <mic@digikod.net>

landlock: Move filesystem helpers and add a new one

Move the SB_NOUSER and IS_PRIVATE dentry check to a standalone
is_nouser_or_private() helper. This will be useful for a following
commit.

Move get_mode_access() and maybe_remove() to make them usable by new
code provided by a following commit.

Reviewed-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506161102.525323-6-mic@digikod.net


# 8ba0005f 06-May-2022 Mickaël Salaün <mic@digikod.net>

landlock: Fix same-layer rule unions

The original behavior was to check if the full set of requested accesses
was allowed by at least a rule of every relevant layer. This didn't
take into account requests for multiple accesses and same-layer rules
allowing the union of these accesses in a complementary way. As a
result, multiple accesses requested on a file hierarchy matching rules
that, together, allowed these accesses, but without a unique rule
allowing all of them, was illegitimately denied. This case should be
rare in practice and it can only be triggered by the path_rename or
file_open hook implementations.

For instance, if, for the same layer, a rule allows execution
beneath /a/b and another rule allows read beneath /a, requesting access
to read and execute at the same time for /a/b should be allowed for this
layer.

This was an inconsistency because the union of same-layer rule accesses
was already allowed if requested once at a time anyway.

This fix changes the way allowed accesses are gathered over a path walk.
To take into account all these rule accesses, we store in a matrix all
layer granting the set of requested accesses, according to the handled
accesses. To avoid heap allocation, we use an array on the stack which
is 2*13 bytes. A following commit bringing the LANDLOCK_ACCESS_FS_REFER
access right will increase this size to reach 112 bytes (2*14*4) in case
of link or rename actions.

Add a new layout1.layer_rule_unions test to check that accesses from
different rules pertaining to the same layer are ORed in a file
hierarchy. Also test that it is not the case for rules from different
layers.

Reviewed-by: Paul Moore <paul@paul-moore.com>
Link: https://lore.kernel.org/r/20220506161102.525323-5-mic@digikod.net
Cc: stable@vger.kernel.org
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# 2cd7cd6e 06-May-2022 Mickaël Salaün <mic@digikod.net>

landlock: Create find_rule() from unmask_layers()

This refactoring will be useful in a following commit.

Reviewed-by: Paul Moore <paul@paul-moore.com>
Link: https://lore.kernel.org/r/20220506161102.525323-4-mic@digikod.net
Cc: stable@vger.kernel.org
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# 75c542d6 06-May-2022 Mickaël Salaün <mic@digikod.net>

landlock: Reduce the maximum number of layers to 16

The maximum number of nested Landlock domains is currently 64. Because
of the following fix and to help reduce the stack size, let's reduce it
to 16. This seems large enough for a lot of use cases (e.g. sandboxed
init service, spawning a sandboxed SSH service, in nested sandboxed
containers). Reducing the number of nested domains may also help to
discover misuse of Landlock (e.g. creating a domain per rule).

Add and use a dedicated layer_mask_t typedef to fit with the number of
layers. This might be useful when changing it and to keep it consistent
with the maximum number of layers.

Reviewed-by: Paul Moore <paul@paul-moore.com>
Link: https://lore.kernel.org/r/20220506161102.525323-3-mic@digikod.net
Cc: stable@vger.kernel.org
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# 5f2ff33e 06-May-2022 Mickaël Salaün <mic@digikod.net>

landlock: Define access_mask_t to enforce a consistent access mask size

Create and use the access_mask_t typedef to enforce a consistent access
mask size and uniformly use a 16-bits type. This will helps transition
to a 32-bits value one day.

Add a build check to make sure all (filesystem) access rights fit in.
This will be extended with a following commit.

Reviewed-by: Paul Moore <paul@paul-moore.com>
Link: https://lore.kernel.org/r/20220506161102.525323-2-mic@digikod.net
Cc: stable@vger.kernel.org
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# 06a1c40a 06-May-2022 Mickaël Salaün <mic@digikod.net>

landlock: Format with clang-format

Let's follow a consistent and documented coding style. Everything may
not be to our liking but it is better than tacit knowledge. Moreover,
this will help maintain style consistency between different developers.

This contains only whitespace changes.

Automatically formatted with:
clang-format-14 -i security/landlock/*.[ch] include/uapi/linux/landlock.h

Link: https://lore.kernel.org/r/20220506160513.523257-3-mic@digikod.net
Cc: stable@vger.kernel.org
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# 6cc2df8e 06-May-2022 Mickaël Salaün <mic@digikod.net>

landlock: Add clang-format exceptions

In preparation to a following commit, add clang-format on and
clang-format off stanzas around constant definitions. This enables to
keep aligned values, which is much more readable than packed
definitions.

Link: https://lore.kernel.org/r/20220506160513.523257-2-mic@digikod.net
Cc: stable@vger.kernel.org
Signed-off-by: Mickaël Salaün <mic@digikod.net>


# cb2c7d1a 22-Apr-2021 Mickaël Salaün <mic@linux.microsoft.com>

landlock: Support filesystem access-control

Using Landlock objects and ruleset, it is possible to tag inodes
according to a process's domain. To enable an unprivileged process to
express a file hierarchy, it first needs to open a directory (or a file)
and pass this file descriptor to the kernel through
landlock_add_rule(2). When checking if a file access request is
allowed, we walk from the requested dentry to the real root, following
the different mount layers. The access to each "tagged" inodes are
collected according to their rule layer level, and ANDed to create
access to the requested file hierarchy. This makes possible to identify
a lot of files without tagging every inodes nor modifying the
filesystem, while still following the view and understanding the user
has from the filesystem.

Add a new ARCH_EPHEMERAL_INODES for UML because it currently does not
keep the same struct inodes for the same inodes whereas these inodes are
in use.

This commit adds a minimal set of supported filesystem access-control
which doesn't enable to restrict all file-related actions. This is the
result of multiple discussions to minimize the code of Landlock to ease
review. Thanks to the Landlock design, extending this access-control
without breaking user space will not be a problem. Moreover, seccomp
filters can be used to restrict the use of syscall families which may
not be currently handled by Landlock.

Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Anton Ivanov <anton.ivanov@cambridgegreys.com>
Cc: James Morris <jmorris@namei.org>
Cc: Jann Horn <jannh@google.com>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: Kees Cook <keescook@chromium.org>
Cc: Richard Weinberger <richard@nod.at>
Cc: Serge E. Hallyn <serge@hallyn.com>
Signed-off-by: Mickaël Salaün <mic@linux.microsoft.com>
Link: https://lore.kernel.org/r/20210422154123.13086-8-mic@digikod.net
Signed-off-by: James Morris <jamorris@linux.microsoft.com>