-
Notifications
You must be signed in to change notification settings - Fork 10
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
Compatibility mode #58
base: main
Are you sure you want to change the base?
Conversation
WIP: This implementation works by leveraging CompatLevel that may need to be replaced. We also need to remove the public set_compatibility(). The use of new() might change because of future access right groups development. Signed-off-by: Mickaël Salaün <[email protected]>
WIP: Clean up the CompatLevel side and correctly handle PathBeneath's compat state. WIP: replacing disable_sandbox_if_unmet() with if_unmet(Consequence), which handles ReturnError. Use case appliances handling a minimal kernel version that is known to support a specific set of Landlock features, but that might use a newer kernel and then opportunistically restrict processes furthermore. This is equivalent to call disable_sandbox_if_unmet(true) is equivalent to set_compatibility(CompatLevel::SoftRequirement) and disable_sandbox_if_unmet(false) is equivalent to set_compatibility(previous_compat_level). Signed-off-by: Mickaël Salaün <[email protected]>
TODO: Squash with previous commit that adds CompatArg Signed-off-by: Mickaël Salaün <[email protected]>
From usage stand point, it would be better to make By making |
As explained in the documentation, the best-effort approach should be the default. The main point being that app developers don't know the kernel on which their app is running, and we want to protect users as much as possible.
I think most users trust (or hope) developers implement the best secure solution for their usage. Most of the time users would not get a false sense of security because they may not see any security message implying that. This is different when developping and testing a sandboxed software where we can control the kernel version and make sure it works (and restrict) as expected. This is why it is still handy to be able to change this behavior at run (or start) time. |
(Sorry about the delay with my response, I missed your previous comment.)
Generally, I agree that software should take best-effort security approach when deployed. My only concern is about what the default value configured for As a concrete example, let's assume a developer built an application with If the default mode for As I wrote this down, I started thinking it may be unreasonable to expect every application to add '--compat-mode' argument and pass appropriate flags to Landlock. This could be a reason to choose
Understood. |
What is best? To protect users as much as possible (according to their running kernel), or to only protect users that are using the same kernel version as the developer? Good sandboxing is transparent sandboxing, so users should not notice any difference. So getting a false impression of security would not make much sense is this cases. However, thanks to this crate's error codes, developers can still inform users that they should update their kernel to get a better protection.
In this case, most users would just try to disable sandboxing to get a working application, and I understand them. For instance, we can look for the number of questions for how to disable SELinux because something is not working as expected.
This is indeed one way to do it, but I prefer by default for things to just work, and optionally print a warning.
Indeed. We should make it simpler to protect most users by default.
|
Update
Ruleset::new()
to take aCompatMode
argument, and add the required dependencies to handle incompatibility consequences withif_unmet()
,CompatAccess
...See rationale here: https://fosdem.org/2023/schedule/event/rust_backward_and_forward_compatibility_for_security_features/
Proposal:
Ruleset
to be able to enforce a "hard requirement" for everything (set to "best effort" with thedefault()
constructor: Use Ruleset::default() instead of Ruleset::new() #44);Example with current API:
Same example with the proposed API:
Example with the best effort behavior:
This design is simpler and it removes the mutable builder property (multiple
.set_compatibility()
calls) that may be confusing and error prone.I started working on that a while ago but the code is still WIP.