* [PATCH v9 10/11] samples/landlock: Extend sample tool to support LANDLOCK_ACCESS_FS_TRUNCATE
@ 2022-10-08 11:13 Günther Noack
2022-10-08 11:13 ` [PATCH v9 11/11] landlock: Document Landlock's file truncation support Günther Noack
0 siblings, 1 reply; 4+ messages in thread
From: Günther Noack @ 2022-10-08 11:13 UTC (permalink / raw)
To: linux-security-module
Cc: Mickaël Salaün, James Morris, Paul Moore,
Serge E . Hallyn, linux-fsdevel, Konstantin Meskhidze,
Nathan Chancellor, Günther Noack
Update the sandboxer sample to restrict truncate actions. This is
automatically enabled by default if the running kernel supports
LANDLOCK_ACCESS_FS_TRUNCATE, except for the paths listed in the
LL_FS_RW environment variable.
Signed-off-by: Günther Noack <gnoack3000@gmail.com>
---
samples/landlock/sandboxer.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c
index f29bb3c72230..fd4237c64fb2 100644
--- a/samples/landlock/sandboxer.c
+++ b/samples/landlock/sandboxer.c
@@ -76,7 +76,8 @@ static int parse_path(char *env_path, const char ***const path_list)
#define ACCESS_FILE ( \
LANDLOCK_ACCESS_FS_EXECUTE | \
LANDLOCK_ACCESS_FS_WRITE_FILE | \
- LANDLOCK_ACCESS_FS_READ_FILE)
+ LANDLOCK_ACCESS_FS_READ_FILE | \
+ LANDLOCK_ACCESS_FS_TRUNCATE)
/* clang-format on */
@@ -160,11 +161,12 @@ static int populate_ruleset(const char *const env_var, const int ruleset_fd,
LANDLOCK_ACCESS_FS_MAKE_FIFO | \
LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
LANDLOCK_ACCESS_FS_MAKE_SYM | \
- LANDLOCK_ACCESS_FS_REFER)
+ LANDLOCK_ACCESS_FS_REFER | \
+ LANDLOCK_ACCESS_FS_TRUNCATE)
/* clang-format on */
-#define LANDLOCK_ABI_LAST 2
+#define LANDLOCK_ABI_LAST 3
int main(const int argc, char *const argv[], char *const *const envp)
{
@@ -234,6 +236,10 @@ int main(const int argc, char *const argv[], char *const *const envp)
case 1:
/* Removes LANDLOCK_ACCESS_FS_REFER for ABI < 2 */
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
+ __attribute__((fallthrough));
+ case 2:
+ /* Removes LANDLOCK_ACCESS_FS_TRUNCATE for ABI < 3 */
+ ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
fprintf(stderr,
"Hint: You should update the running kernel "
--
2.38.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v9 11/11] landlock: Document Landlock's file truncation support
2022-10-08 11:13 [PATCH v9 10/11] samples/landlock: Extend sample tool to support LANDLOCK_ACCESS_FS_TRUNCATE Günther Noack
@ 2022-10-08 11:13 ` Günther Noack
2022-10-08 11:19 ` Günther Noack
0 siblings, 1 reply; 4+ messages in thread
From: Günther Noack @ 2022-10-08 11:13 UTC (permalink / raw)
To: linux-security-module
Cc: Mickaël Salaün, James Morris, Paul Moore,
Serge E . Hallyn, linux-fsdevel, Konstantin Meskhidze,
Nathan Chancellor, Günther Noack
Use the LANDLOCK_ACCESS_FS_TRUNCATE flag in the tutorial.
Adapt the backwards compatibility example and discussion to remove the
truncation flag where needed.
Point out potential surprising behaviour related to truncate.
Signed-off-by: Günther Noack <gnoack3000@gmail.com>
---
Documentation/userspace-api/landlock.rst | 67 +++++++++++++++++++++---
1 file changed, 60 insertions(+), 7 deletions(-)
diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst
index cec780c2f497..d8cd8cd9ce25 100644
--- a/Documentation/userspace-api/landlock.rst
+++ b/Documentation/userspace-api/landlock.rst
@@ -8,7 +8,7 @@ Landlock: unprivileged access control
=====================================
:Author: Mickaël Salaün
-:Date: September 2022
+:Date: October 2022
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
@@ -60,7 +60,8 @@ the need to be explicit about the denied-by-default access rights.
LANDLOCK_ACCESS_FS_MAKE_FIFO |
LANDLOCK_ACCESS_FS_MAKE_BLOCK |
LANDLOCK_ACCESS_FS_MAKE_SYM |
- LANDLOCK_ACCESS_FS_REFER,
+ LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_TRUNCATE,
};
Because we may not know on which kernel version an application will be
@@ -69,16 +70,28 @@ should try to protect users as much as possible whatever the kernel they are
using. To avoid binary enforcement (i.e. either all security features or
none), we can leverage a dedicated Landlock command to get the current version
of the Landlock ABI and adapt the handled accesses. Let's check if we should
-remove the ``LANDLOCK_ACCESS_FS_REFER`` access right which is only supported
-starting with the second version of the ABI.
+remove the ``LANDLOCK_ACCESS_FS_REFER`` or ``LANDLOCK_ACCESS_FS_TRUNCATE``
+access rights, which are only supported starting with the second and third
+version of the ABI.
.. code-block:: c
int abi;
abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
- if (abi < 2) {
+ if (abi < 0) {
+ /* Degrades gracefully if Landlock is not handled. */
+ perror("The running kernel does not enable to use Landlock");
+ return 0;
+ }
+ switch (abi) {
+ case 1:
+ /* Removes LANDLOCK_ACCESS_FS_REFER for ABI < 2 */
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
+ __attribute__((fallthrough));
+ case 2:
+ /* Removes LANDLOCK_ACCESS_FS_TRUNCATE for ABI < 3 */
+ ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
}
This enables to create an inclusive ruleset that will contain our rules.
@@ -127,8 +140,8 @@ descriptor.
It may also be required to create rules following the same logic as explained
for the ruleset creation, by filtering access rights according to the Landlock
-ABI version. In this example, this is not required because
-``LANDLOCK_ACCESS_FS_REFER`` is not allowed by any rule.
+ABI version. In this example, this is not required because all of the requested
+``allowed_access`` rights are already available in ABI 1.
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
@@ -252,6 +265,37 @@ To be allowed to use :manpage:`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_ACCESS_FS_TRUNCATE`` both change the contents of a file and sometimes
+overlap in non-intuitive ways. It is recommended to always specify both of
+these together.
+
+A particularly surprising example is :manpage:`creat(2)`. The name suggests
+that this system call requires the rights to create and write files. However,
+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
+``LANDLOCK_ACCESS_FS_WRITE_FILE`` right. Apart from the :manpage:`truncate(2)`
+system call, this can also be done through :manpage:`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 :manpage:`ftruncate(2)`. The behavior is
+similar to opening a file for reading or writing, where permissions are checked
+during :manpage:`open(2)`, but not during the subsequent :manpage:`read(2)` and
+:manpage:`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.
+
Compatibility
=============
@@ -398,6 +442,15 @@ Starting with the Landlock ABI version 2, it is now possible to securely
control renaming and linking thanks to the new ``LANDLOCK_ACCESS_FS_REFER``
access right.
+File truncation (ABI < 3)
+-------------------------
+
+File truncation could not be denied before the third Landlock ABI, so it is
+always allowed when using a kernel that only supports the first or second ABI.
+
+Starting with the Landlock ABI version 3, it is now possible to securely control
+truncation thanks to the new ``LANDLOCK_ACCESS_FS_TRUNCATE`` access right.
+
.. _kernel_support:
Kernel support
--
2.38.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH v9 11/11] landlock: Document Landlock's file truncation support
2022-10-08 11:13 ` [PATCH v9 11/11] landlock: Document Landlock's file truncation support Günther Noack
@ 2022-10-08 11:19 ` Günther Noack
0 siblings, 0 replies; 4+ messages in thread
From: Günther Noack @ 2022-10-08 11:19 UTC (permalink / raw)
To: linux-security-module
Cc: Mickaël Salaün, James Morris, Paul Moore,
Serge E . Hallyn, linux-fsdevel, Konstantin Meskhidze,
Nathan Chancellor
Sorry, please ignore this thread -- I messed it up and accidentally sent it with the wrong Reply-To headers.
—Günther
On Sat, Oct 08, 2022 at 01:13:36PM +0200, Günther Noack wrote:
> Use the LANDLOCK_ACCESS_FS_TRUNCATE flag in the tutorial.
>
> Adapt the backwards compatibility example and discussion to remove the
> truncation flag where needed.
>
> Point out potential surprising behaviour related to truncate.
>
> Signed-off-by: Günther Noack <gnoack3000@gmail.com>
> ---
> Documentation/userspace-api/landlock.rst | 67 +++++++++++++++++++++---
> 1 file changed, 60 insertions(+), 7 deletions(-)
>
> diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst
> index cec780c2f497..d8cd8cd9ce25 100644
> --- a/Documentation/userspace-api/landlock.rst
> +++ b/Documentation/userspace-api/landlock.rst
> @@ -8,7 +8,7 @@ Landlock: unprivileged access control
> =====================================
>
> :Author: Mickaël Salaün
> -:Date: September 2022
> +:Date: October 2022
>
> 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
> @@ -60,7 +60,8 @@ the need to be explicit about the denied-by-default access rights.
> LANDLOCK_ACCESS_FS_MAKE_FIFO |
> LANDLOCK_ACCESS_FS_MAKE_BLOCK |
> LANDLOCK_ACCESS_FS_MAKE_SYM |
> - LANDLOCK_ACCESS_FS_REFER,
> + LANDLOCK_ACCESS_FS_REFER |
> + LANDLOCK_ACCESS_FS_TRUNCATE,
> };
>
> Because we may not know on which kernel version an application will be
> @@ -69,16 +70,28 @@ should try to protect users as much as possible whatever the kernel they are
> using. To avoid binary enforcement (i.e. either all security features or
> none), we can leverage a dedicated Landlock command to get the current version
> of the Landlock ABI and adapt the handled accesses. Let's check if we should
> -remove the ``LANDLOCK_ACCESS_FS_REFER`` access right which is only supported
> -starting with the second version of the ABI.
> +remove the ``LANDLOCK_ACCESS_FS_REFER`` or ``LANDLOCK_ACCESS_FS_TRUNCATE``
> +access rights, which are only supported starting with the second and third
> +version of the ABI.
>
> .. code-block:: c
>
> int abi;
>
> abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
> - if (abi < 2) {
> + if (abi < 0) {
> + /* Degrades gracefully if Landlock is not handled. */
> + perror("The running kernel does not enable to use Landlock");
> + return 0;
> + }
> + switch (abi) {
> + case 1:
> + /* Removes LANDLOCK_ACCESS_FS_REFER for ABI < 2 */
> ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
> + __attribute__((fallthrough));
> + case 2:
> + /* Removes LANDLOCK_ACCESS_FS_TRUNCATE for ABI < 3 */
> + ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
> }
>
> This enables to create an inclusive ruleset that will contain our rules.
> @@ -127,8 +140,8 @@ descriptor.
>
> It may also be required to create rules following the same logic as explained
> for the ruleset creation, by filtering access rights according to the Landlock
> -ABI version. In this example, this is not required because
> -``LANDLOCK_ACCESS_FS_REFER`` is not allowed by any rule.
> +ABI version. In this example, this is not required because all of the requested
> +``allowed_access`` rights are already available in ABI 1.
>
> 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
> @@ -252,6 +265,37 @@ To be allowed to use :manpage:`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_ACCESS_FS_TRUNCATE`` both change the contents of a file and sometimes
> +overlap in non-intuitive ways. It is recommended to always specify both of
> +these together.
> +
> +A particularly surprising example is :manpage:`creat(2)`. The name suggests
> +that this system call requires the rights to create and write files. However,
> +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
> +``LANDLOCK_ACCESS_FS_WRITE_FILE`` right. Apart from the :manpage:`truncate(2)`
> +system call, this can also be done through :manpage:`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 :manpage:`ftruncate(2)`. The behavior is
> +similar to opening a file for reading or writing, where permissions are checked
> +during :manpage:`open(2)`, but not during the subsequent :manpage:`read(2)` and
> +:manpage:`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.
> +
> Compatibility
> =============
>
> @@ -398,6 +442,15 @@ Starting with the Landlock ABI version 2, it is now possible to securely
> control renaming and linking thanks to the new ``LANDLOCK_ACCESS_FS_REFER``
> access right.
>
> +File truncation (ABI < 3)
> +-------------------------
> +
> +File truncation could not be denied before the third Landlock ABI, so it is
> +always allowed when using a kernel that only supports the first or second ABI.
> +
> +Starting with the Landlock ABI version 3, it is now possible to securely control
> +truncation thanks to the new ``LANDLOCK_ACCESS_FS_TRUNCATE`` access right.
> +
> .. _kernel_support:
>
> Kernel support
> --
> 2.38.0
>
--
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v9 00/11] landlock: truncate support
@ 2022-10-08 10:09 Günther Noack
2022-10-08 11:18 ` [PATCH v9 10/11] samples/landlock: Extend sample tool to support LANDLOCK_ACCESS_FS_TRUNCATE Günther Noack
0 siblings, 1 reply; 4+ messages in thread
From: Günther Noack @ 2022-10-08 10:09 UTC (permalink / raw)
To: linux-security-module
Cc: Mickaël Salaün, James Morris, Paul Moore,
Serge E . Hallyn, linux-fsdevel, Konstantin Meskhidze,
Nathan Chancellor, Günther Noack
The goal of these patches is to work towards a more complete coverage
of file system operations that are restrictable with Landlock.
Motivation
----------
The known set of currently unsupported file system operations in
Landlock is described at [1]. Out of the operations listed there,
truncate is the only one that modifies file contents, so these patches
should make it possible to prevent the direct modification of file
contents with Landlock.
Apart from Landlock, file truncation can also be restricted using
seccomp-bpf, but it is more difficult to use (requires BPF, requires
keeping up-to-date syscall lists) and it is not configurable by file
hierarchy, as Landlock is. The simplicity and flexibility of the
Landlock approach makes it worthwhile adding.
Implementation overview
-----------------------
The patch introduces the truncation restriction feature as an
additional bit in the access_mask_t bitmap, in line with the existing
supported operations.
The truncation flag covers both the truncate(2) and ftruncate(2)
families of syscalls, as well as open(2) with the O_TRUNC flag.
This includes usages of creat() in the case where existing regular
files are overwritten.
Additionally, this patch set introduces a new Landlock security blob
associated with opened files, to track the available Landlock access
rights at the time of opening the file. This is in line with Unix's
general approach of checking the read and write permissions during
open(), and associating this previously checked authorization with the
opened file.
In order to treat truncate(2) and ftruncate(2) calls differently in an
LSM hook, we split apart the existing security_path_truncate hook into
security_path_truncate (for truncation by path) and
security_file_truncate (for truncation of previously opened files).
We also implement the file_alloc_security hook, in order to override
the access rights in the file security blob, in cases where the file
is opened by other means than open(2), but where the opened file still
supports ftruncate(2). This is also demonstrated in a selftest, using
memfd_create(2).
Relationship between "truncate" and "write" rights
--------------------------------------------------
While it's possible to use the "write file" and "truncate" rights
independent of each other, it simplifies the mental model for
userspace callers to always use them together.
Specifically, the following behaviours might be surprising for users
when using these independently:
* The commonly creat() syscall requires the truncate right when
overwriting existing files, as it is equivalent to open(2) with
O_TRUNC|O_CREAT|O_WRONLY.
* The "write file" right is not always required to truncate a file,
even through the open(2) syscall (when using O_RDONLY|O_TRUNC).
Nevertheless, keeping the two flags separate is the correct approach
to guarantee backwards compatibility for existing Landlock users.
When the "truncate" right is checked for ftruncate(2)
-----------------------------------------------------
Notably, for the purpose of ftruncate(2), the Landlock truncation
access right is looked up when *opening* the file, not when calling
ftruncate(). The availability of the truncate right is associated with
the opened file and is later checked to authorize ftruncate(2)
operations.
This is similar to how the write mode gets remembered after a
open(..., O_WRONLY) to authorize later write() operations.
These opened file descriptors can also be passed between processes and
will continue to enforce their truncation properties when these
processes attempt an ftruncate().
These patches are based on master, commit e8bc52cb8df8 ("Merge tag
'driver-core-6.1-rc1' of
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core").
Best regards,
Günther
[1] https://docs.kernel.org/userspace-api/landlock.html#filesystem-flags
Past discussions:
V1: https://lore.kernel.org/all/20220707200612.132705-1-gnoack3000@gmail.com/
V2: https://lore.kernel.org/all/20220712211405.14705-1-gnoack3000@gmail.com/
V3: https://lore.kernel.org/all/20220804193746.9161-1-gnoack3000@gmail.com/
V4: https://lore.kernel.org/all/20220814192603.7387-1-gnoack3000@gmail.com/
V5: https://lore.kernel.org/all/20220817203006.21769-1-gnoack3000@gmail.com/
V6: https://lore.kernel.org/all/20220908195805.128252-1-gnoack3000@gmail.com/
V7: https://lore.kernel.org/all/20220930160144.141504-1-gnoack3000@gmail.com/
V8: https://lore.kernel.org/all/20221001154908.49665-1-gnoack3000@gmail.com/
Changelog:
V9:
* Implement file_alloc_security hook
* Needs to grant all Landlock rights by default for use cases where
files are opened by other means than open(2), i.e. memfd_create(2)
* Discovered and fixed by Mickaël Salaün on his -next branch
* Add a selftest for the memfd_create(2) example
* file_open_hook: Reorder the logic a bit as discussed in review
* selftests: Return -errno from recv_fd() and send_fd()
* Rebase to master branch
* Reorder __maybe_unused patch before its use
* Various small formatting and documentation fixes in code,
documentation and commit messages
V8:
* landlock: Refactor check_access_path_dual() into
is_access_to_paths_allowed(), as suggested by Mickaël Salaün on the
v7 review. Added this as a separate commit.
* landlock truncate feature: inline get_path_access()
* Documentation: update documentation date to October 2022
* selftests: locally #define __maybe_unused (checkpatch started
complaining about it, but the header where it's defined is not
usable from selftests)
V7:
* security: Create file_truncate hook
* Fix the build on kernels without CONFIG_SECURITY_PATH (fixed by
Mickaël Salaün)
* lsm_hooks.h: Document file_truncate hook
* fs/open.c: undo accidental indentation changes
* landlock: Support file truncation
* Use the init_layer_masks() result as input for
check_access_path_dual()
* Naming
* Rename the landlock_file_security.allowed_access field
(previously called "rights")
* Rename get_path_access_rights() to get_path_access()
* Rename get_file_access() to get_required_file_open_access() to
avoid confusion with get_path_access()
* Use "access_request" for access_mask_t variables, access_req for
unsigned long
* Documentation:
* Fixed some comments according to review
* Added comments to get_required_file_open_access() and
init_layer_masks()
* selftests:
* remove unused variables
* rename fd0,...,fd3 to fd_layer0,...,fd_layer3.
* test_ftruncate: define layers on top and inline the helper function
* New tests (both added as separate commits)
* More exhaustive ftruncate test: Add open_and_ftruncate test that
exercises ftruncate more thoroughly with fixture variants
* FD-passing test: exercise restricted file descriptors getting
passed between processes, also using the same fixture variants
* Documentation: integrate review comments by Mickaël Salaün
* do not use contraptions (don't)
* use double backquotes in all touched lines
* add the read/write open() analogy to the truncation docs
* in code example, check for abi<0 explicitly and fix indentation
V6:
* LSM hooks: create file_truncate hook in addition to path_truncate.
Use it in the existing path_truncate call sites where appropriate.
* landlock: check LANDLOCK_ACCESS_FS_TRUNCATE right during open(), and
associate that right with the opened struct file in a security blob.
Introduce get_path_access_rights() helper function.
* selftests: test ftruncate in a separate test, to exercise that
the rights are associated with the file descriptor.
* Documentation: Rework documentation to reflect new ftruncate() semantics.
* Applied small fixes by Mickaël Salaün which he added on top of V5, in
https://git.kernel.org/pub/scm/linux/kernel/git/mic/linux.git/log/?h=next
(I hope I found them all.)
V5:
* Documentation
* Fix wording in userspace-api headers and in landlock.rst.
* Move the truncation limitation section one to the bottom.
* Move all .rst changes into the documentation commit.
* selftests
* Remove _metadata argument from helpers where it became unnecessary.
* Open writable file descriptors at the top of both tests, before Landlock
is enabled, to exercise ftruncate() independently from open().
* Simplify test_ftruncate and decouple it from exercising open().
* test_creat(): Return errno on close() failure (it does not conflict).
* Fix /* comment style */
* Reorder blocks of EXPECT_EQ checks to be consistent within a test.
* Add missing |O_TRUNC to a check in one test.
* Put the truncate_unhandled test before the other.
V4:
* Documentation
* Clarify wording and syntax as discussed in review.
* Use a less confusing error message in the example.
* selftests:
* Stop using ASSERT_EQ in test helpers, return EBADFD instead.
(This is an intentionally uncommon error code, so that the source
of the error is clear and the test can distinguish test setup
failures from failures in the actual system call under test.)
* samples/Documentation:
* Use additional clarifying comments in the kernel backwards
compatibility logic.
V3:
* selftests:
* Explicitly test ftruncate with readonly file descriptors
(returns EINVAL).
* Extract test_ftruncate, test_truncate, test_creat helpers,
which simplified the previously mixed usage of EXPECT/ASSERT.
* Test creat() behaviour as part of the big truncation test.
* Stop testing the truncate64(2) and ftruncate64(2) syscalls.
This simplifies the tests a bit. The kernel implementations are the
same as for truncate(2) and ftruncate(2), so there is little benefit
from testing them exhaustively. (We aren't testing all open(2)
variants either.)
* samples/landlock/sandboxer.c:
* Use switch() to implement best effort mode.
* Documentation:
* Give more background on surprising truncation behaviour.
* Use switch() in the example too, to stay in-line with the sample tool.
* Small fixes in header file to address previous comments.
* misc:
* Fix some typos and const usages.
V2:
* Documentation: Mention the truncation flag where needed.
* Documentation: Point out connection between truncation and file writing.
* samples: Add file truncation to the landlock/sandboxer.c sample tool.
* selftests: Exercise open(2) with O_TRUNC and creat(2) exhaustively.
* selftests: Exercise truncation syscalls when the truncate right
is not handled by Landlock.
Günther Noack (11):
security: Create file_truncate hook from path_truncate hook
landlock: Refactor check_access_path_dual() into
is_access_to_paths_allowed()
landlock: Document init_layer_masks() helper
landlock: Support file truncation
selftests/landlock: Test file truncation support
selftests/landlock: Test open() and ftruncate() in multiple scenarios
selftests/landlock: Locally define __maybe_unused
selftests/landlock: Test FD passing from restricted to unrestricted
processes
selftests/landlock: Test ftruncate on FDs created by memfd_create(2)
samples/landlock: Extend sample tool to support
LANDLOCK_ACCESS_FS_TRUNCATE
landlock: Document Landlock's file truncation support
Documentation/userspace-api/landlock.rst | 67 ++-
fs/namei.c | 2 +-
fs/open.c | 2 +-
include/linux/lsm_hook_defs.h | 1 +
include/linux/lsm_hooks.h | 10 +-
include/linux/security.h | 6 +
include/uapi/linux/landlock.h | 21 +-
samples/landlock/sandboxer.c | 12 +-
security/apparmor/lsm.c | 6 +
security/landlock/fs.c | 204 ++++++--
security/landlock/fs.h | 24 +
security/landlock/limits.h | 2 +-
security/landlock/setup.c | 1 +
security/landlock/syscalls.c | 2 +-
security/security.c | 5 +
security/tomoyo/tomoyo.c | 13 +
tools/testing/selftests/landlock/base_test.c | 38 +-
tools/testing/selftests/landlock/common.h | 85 +++-
tools/testing/selftests/landlock/fs_test.c | 468 ++++++++++++++++++-
19 files changed, 854 insertions(+), 115 deletions(-)
base-commit: e8bc52cb8df80c31c73c726ab58ea9746e9ff734
--
2.38.0
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH v9 10/11] samples/landlock: Extend sample tool to support LANDLOCK_ACCESS_FS_TRUNCATE
2022-10-08 10:09 [PATCH v9 00/11] landlock: truncate support Günther Noack
@ 2022-10-08 11:18 ` Günther Noack
2022-10-08 11:18 ` [PATCH v9 11/11] landlock: Document Landlock's file truncation support Günther Noack
0 siblings, 1 reply; 4+ messages in thread
From: Günther Noack @ 2022-10-08 11:18 UTC (permalink / raw)
To: linux-security-module
Cc: Mickaël Salaün, James Morris, Paul Moore,
Serge E . Hallyn, linux-fsdevel, Konstantin Meskhidze,
Nathan Chancellor, Günther Noack
Update the sandboxer sample to restrict truncate actions. This is
automatically enabled by default if the running kernel supports
LANDLOCK_ACCESS_FS_TRUNCATE, except for the paths listed in the
LL_FS_RW environment variable.
Signed-off-by: Günther Noack <gnoack3000@gmail.com>
---
samples/landlock/sandboxer.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c
index f29bb3c72230..fd4237c64fb2 100644
--- a/samples/landlock/sandboxer.c
+++ b/samples/landlock/sandboxer.c
@@ -76,7 +76,8 @@ static int parse_path(char *env_path, const char ***const path_list)
#define ACCESS_FILE ( \
LANDLOCK_ACCESS_FS_EXECUTE | \
LANDLOCK_ACCESS_FS_WRITE_FILE | \
- LANDLOCK_ACCESS_FS_READ_FILE)
+ LANDLOCK_ACCESS_FS_READ_FILE | \
+ LANDLOCK_ACCESS_FS_TRUNCATE)
/* clang-format on */
@@ -160,11 +161,12 @@ static int populate_ruleset(const char *const env_var, const int ruleset_fd,
LANDLOCK_ACCESS_FS_MAKE_FIFO | \
LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
LANDLOCK_ACCESS_FS_MAKE_SYM | \
- LANDLOCK_ACCESS_FS_REFER)
+ LANDLOCK_ACCESS_FS_REFER | \
+ LANDLOCK_ACCESS_FS_TRUNCATE)
/* clang-format on */
-#define LANDLOCK_ABI_LAST 2
+#define LANDLOCK_ABI_LAST 3
int main(const int argc, char *const argv[], char *const *const envp)
{
@@ -234,6 +236,10 @@ int main(const int argc, char *const argv[], char *const *const envp)
case 1:
/* Removes LANDLOCK_ACCESS_FS_REFER for ABI < 2 */
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
+ __attribute__((fallthrough));
+ case 2:
+ /* Removes LANDLOCK_ACCESS_FS_TRUNCATE for ABI < 3 */
+ ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
fprintf(stderr,
"Hint: You should update the running kernel "
--
2.38.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH v9 11/11] landlock: Document Landlock's file truncation support
2022-10-08 11:18 ` [PATCH v9 10/11] samples/landlock: Extend sample tool to support LANDLOCK_ACCESS_FS_TRUNCATE Günther Noack
@ 2022-10-08 11:18 ` Günther Noack
0 siblings, 0 replies; 4+ messages in thread
From: Günther Noack @ 2022-10-08 11:18 UTC (permalink / raw)
To: linux-security-module
Cc: Mickaël Salaün, James Morris, Paul Moore,
Serge E . Hallyn, linux-fsdevel, Konstantin Meskhidze,
Nathan Chancellor, Günther Noack
Use the LANDLOCK_ACCESS_FS_TRUNCATE flag in the tutorial.
Adapt the backwards compatibility example and discussion to remove the
truncation flag where needed.
Point out potential surprising behaviour related to truncate.
Signed-off-by: Günther Noack <gnoack3000@gmail.com>
---
Documentation/userspace-api/landlock.rst | 67 +++++++++++++++++++++---
1 file changed, 60 insertions(+), 7 deletions(-)
diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst
index cec780c2f497..d8cd8cd9ce25 100644
--- a/Documentation/userspace-api/landlock.rst
+++ b/Documentation/userspace-api/landlock.rst
@@ -8,7 +8,7 @@ Landlock: unprivileged access control
=====================================
:Author: Mickaël Salaün
-:Date: September 2022
+:Date: October 2022
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
@@ -60,7 +60,8 @@ the need to be explicit about the denied-by-default access rights.
LANDLOCK_ACCESS_FS_MAKE_FIFO |
LANDLOCK_ACCESS_FS_MAKE_BLOCK |
LANDLOCK_ACCESS_FS_MAKE_SYM |
- LANDLOCK_ACCESS_FS_REFER,
+ LANDLOCK_ACCESS_FS_REFER |
+ LANDLOCK_ACCESS_FS_TRUNCATE,
};
Because we may not know on which kernel version an application will be
@@ -69,16 +70,28 @@ should try to protect users as much as possible whatever the kernel they are
using. To avoid binary enforcement (i.e. either all security features or
none), we can leverage a dedicated Landlock command to get the current version
of the Landlock ABI and adapt the handled accesses. Let's check if we should
-remove the ``LANDLOCK_ACCESS_FS_REFER`` access right which is only supported
-starting with the second version of the ABI.
+remove the ``LANDLOCK_ACCESS_FS_REFER`` or ``LANDLOCK_ACCESS_FS_TRUNCATE``
+access rights, which are only supported starting with the second and third
+version of the ABI.
.. code-block:: c
int abi;
abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
- if (abi < 2) {
+ if (abi < 0) {
+ /* Degrades gracefully if Landlock is not handled. */
+ perror("The running kernel does not enable to use Landlock");
+ return 0;
+ }
+ switch (abi) {
+ case 1:
+ /* Removes LANDLOCK_ACCESS_FS_REFER for ABI < 2 */
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
+ __attribute__((fallthrough));
+ case 2:
+ /* Removes LANDLOCK_ACCESS_FS_TRUNCATE for ABI < 3 */
+ ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
}
This enables to create an inclusive ruleset that will contain our rules.
@@ -127,8 +140,8 @@ descriptor.
It may also be required to create rules following the same logic as explained
for the ruleset creation, by filtering access rights according to the Landlock
-ABI version. In this example, this is not required because
-``LANDLOCK_ACCESS_FS_REFER`` is not allowed by any rule.
+ABI version. In this example, this is not required because all of the requested
+``allowed_access`` rights are already available in ABI 1.
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
@@ -252,6 +265,37 @@ To be allowed to use :manpage:`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_ACCESS_FS_TRUNCATE`` both change the contents of a file and sometimes
+overlap in non-intuitive ways. It is recommended to always specify both of
+these together.
+
+A particularly surprising example is :manpage:`creat(2)`. The name suggests
+that this system call requires the rights to create and write files. However,
+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
+``LANDLOCK_ACCESS_FS_WRITE_FILE`` right. Apart from the :manpage:`truncate(2)`
+system call, this can also be done through :manpage:`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 :manpage:`ftruncate(2)`. The behavior is
+similar to opening a file for reading or writing, where permissions are checked
+during :manpage:`open(2)`, but not during the subsequent :manpage:`read(2)` and
+:manpage:`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.
+
Compatibility
=============
@@ -398,6 +442,15 @@ Starting with the Landlock ABI version 2, it is now possible to securely
control renaming and linking thanks to the new ``LANDLOCK_ACCESS_FS_REFER``
access right.
+File truncation (ABI < 3)
+-------------------------
+
+File truncation could not be denied before the third Landlock ABI, so it is
+always allowed when using a kernel that only supports the first or second ABI.
+
+Starting with the Landlock ABI version 3, it is now possible to securely control
+truncation thanks to the new ``LANDLOCK_ACCESS_FS_TRUNCATE`` access right.
+
.. _kernel_support:
Kernel support
--
2.38.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2022-10-08 11:19 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-08 11:13 [PATCH v9 10/11] samples/landlock: Extend sample tool to support LANDLOCK_ACCESS_FS_TRUNCATE Günther Noack
2022-10-08 11:13 ` [PATCH v9 11/11] landlock: Document Landlock's file truncation support Günther Noack
2022-10-08 11:19 ` Günther Noack
-- strict thread matches above, loose matches on Subject: below --
2022-10-08 10:09 [PATCH v9 00/11] landlock: truncate support Günther Noack
2022-10-08 11:18 ` [PATCH v9 10/11] samples/landlock: Extend sample tool to support LANDLOCK_ACCESS_FS_TRUNCATE Günther Noack
2022-10-08 11:18 ` [PATCH v9 11/11] landlock: Document Landlock's file truncation support Günther Noack
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).