-
Notifications
You must be signed in to change notification settings - Fork 1.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
Image verification for namespaced policies #8212
Conversation
f3285a9
to
d104419
Compare
@harche feel free to ping here if you need assistance or review. |
8126007
to
8231d9f
Compare
8231d9f
to
aa5a6c6
Compare
8853f7b
to
6fae2e4
Compare
internal/storage/image.go
Outdated
if err != nil && !errors.Is(err, storage.ErrImageUnknown) { | ||
return fmt.Errorf("error retrieving image %s: %w", configImage, err) | ||
} | ||
if img != nil { |
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.
perhaps double check the length of img here.
It should >= 1 in this context.
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 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.
Right, but the length of the array could be zero, and we are indexing into 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.
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'm going to retract my comment here... I think the better approach is to check if err != nil if the alternative case, on line 542, and remove the if img != nil
entirely.
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.
you can have err == nil
and img == nil
at the same time. It just means that, there was no error looking up in the image store but the image doesn't exist in that store.
6fae2e4
to
f0c7e69
Compare
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 unit test mocks needs to be updated (see GitHub actions).
Is this still work in progress (WIP)?
f0c7e69
to
51c7108
Compare
51c7108
to
bbbc96d
Compare
/retest-required |
Signed-off-by: Peter Hunt <pehunt@redhat.com>
Signed-off-by: Peter Hunt <pehunt@redhat.com>
Signed-off-by: Peter Hunt <pehunt@redhat.com>
which protects us against cases where the user_defined_image isn't specified (like for container restores) Signed-off-by: Peter Hunt <pehunt@redhat.com>
We already have access to the storage reference, so we should use it Signed-off-by: Peter Hunt <pehunt@redhat.com>
…mage Signed-off-by: Peter Hunt <pehunt@redhat.com>
Signed-off-by: Peter Hunt <pehunt@redhat.com>
Signed-off-by: Peter Hunt <pehunt@redhat.com>
eac32f6
to
fbd73b3
Compare
/lgtm (had to update the CR test) |
/override ci/prow/ci-rhel-critest |
@haircommander: Overrode contexts on behalf of haircommander: ci/prow/ci-rhel-critest In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
/retest |
/override ci/prow/ci-rhel-critest |
@haircommander: Overrode contexts on behalf of haircommander: ci/prow/ci-rhel-critest In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
/retest |
/override ci/prow/ci-rhel-critest |
@haircommander: Overrode contexts on behalf of haircommander: ci/prow/ci-rhel-critest In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
/override ci/prow/ci-rhel-critest |
@haircommander: Overrode contexts on behalf of haircommander: ci/prow/ci-rhel-critest In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
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.
Late review … now comprehensive.
I’ll file a PR for some parts, and an issue for the remaining outstanding things.
imageID, err := storage.ParseStorageImageIDFromOutOfProcessData("2a03a6059f21e150ae84b0973863609494aad70f0a80eaeb64bddd8d92465812") | ||
Expect(err).ToNot(HaveOccurred()) | ||
otherImageID, err := storage.ParseStorageImageIDFromOutOfProcessData("3a03a6059f21e150ae84b0973863609494aad70f0a80eaeb64bddd8d92465812") | ||
canonicalImageCandidate, err := reference.WithDigest(imageCandidate.Raw(), digest.Digest("sha256:340d9b015b194dc6e2a13938944e0d016e57b9679963fdeb9ce021daac430221")) |
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 is not representative; PullImage
returns a name@
digest, this is name:
tag@
digest.
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.
Fixed in #8590 .
@@ -26,7 +26,7 @@ function teardown() { | |||
@test "run container in pod with image ID" { | |||
start_crio | |||
pod_id=$(crictl runp "$TESTDATA"/sandbox_config.json) | |||
jq '.image.image = "'"$REDIS_IMAGEID"'"' \ | |||
jq '.image.image = "'"$REDIS_IMAGEID"'" | .image.user_specified_image = "'"$REDIS_IMAGEDIGEST"'"' \ |
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.
In the three instances in this file, image.user_specified_image
is already set (to name:tag) in container_config.json
; is there a specific need to override that to a digest value?
Or is that just for consistency with the other tests that override both .image.image
and .image.user_specified_image
?
select(.repoTags[0] == "quay.io/crio/hello-wasm:latest") | | ||
"WASM_IMAGEID=" + .id + "\n" + | ||
"WASM_IMAGEDIGEST=" + .repoDigests[0] + "\n" + | ||
"REDIS_IMAGEREF=" + .repoDigests[0]' <<< "$json")" |
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.
Is this a copy&paste error?
@@ -328,7 +332,8 @@ type ContainerOption func(*cri.ContainerConfig) error | |||
func WithImage(image string) ContainerOption { |
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 can’t see any users of this.)
@@ -316,7 +316,7 @@ func (r *runtimeService) CreatePodSandbox(systemContext *types.SystemContext, po | |||
if imageAuthFile != "" { | |||
sourceCtx.AuthFilePath = imageAuthFile | |||
} | |||
ref, err = r.storageImageServer.PullImage(context.Background(), pauseImage, &ImageCopyOptions{ | |||
ref, _, err = r.storageImageServer.PullImage(context.Background(), pauseImage, &ImageCopyOptions{ |
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 is probably good enough because the pause image is ~trusted, and because MCO sets up the signature policy in a way that doesn’t let users loosen it, IIRC.
Ideally the returned repo@digest would be used to determine img
below, so that the code uses exactly the just-pulled image.
And then the first return value of PullImage
becomes unused and can be dropped entirely, simplifying the code.
Perhaps the repo@digest return value should be a RegistryImageReference
, not a raw reference.Canonical
.
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.
Done in #8590.
// | ||
// Arguments: | ||
// - ctx: The context for controlling the function's execution | ||
// - systemContext: server's system context for the given namespace |
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.
…, notably might have a customized SignaturePolicyPath
.
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.
Fixed in #8590.
} | ||
}() | ||
|
||
if err := svc.checkSignature(ctx, systemContext, policyContext, imageName, imageID); err != nil { |
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’m not sure why splitting this function into two is valuable, but it also doesn’t hurt.)
return nil | ||
} | ||
|
||
func (svc *imageService) checkSignature(ctx context.Context, sys *types.SystemContext, policyContext *signature.PolicyContext, imageName RegistryImageReference, imageID StorageImageID) 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.
s/imageName/userSpecifiedImage/
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.
Fixed in #8590.
return nil, fmt.Errorf("get context for namespace: %w", err) | ||
} | ||
|
||
if systemCtx.SignaturePolicyPath != "" { |
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.
Hum, do we want/need this condition here? It basically hard-codes the MCO behavior that the per-namespace policy is never more restrictive than the system policy.
That is fine for us right now, but it might not be true forever.
Does this exist for the container restore RootFSImage{Name,Ref}
uses?
I guess that, at the very least, the two conditions (here and in the container restore path) should document this assumption.
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.
Commented in #8590 .
// and it is meaningless to try to verify an image that isn't even an image | ||
// (like a checkpointed file is). |
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 don’t think we get here in the container restore path where Image.Image
is at tar file; we have already successfully found a c/storage imgResult
at this point.
What type of PR is this?
/kind feature
What this PR does / why we need it:
Adds support for verification using namespaced policies during container creation.
Which issue(s) this PR fixes:
None
Special notes for your reviewer:
Does this PR introduce a user-facing change?