-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
libct/cap: switch to moby/sys/capability, lazy init #4358
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.
LGTM; left one suggestion (not blocking)
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, thanks!
This still LGTM. Let me know if it's ready, IMHO this is ready to merge. |
@kolyshkin was the last commit intended for this PR, or for a follow up? |
I can split this PR into two, but really I want all this to be merged (and you don't have to re-review the first two commits). |
This comment was marked as outdated.
This comment was marked as outdated.
Please don't tag people you don't know. These are definitely not those who can help. We will figure it out. |
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 mostly LGTM, left some comments
out = append(out, v) | ||
} | ||
} | ||
return out | ||
} | ||
inheritable := capSlice(capConfig.Inheritable, nil) | ||
// Ambient vector can not contain values not raised in the Inheritable vector, |
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 whole sentence from: https://pkg.go.dev/kernel.org/pub/linux/libs/security/libcap/cap#section-readme is:
Note, the Ambient vector cannot contain values not raised in the Inh vector, so setting values directly in one vector may have the side effect of mirroring the value in the other vector to maintain this constraint
I guess we want to ignore it, instead of adding it, as we are doing for a long time now. But wanted to raise this, just in case.
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.
Yes, that library raises inheritable bits where the corresponding ambient bits are raised.
I agree that we should not change the behavior (and instead maybe document that if you want to raise ambient caps, you have to raise inheritable ones as well).
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.
SGTM
a4dfbc8
to
97b707f
Compare
No longer a draft; PTAL @lifubang @AkihiroSuda @thaJeztah |
// compatibility we have to ignore those Ambient caps that are not also raised | ||
// in Inheritable (and issue a warning). | ||
ambient := capSlice(capConfig.Ambient, inheritable) | ||
if len(ignoredCaps) > 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.
There are at least 2 conditions to return error when setting ambient caps:
- The ambient cap sets is not in both permitted and inheritable cap sets;
- The PR_CAP_AMBIENT_LOWER securebit has been set.
So maybe this is not enough. I take another easy way to implement this compatibility. (#4418)
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 PR handles condition 1. As for condition 2, it works as it used to work before, no changes needed here.
In general, I think, we should return an error when we're unable to set a capability requested. The warning which this PR adds is a temporary measure, to ensure we're not breaking our users. Eventually this warning should become an error.
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 PR handles condition 1.
Because of ‘both permitted and inheritable cap sets’.
Even in condition 1, I think you need to add check ‘permitted’ too, not only ‘inheritable’. Please see my first commit in #4418 .
As for condition 2, it works as it used to work before, no changes needed here.
I think this error was also masked before this PR, but will be failed in the future. It should have a compatibility like condition 1.
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.
Even in condition 1, I think you need to add check ‘permitted’ too, not only ‘inheritable’. Please see my first commit in #4418 .
It looks like such configuration is not working in the current runc version:
@test "runc run [raise inheritable bit not set in permitted]" {
update_config ' .process.capabilities.inheritable = ["CAP_KILL"]
| .process.capabilities.permitted = ["CAP_CHOWN"]'
# | .process.capabilities.ambient = ["CAP_KILL", "CAP_CHOWN"]'
runc run testct
[ "$status" -eq 0 ]
runc run testct (status=1):
time="2024-09-27T17:31:28-07:00" level=error msg="runc run failed: unable to start container process: error during container init: unable to apply caps: operation not permitted"
This means:
- If it's not working now, it should not start work in the future.
- We don't have to check for permitted bit set when checking ambient.
As for condition 2, it works as it used to work before, no changes needed here.
I think this error was also masked before this PR, but will be failed in the future. It should have a compatibility like condition 1.
You might be right, I need to check it.
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 looks like such configuration is not working in the current runc version:
ff2e3dd
to
e954d45
Compare
@cyphar @AkihiroSuda PTAL |
@AkihiroSuda There is at least one error in this PR(#4358 (comment)), I suggest to wait |
@lifubang Thanks, but can you elaborate on what is the error exactly? The link to a test case, what does that mean? Should that test fail? Or is it working and it shouldn't? Is that before/after the PR? What do you want to show exactly? I'll check-out this branch and test myself, but it would be great if you can elaborate more on your concern. |
#4358 (comment)
It means the regression 1. So, how about merge this test case first to ensure we can't introduce any regression in the future? |
I think we can split this PR to 3 PRs, then we can push the progress more easily. But unfortunately, there are still some bugs in github.com/moby/sys/capability. So we need to wait a new release of it. |
@lifubang I fully agree, let's make this PR be 1 or 1 and 2. And PR 3 can be done later, maybe even after the 1.2.0 release (I'm not sure I'd hold the release for adding a warning, especially something that has been like this for a long time). @kolyshkin what do you think? |
Unfortunately it does change the behavior, because of the bug in the original package which is fixed in the fork (kolyshkin/capability#3). Even if we try to work around this (set the AMBIENT caps separately and ignore the error), it will still change the behavior, because the fork returns the error as soon as it has it, while the original package keep going and tries to set all capabilities. To solve this, we need something like |
More like "missing functionality" (of setting ambient capabilities one by one), although we can actually use x/sys/unix for that. The only bug I'm aware of is this one, and it does not affect runc in any way. |
Yes, like #4418, it is the final usage after we release |
b9a4909
to
490ab7a
Compare
490ab7a
to
fc9a0a6
Compare
moby/sys/capability v0.4.0 released; this PR is rebased and (hopefully) ready for review. PTAL @thaJeztah @lifubang |
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
A map which is created in func init is only used by capSlice, which is only used by New, which is only used by runc init. Switch to lazy init to slightly save on startup time. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This removes the last unversioned package in runc's direct dependencies. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
fc9a0a6
to
6696982
Compare
This has started as a simple way to reduce init() overhead in libcontainer/capabilities, but ended up switching to the fork of gocapability package, and also fixing a big issue in handling of ambient capabilities.
Please see individual commits for details; I will open an issue about ambient caps tomorrow.