Skip to content

Commit 1453679

Browse files
Merge pull request #19037 from miminar/naughty-image-signature-annotation
Automatic merge from submit-queue (batch tested with PRs 18905, 18968, 19016, 19037, 19056). Drop image signature annotations Because they were never meant to be allowed. Includes and superseds #19030 (kudos to @deads2k) Closes #19011 Resolves: [rhbz#1557607](https://bugzilla.redhat.com/show_bug.cgi?id=1557607) /assign @bparees @deads2k /cc @mfojtik
2 parents 53d3716 + 6feafaf commit 1453679

File tree

4 files changed

+90
-14
lines changed

4 files changed

+90
-14
lines changed

pkg/image/controller/signature/container_image_downloader.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,6 @@ func (s *containerImageSignatureDownloader) DownloadImageSignatures(image *image
6262
// signature.
6363
sig.Name = imageapi.JoinImageStreamImage(image.Name, fmt.Sprintf("%x", sha256.Sum256(blob)))
6464
sig.Content = blob
65-
sig.Annotations = map[string]string{
66-
SignatureManagedAnnotation: "true",
67-
}
6865
sig.CreationTimestamp = metav1.Now()
6966
ret = append(ret, sig)
7067
}

pkg/image/controller/signature/signature_import_controller.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@ import (
1919
imagelister "github.com/openshift/origin/pkg/image/generated/listers/image/internalversion"
2020
)
2121

22-
const (
23-
// SignatureManagedAnnotation marks signatures that were imported by this
24-
// controller.
25-
SignatureManagedAnnotation = "image.openshift.io/managed-signature"
26-
)
27-
2822
type SignatureDownloader interface {
2923
DownloadImageSignatures(*imageapi.Image) ([]imageapi.ImageSignature, error)
3024
}

pkg/image/registry/image/strategy.go

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ import (
1616
"github.com/openshift/origin/pkg/image/util"
1717
)
1818

19+
// managedSignatureAnnotation used to be set by image signature import controller as a signature annotation.
20+
const managedSignatureAnnotation = "image.openshift.io/managed-signature"
21+
1922
// imageStrategy implements behavior for Images.
2023
type imageStrategy struct {
2124
runtime.ObjectTyper
@@ -49,6 +52,8 @@ func (s imageStrategy) PrepareForCreate(ctx apirequest.Context, obj runtime.Obje
4952
newImage.DockerImageManifest = ""
5053
newImage.DockerImageConfig = ""
5154
}
55+
56+
removeManagedSignatureAnnotation(newImage)
5257
}
5358

5459
// Validate validates a new image.
@@ -127,9 +132,20 @@ func (s imageStrategy) PrepareForUpdate(ctx apirequest.Context, obj, old runtime
127132
newImage.DockerImageManifest = ""
128133
newImage.DockerImageConfig = ""
129134
}
135+
136+
removeManagedSignatureAnnotation(newImage)
130137
}
131138

132139
// ValidateUpdate is the default update validation for an end user.
133140
func (imageStrategy) ValidateUpdate(ctx apirequest.Context, obj, old runtime.Object) field.ErrorList {
134-
return validation.ValidateImageUpdate(old.(*imageapi.Image), obj.(*imageapi.Image))
141+
return validation.ValidateImageUpdate(obj.(*imageapi.Image), old.(*imageapi.Image))
142+
}
143+
144+
// removeManagedSignatureAnnotation removes deprecated annotation from image signatures. A bug in image update
145+
// logic allowed to set arbitrary annotations that would otherwise be rejected by validation.
146+
// Resolves rhbz#1557607
147+
func removeManagedSignatureAnnotation(img *imageapi.Image) {
148+
for i := range img.Signatures {
149+
delete(img.Signatures[i].Annotations, managedSignatureAnnotation)
150+
}
135151
}

pkg/image/registry/image/strategy_test.go

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,20 @@ func TestStrategyPrepareForCreate(t *testing.T) {
7676

7777
Strategy.PrepareForCreate(ctx, image)
7878

79-
if len(image.Signatures) != len(fuzzed.Signatures) {
80-
t.Errorf("unexpected number of signatures: %d != %d", len(image.Signatures), len(fuzzed.Signatures))
79+
testVerifySignatures(t, fuzzed, image)
80+
}
81+
82+
func testVerifySignatures(t *testing.T, orig, new *imageapi.Image) {
83+
if len(new.Signatures) != len(orig.Signatures) {
84+
t.Errorf("unexpected number of signatures: %d != %d", len(new.Signatures), len(orig.Signatures))
8185
}
8286

83-
for i, sig := range image.Signatures {
87+
for i, sig := range new.Signatures {
88+
// expect annotations to be cleared
89+
delete(orig.Signatures[i].Annotations, managedSignatureAnnotation)
90+
8491
vi := reflect.ValueOf(&sig).Elem()
85-
vf := reflect.ValueOf(&fuzzed.Signatures[i]).Elem()
92+
vf := reflect.ValueOf(&orig.Signatures[i]).Elem()
8693
typeOfT := vf.Type()
8794

8895
for j := 0; j < vf.NumField(); j++ {
@@ -98,3 +105,65 @@ func TestStrategyPrepareForCreate(t *testing.T) {
98105
}
99106
}
100107
}
108+
109+
func TestStrategyPrepareForCreateSignature(t *testing.T) {
110+
ctx := apirequest.NewDefaultContext()
111+
112+
original := imageapi.Image{
113+
ObjectMeta: metav1.ObjectMeta{
114+
Name: "image",
115+
},
116+
}
117+
118+
seed := int64(2703387474910584091) //rand.Int63()
119+
fuzzed := fuzzImage(t, &original, seed)
120+
121+
if len(fuzzed.Signatures) == 0 {
122+
t.Fatalf("fuzzifier failed to generate signatures")
123+
}
124+
125+
for _, tc := range []struct {
126+
name string
127+
annotations map[string]string
128+
expected map[string]string
129+
}{
130+
{
131+
name: "unset annotations",
132+
annotations: nil,
133+
expected: nil,
134+
},
135+
{
136+
name: "empty annotations",
137+
annotations: map[string]string{},
138+
expected: map[string]string{},
139+
},
140+
{
141+
name: "managed annotation shall be removed",
142+
annotations: map[string]string{managedSignatureAnnotation: "value"},
143+
expected: map[string]string{},
144+
},
145+
{
146+
name: "other annotations shall stay",
147+
annotations: map[string]string{"key": "value"},
148+
expected: map[string]string{"key": "value"},
149+
},
150+
{
151+
name: "remove and keep",
152+
annotations: map[string]string{"key": "value", managedSignatureAnnotation: "true"},
153+
expected: map[string]string{"key": "value"},
154+
},
155+
} {
156+
t.Run(tc.name, func(t *testing.T) {
157+
fuzzed.Signatures[0].Annotations = tc.annotations
158+
image := fuzzed.DeepCopy()
159+
160+
Strategy.PrepareForCreate(ctx, image)
161+
162+
testVerifySignatures(t, fuzzed, image)
163+
164+
if !reflect.DeepEqual(image.Signatures[0].Annotations, tc.expected) {
165+
t.Errorf("unexpected signature annotations: %s", diff.ObjectGoPrintDiff(image.Annotations, tc.expected))
166+
}
167+
})
168+
}
169+
}

0 commit comments

Comments
 (0)