Skip to content
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

Ensure we resolve tags once. #776

Merged
merged 1 commit into from
Sep 24, 2021
Merged

Conversation

mattmoor
Copy link
Member

@mattmoor mattmoor commented Sep 24, 2021

As I've been refactoring things, I noticed a handful of places where a single command potentially used a name.Tag multiple times for remote access. There is an exceedingly small window here for a race to happen where the first tag access points to one image, and the subsequent access points to another.

I've already fixed a handful of these, and this change fixes one more (in sget IIRC), but also tries to add some defensive logic in a few places where we were already doing the right thing.

The defensive logic I added is to clobber ref with digest after resolving the reference:

       digest, err := ociremote.ResolveDigest(ref, regOpts.ClientOpts(ctx)...)
       if err != nil {
               return err
       }
       // Overwrite "ref" with a digest to avoid a race where we use a tag
       // multiple times, and it potentially points to different things at
       // each access.
       ref = digest // nolint

This ensures that regardless of which reference is used below resolution, we always get what we resolved at this point.

There are some other superficial cleanups lumped in, which I noticed as I skimmed the code.

Signed-off-by: Matt Moore [email protected]

Ticket Link

Release Note

NONE

As I've been refactoring things, I noticed a handful of places where a single command potentially used a `name.Tag` multiple times for remote access.  There is an exceedingly small window here for a race to happen where the first tag access points to one image, and the subsequent access points to another.

I've already fixed a handful of these, and this change fixes one more (in `sget` IIRC), but also tries to add some defensive logic in a few places where we were already doing the right thing.

The defensive logic I added is to clobber `ref` with `digest` after resolving the reference:
```go
       digest, err := ociremote.ResolveDigest(ref, regOpts.ClientOpts(ctx)...)
       if err != nil {
               return err
       }
       // Overwrite "ref" with a digest to avoid a race where we use a tag
       // multiple times, and it potentially points to different things at
       // each access.
       ref = digest
```

This ensures that regardless of which reference is used below resolution, we always get what we resolved at this point.

There are some other superficial cleanups lumped in, which I noticed as I skimmed the code.

Signed-off-by: Matt Moore <[email protected]>
@dekkagaijin
Copy link
Member

dekkagaijin commented Sep 24, 2021

We should make sure ~all of the library to take digests (name.Digest, v1.Image, v1.Descriptor, the new oci types) explicitly. Helps avoid footguns and evangelizes the good word of content addressability.

@dekkagaijin dekkagaijin merged commit f7c3a20 into sigstore:main Sep 24, 2021
@github-actions github-actions bot added this to the v1.3.0 milestone Sep 24, 2021
@mattmoor mattmoor deleted the resolve-once branch September 24, 2021 01:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants