diff options
author | Mickaël Salaün <mic@digikod.net> | 2022-05-06 18:10:59 +0200 |
---|---|---|
committer | Mickaël Salaün <mic@digikod.net> | 2022-05-23 13:28:00 +0200 |
commit | 76b902f874ff4de9c1078489d4c7678a64105ea6 (patch) | |
tree | 2b890621d9978d414c76f83952e29608833b88c1 /samples | |
parent | f4056b9266b571c63f30cda70c2d89f7b7e8bb7b (diff) |
samples/landlock: Add support for file reparenting
Add LANDLOCK_ACCESS_FS_REFER to the "roughly write" access rights and
leverage the Landlock ABI version to only try to enforce it if it is
supported by the running kernel.
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-10-mic@digikod.net
Diffstat (limited to 'samples')
-rw-r--r-- | samples/landlock/sandboxer.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c index c089e9cdaf32..3e404e51ec64 100644 --- a/samples/landlock/sandboxer.c +++ b/samples/landlock/sandboxer.c @@ -159,7 +159,11 @@ out_free_name: LANDLOCK_ACCESS_FS_MAKE_SOCK | \ LANDLOCK_ACCESS_FS_MAKE_FIFO | \ LANDLOCK_ACCESS_FS_MAKE_BLOCK | \ - LANDLOCK_ACCESS_FS_MAKE_SYM) + LANDLOCK_ACCESS_FS_MAKE_SYM | \ + LANDLOCK_ACCESS_FS_REFER) + +#define ACCESS_ABI_2 ( \ + LANDLOCK_ACCESS_FS_REFER) /* clang-format on */ @@ -167,10 +171,11 @@ int main(const int argc, char *const argv[], char *const *const envp) { const char *cmd_path; char *const *cmd_argv; - int ruleset_fd; + int ruleset_fd, abi; + __u64 access_fs_ro = ACCESS_FS_ROUGHLY_READ, + access_fs_rw = ACCESS_FS_ROUGHLY_READ | ACCESS_FS_ROUGHLY_WRITE; struct landlock_ruleset_attr ruleset_attr = { - .handled_access_fs = ACCESS_FS_ROUGHLY_READ | - ACCESS_FS_ROUGHLY_WRITE, + .handled_access_fs = access_fs_rw, }; if (argc < 2) { @@ -196,12 +201,11 @@ int main(const int argc, char *const argv[], char *const *const envp) return 1; } - ruleset_fd = - landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); - if (ruleset_fd < 0) { + abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION); + if (abi < 0) { const int err = errno; - perror("Failed to create a ruleset"); + perror("Failed to check Landlock compatibility"); switch (err) { case ENOSYS: fprintf(stderr, @@ -221,13 +225,23 @@ int main(const int argc, char *const argv[], char *const *const envp) } return 1; } - if (populate_ruleset(ENV_FS_RO_NAME, ruleset_fd, - ACCESS_FS_ROUGHLY_READ)) { + /* Best-effort security. */ + if (abi < 2) { + ruleset_attr.handled_access_fs &= ~ACCESS_ABI_2; + access_fs_ro &= ~ACCESS_ABI_2; + access_fs_rw &= ~ACCESS_ABI_2; + } + + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + if (ruleset_fd < 0) { + perror("Failed to create a ruleset"); + return 1; + } + if (populate_ruleset(ENV_FS_RO_NAME, ruleset_fd, access_fs_ro)) { goto err_close_ruleset; } - if (populate_ruleset(ENV_FS_RW_NAME, ruleset_fd, - ACCESS_FS_ROUGHLY_READ | - ACCESS_FS_ROUGHLY_WRITE)) { + if (populate_ruleset(ENV_FS_RW_NAME, ruleset_fd, access_fs_rw)) { goto err_close_ruleset; } if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { |