-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
setpriv: add landlock support #2628
Conversation
89e5a5d
to
89f195b
Compare
It would be nice to describe how to use the command line option here. |
My hope was that the unittests provide enough examples for the RFC. Note: the CLI makes most sense with an understanding of landlock itself. |
I have read the PR and the CI test, but I am still not sure about --landlock-{access,rule} relation and syntax for the options' arguments ;-) |
I'm always a little bit nervous when I see something so complex like: |
Some quick docs, I'll write something better on the weekend:
At the moment only filesystem access with |
d0db3eb
to
1b786da
Compare
Thanks, now it makes more sense ;-) The LANDLOCK_ACCESS_* (and --landlock-access) is a strange name if used to deny access. Having --landlock-deny and --landlock-allow would be more readable, but I understand you want to follow kernel. |
2112253
to
f3b29d2
Compare
Ad license, on Fedora we have a |
f3b29d2
to
0a9ffa3
Compare
landlock [0] is a Linux stackable LSM that can be used by unprivileged processes to build a sandbox around them. With support for landlock in setpriv users can easily construct a sandbox on-the-fly when executing programs. [0] https://landlock.io/ Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
0a9ffa3
to
ae015d7
Compare
@@ -87,6 +87,16 @@ _setpriv_module() | |||
COMPREPLY=( $(compgen -W "profile" -- $cur) ) | |||
return 0 | |||
;; | |||
'--landlock-access') | |||
# FIXME: how to list landlock accesses? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Landlock does not currently provide an API to list all existing Landlock accesses with their names. You need to use the ones from the header.
If this TODO is about listing the accesses that are already enforced, that is also not currently possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can rely on the Landlock ABI version to infer the supported access rights, but we indeed need to have the name mapping. I don't think this is an issue because util-linux would need to know how to use the new access rights anyway, so if they are not part of the code there is no need to use them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
My main concern is about potential compatibility issues with older kernels or newer util-linux, see my comments.
size_t i; | ||
|
||
/* without argument, match all */ | ||
if (list[0] == '\0') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might lead to unknown restrictions (from the user point of view) being enforced when updating util-linux with an extended landlock_access_fs
definition. For instance, handling a new "ioctl" access right might deny legitimate IOCTL commands without the user noticing. In a nutshell, not specifying any handled access might lead to restricting all util-linux's known access rights, which might lead to an unknown/undeterministic behavior of the sandboxed applications. See the kernel documentation or the Rust library documentation.
Specifying all handled access rights is verbose, and I agree that it would help a lot to be able to not list all of them.
An alternative would be to collect all rules' access rights (which must be specified anyway) and put them here. Access rights that must be denied (and not used in any rule) would still need to be specified though.
An other alternative would be to specify a fixed set of handled access rights, e.g. using a Landlock ABI version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setpriv
is a fairly lowlevel tool. So in my opinion it would be fine to force users to specify explicitly what they want if they need longterm deterministic behavior.
As a default I would like to keep the API as close to the kernel as possible, providing users with the possibility to discover which rules are supported by the kernel and util-linux via exitcodes.
(I see that this also needs to be reworked)
This should be better documented.
Then on top of the base functionality we could add userfriendly extensions.
size_t i; | ||
|
||
if (strcmp(str, "fs") == 0) { | ||
for (i = 0; i < ARRAY_SIZE(landlock_access_fs); i++) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might also be an issue with new versions of util-linux extending landlock_access_fs
.
|
||
path++; | ||
|
||
parent_fd = open(path, O_RDONLY | O_PATH | O_CLOEXEC); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to be able to specify a file descriptor with a path-beneath
argument. Indeed, Landlock's rules supports FDs, and it might be convenient, safer and most importantly race-free for rule building. Maybe something like setpriv --landlock-rule path-beneath:read:fd:0
? Relying on /proc/self/fd/*
might be another way but maybe a bit hacky (and not possible without /proc). Note that restrictions only applies to newly opened files though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good idea.
I'm a bit unhappy with path-beneath:read:fd:0
as it would break the structure compared to file paths. So specifying fd:0
as a filename would not be possible directly.
I like the /proc/self/fd
paths. I don't expect setpriv to be used without /proc
being mounted. Or we could special-case /proc/self/fd/
arguments and parse out the number.
|
||
ret = landlock_add_rule(fd, rule->rule_type, &rule->path_beneath_attr, 0); | ||
if (ret == -1) | ||
err(SETPRIV_EXIT_PRIVERR, _("adding landlock rule failed")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice to be able to specify a best-effort approach to still enable partial restriction even if the (old) running kernel doesn't support all util-linux's known access rights. For instance, with the current approach, not specifying --landlock-access
might work on the user's system with one version of util-linux but not with a newer version. Likewise, users using an old kernel that only supports a subset of landlock_access_fs
would not be able to use Landlock with setpriv unless they specify --landlock-access
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess a new CLI flag would fit nicely here.
@@ -87,6 +87,16 @@ _setpriv_module() | |||
COMPREPLY=( $(compgen -W "profile" -- $cur) ) | |||
return 0 | |||
;; | |||
'--landlock-access') | |||
# FIXME: how to list landlock accesses? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can rely on the Landlock ABI version to infer the supported access rights, but we indeed need to have the name mapping. I don't think this is an issue because util-linux would need to know how to use the new access rights anyway, so if they are not part of the code there is no need to use them.
FWIW, the kernel wording is "handled" which can be translated to "denied unless allowed by a rule". |
landlock [0] is a Linux stackable LSM that can be used by unprivileged processes to build a sandbox around them.
With support for landlock in setpriv users can easily construct a sandbox on-the-fly when executing programs.
[0] https://landlock.io/
Note: This is only an RFC state, missing help, completions and docs.