-
Notifications
You must be signed in to change notification settings - Fork 355
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
Pass process user integration test #243
Conversation
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 leaves us with three scenarios:
Unprivileged user starting a rootless container: The main process is running as an unprivileged user and therefore cannot write the mapping until "deny" has been written to /proc/{pid}/setgroups. Once written /proc/{pid}/setgroups cannot be reset and the setgroups system call will be disabled for all processes in this user namespace. This also means that we should detect if the user is unprivileged and additional gids have been specified and bail out early as this can never work.
Privileged user starting a rootless container: It is not necessary to write "deny" to /proc/setgroups in order to create the gid mapping and therefore we don't. This means that setgroups could be used to drop groups, but this is fine as the user is privileged and could do so anyway.
We should check if the specified supplemental groups fall into the range that are specified in the gid mapping and bail out early if they do not.
Privileged user starting a normal container: Just add the supplementary groups.
Can you put the discussion into comments about the use of in the code. Those discussion are really good and I think they belong in the code, rather than PR.
b2bf981
to
a581129
Compare
Codecov Report
@@ Coverage Diff @@
## main #243 +/- ##
==========================================
- Coverage 38.36% 37.77% -0.59%
==========================================
Files 15 15
Lines 1366 1387 +21
Branches 372 379 +7
==========================================
Hits 524 524
- Misses 673 694 +21
Partials 169 169 |
@yihuaf PTAL |
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.
LGTM, and in my opinion much easier to follow with the added comments. Just two minor questions.
nix::unistd::setgroups(&gids).context("failed to set supplementary gids")?; | ||
} | ||
// this should have been detected during validation | ||
_ => unreachable!( |
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.
Under what circumstance where is branch get triggered? Isn't match option can only be either Some or None?
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.
The Some has a match guard, so this is only triggered when the user is not privileged. Ideally I could write
None | Some(r) if r. privileged
but Rust does not allow that (yet).
Making this test pass is easy enough (just add the supplementary groups using setgroups system call) but there are some subtleties around this for rootless containers due to CVE-2014-8989.
The gist of this priviledge escalation is: Before 3.19 it was possible for an unprivileged user to enter an user namespace, become root and then call setgroups in order to drop membership in supplementary groups. This allowed access to files which blocked access based on being a member of these groups.
This leaves us with three scenarios:
Unprivileged user starting a rootless container: The main process is running as an unprivileged user and therefore cannot write the mapping until "deny" has been written to /proc/{pid}/setgroups. Once written /proc/{pid}/setgroups cannot be reset and the setgroups system call will be disabled for all processes in this user namespace. This also means that we should detect if the user is unprivileged and additional gids have been specified and bail out early as this can never work.
Privileged user starting a rootless container: It is not necessary to write "deny" to /proc/setgroups in order to create the gid mapping and therefore we don't. This means that setgroups could be used to drop groups, but this is fine as the user is privileged and could do so anyway.
We should check if the specified supplemental groups fall into the range that are specified in the gid mapping and bail out early if they do not.
Privileged user starting a normal container: Just add the supplementary groups.
I noticed some problems when testing with rootless containers, which are not directly related to this feature and fixed them: