summaryrefslogtreecommitdiffstats
path: root/recipes-containers
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-containers')
-rw-r--r--recipes-containers/kubernetes/kubernetes/CVE-2023-2727-CVE-2023-2728.patch559
-rw-r--r--recipes-containers/kubernetes/kubernetes_git.bb1
2 files changed, 560 insertions, 0 deletions
diff --git a/recipes-containers/kubernetes/kubernetes/CVE-2023-2727-CVE-2023-2728.patch b/recipes-containers/kubernetes/kubernetes/CVE-2023-2727-CVE-2023-2728.patch
new file mode 100644
index 00000000..2a9e8489
--- /dev/null
+++ b/recipes-containers/kubernetes/kubernetes/CVE-2023-2727-CVE-2023-2728.patch
@@ -0,0 +1,559 @@
1From f754a4dee31455a0d7fc0f51cb85348af9ea5e1f Mon Sep 17 00:00:00 2001
2From: Rita Zhang <rita.z.zhang@gmail.com>
3Date: Tue, 30 May 2023 20:35:33 +0000
4Subject: [PATCH] Add ephemeralcontainer to imagepolicy securityaccount
5 admission plugin
6
7Signed-off-by: Rita Zhang <rita.z.zhang@gmail.com>
8
9CVE: CVE-2023-2727, CVE-2023-2728
10
11Upstream-Status: Backport [https://github.com/kubernetes/kubernetes/commit/f754a4dee31455a0d7fc0f51cb85348af9ea5e1f]
12
13Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
14---
15 plugin/pkg/admission/imagepolicy/admission.go | 28 ++--
16 .../admission/imagepolicy/admission_test.go | 148 +++++++++++++++++-
17 .../pkg/admission/serviceaccount/admission.go | 57 ++++++-
18 .../serviceaccount/admission_test.go | 88 +++++++++++
19 4 files changed, 297 insertions(+), 24 deletions(-)
20
21diff --git a/plugin/pkg/admission/imagepolicy/admission.go b/plugin/pkg/admission/imagepolicy/admission.go
22index aea4f713eb5..3dfcbf95eef 100644
23--- a/plugin/pkg/admission/imagepolicy/admission.go
24+++ b/plugin/pkg/admission/imagepolicy/admission.go
25@@ -46,6 +46,7 @@ import (
26
27 // PluginName indicates name of admission plugin.
28 const PluginName = "ImagePolicyWebhook"
29+const ephemeralcontainers = "ephemeralcontainers"
30
31 // AuditKeyPrefix is used as the prefix for all audit keys handled by this
32 // pluggin. Some well known suffixes are listed below.
33@@ -132,8 +133,9 @@ func (a *Plugin) webhookError(pod *api.Pod, attributes admission.Attributes, err
34
35 // Validate makes an admission decision based on the request attributes
36 func (a *Plugin) Validate(ctx context.Context, attributes admission.Attributes, o admission.ObjectInterfaces) (err error) {
37- // Ignore all calls to subresources or resources other than pods.
38- if attributes.GetSubresource() != "" || attributes.GetResource().GroupResource() != api.Resource("pods") {
39+ // Ignore all calls to subresources other than ephemeralcontainers or calls to resources other than pods.
40+ subresource := attributes.GetSubresource()
41+ if (subresource != "" && subresource != ephemeralcontainers) || attributes.GetResource().GroupResource() != api.Resource("pods") {
42 return nil
43 }
44
45@@ -144,13 +146,21 @@ func (a *Plugin) Validate(ctx context.Context, attributes admission.Attributes,
46
47 // Build list of ImageReviewContainerSpec
48 var imageReviewContainerSpecs []v1alpha1.ImageReviewContainerSpec
49- containers := make([]api.Container, 0, len(pod.Spec.Containers)+len(pod.Spec.InitContainers))
50- containers = append(containers, pod.Spec.Containers...)
51- containers = append(containers, pod.Spec.InitContainers...)
52- for _, c := range containers {
53- imageReviewContainerSpecs = append(imageReviewContainerSpecs, v1alpha1.ImageReviewContainerSpec{
54- Image: c.Image,
55- })
56+ if subresource == "" {
57+ containers := make([]api.Container, 0, len(pod.Spec.Containers)+len(pod.Spec.InitContainers))
58+ containers = append(containers, pod.Spec.Containers...)
59+ containers = append(containers, pod.Spec.InitContainers...)
60+ for _, c := range containers {
61+ imageReviewContainerSpecs = append(imageReviewContainerSpecs, v1alpha1.ImageReviewContainerSpec{
62+ Image: c.Image,
63+ })
64+ }
65+ } else if subresource == ephemeralcontainers {
66+ for _, c := range pod.Spec.EphemeralContainers {
67+ imageReviewContainerSpecs = append(imageReviewContainerSpecs, v1alpha1.ImageReviewContainerSpec{
68+ Image: c.Image,
69+ })
70+ }
71 }
72 imageReview := v1alpha1.ImageReview{
73 Spec: v1alpha1.ImageReviewSpec{
74diff --git a/plugin/pkg/admission/imagepolicy/admission_test.go b/plugin/pkg/admission/imagepolicy/admission_test.go
75index d1f81d51950..a9188462fb9 100644
76--- a/plugin/pkg/admission/imagepolicy/admission_test.go
77+++ b/plugin/pkg/admission/imagepolicy/admission_test.go
78@@ -37,7 +37,6 @@ import (
79 api "k8s.io/kubernetes/pkg/apis/core"
80
81 "fmt"
82- "io/ioutil"
83 "os"
84 "path/filepath"
85 "text/template"
86@@ -67,7 +66,7 @@ imagePolicy:
87 `
88
89 func TestNewFromConfig(t *testing.T) {
90- dir, err := ioutil.TempDir("", "")
91+ dir, err := os.MkdirTemp("", "")
92 if err != nil {
93 t.Fatal(err)
94 }
95@@ -92,7 +91,7 @@ func TestNewFromConfig(t *testing.T) {
96 {data.Key, clientKey},
97 }
98 for _, file := range files {
99- if err := ioutil.WriteFile(file.name, file.data, 0400); err != nil {
100+ if err := os.WriteFile(file.name, file.data, 0400); err != nil {
101 t.Fatal(err)
102 }
103 }
104@@ -196,7 +195,7 @@ current-context: default
105 // Use a closure so defer statements trigger between loop iterations.
106 t.Run(tt.msg, func(t *testing.T) {
107 err := func() error {
108- tempfile, err := ioutil.TempFile("", "")
109+ tempfile, err := os.CreateTemp("", "")
110 if err != nil {
111 return err
112 }
113@@ -211,7 +210,7 @@ current-context: default
114 return fmt.Errorf("failed to execute test template: %v", err)
115 }
116
117- tempconfigfile, err := ioutil.TempFile("", "")
118+ tempconfigfile, err := os.CreateTemp("", "")
119 if err != nil {
120 return err
121 }
122@@ -359,7 +358,7 @@ func (m *mockService) HTTPStatusCode() int { return m.statusCode }
123 // newImagePolicyWebhook creates a temporary kubeconfig file from the provided arguments and attempts to load
124 // a new newImagePolicyWebhook from it.
125 func newImagePolicyWebhook(callbackURL string, clientCert, clientKey, ca []byte, cacheTime time.Duration, defaultAllow bool) (*Plugin, error) {
126- tempfile, err := ioutil.TempFile("", "")
127+ tempfile, err := os.CreateTemp("", "")
128 if err != nil {
129 return nil, err
130 }
131@@ -381,7 +380,7 @@ func newImagePolicyWebhook(callbackURL string, clientCert, clientKey, ca []byte,
132 return nil, err
133 }
134
135- tempconfigfile, err := ioutil.TempFile("", "")
136+ tempconfigfile, err := os.CreateTemp("", "")
137 if err != nil {
138 return nil, err
139 }
140@@ -595,17 +594,23 @@ func TestContainerCombinations(t *testing.T) {
141 test string
142 pod *api.Pod
143 wantAllowed, wantErr bool
144+ subresource string
145+ operation admission.Operation
146 }{
147 {
148 test: "Single container allowed",
149 pod: goodPod("good"),
150 wantAllowed: true,
151+ subresource: "",
152+ operation: admission.Create,
153 },
154 {
155 test: "Single container denied",
156 pod: goodPod("bad"),
157 wantAllowed: false,
158 wantErr: true,
159+ subresource: "",
160+ operation: admission.Create,
161 },
162 {
163 test: "One good container, one bad",
164@@ -627,6 +632,8 @@ func TestContainerCombinations(t *testing.T) {
165 },
166 wantAllowed: false,
167 wantErr: true,
168+ subresource: "",
169+ operation: admission.Create,
170 },
171 {
172 test: "Multiple good containers",
173@@ -648,6 +655,8 @@ func TestContainerCombinations(t *testing.T) {
174 },
175 wantAllowed: true,
176 wantErr: false,
177+ subresource: "",
178+ operation: admission.Create,
179 },
180 {
181 test: "Multiple bad containers",
182@@ -669,6 +678,8 @@ func TestContainerCombinations(t *testing.T) {
183 },
184 wantAllowed: false,
185 wantErr: true,
186+ subresource: "",
187+ operation: admission.Create,
188 },
189 {
190 test: "Good container, bad init container",
191@@ -692,6 +703,8 @@ func TestContainerCombinations(t *testing.T) {
192 },
193 wantAllowed: false,
194 wantErr: true,
195+ subresource: "",
196+ operation: admission.Create,
197 },
198 {
199 test: "Bad container, good init container",
200@@ -715,6 +728,8 @@ func TestContainerCombinations(t *testing.T) {
201 },
202 wantAllowed: false,
203 wantErr: true,
204+ subresource: "",
205+ operation: admission.Create,
206 },
207 {
208 test: "Good container, good init container",
209@@ -738,6 +753,123 @@ func TestContainerCombinations(t *testing.T) {
210 },
211 wantAllowed: true,
212 wantErr: false,
213+ subresource: "",
214+ operation: admission.Create,
215+ },
216+ {
217+ test: "Good container, good init container, bad ephemeral container when updating ephemeralcontainers subresource",
218+ pod: &api.Pod{
219+ Spec: api.PodSpec{
220+ ServiceAccountName: "default",
221+ SecurityContext: &api.PodSecurityContext{},
222+ Containers: []api.Container{
223+ {
224+ Image: "good",
225+ SecurityContext: &api.SecurityContext{},
226+ },
227+ },
228+ InitContainers: []api.Container{
229+ {
230+ Image: "good",
231+ SecurityContext: &api.SecurityContext{},
232+ },
233+ },
234+ EphemeralContainers: []api.EphemeralContainer{
235+ {
236+ EphemeralContainerCommon: api.EphemeralContainerCommon{
237+ Image: "bad",
238+ SecurityContext: &api.SecurityContext{},
239+ },
240+ },
241+ },
242+ },
243+ },
244+ wantAllowed: false,
245+ wantErr: true,
246+ subresource: "ephemeralcontainers",
247+ operation: admission.Update,
248+ },
249+ {
250+ test: "Good container, good init container, bad ephemeral container when updating subresource=='' which sets initContainer and container only",
251+ pod: &api.Pod{
252+ Spec: api.PodSpec{
253+ ServiceAccountName: "default",
254+ SecurityContext: &api.PodSecurityContext{},
255+ Containers: []api.Container{
256+ {
257+ Image: "good",
258+ SecurityContext: &api.SecurityContext{},
259+ },
260+ },
261+ InitContainers: []api.Container{
262+ {
263+ Image: "good",
264+ SecurityContext: &api.SecurityContext{},
265+ },
266+ },
267+ EphemeralContainers: []api.EphemeralContainer{
268+ {
269+ EphemeralContainerCommon: api.EphemeralContainerCommon{
270+ Image: "bad",
271+ SecurityContext: &api.SecurityContext{},
272+ },
273+ },
274+ },
275+ },
276+ },
277+ wantAllowed: true,
278+ wantErr: false,
279+ subresource: "",
280+ operation: admission.Update,
281+ },
282+
283+ {
284+ test: "Bad container, good ephemeral container when updating subresource=='ephemeralcontainers' which sets ephemeralcontainers only",
285+ pod: &api.Pod{
286+ Spec: api.PodSpec{
287+ ServiceAccountName: "default",
288+ SecurityContext: &api.PodSecurityContext{},
289+ Containers: []api.Container{
290+ {
291+ Image: "bad",
292+ SecurityContext: &api.SecurityContext{},
293+ },
294+ },
295+ EphemeralContainers: []api.EphemeralContainer{
296+ {
297+ EphemeralContainerCommon: api.EphemeralContainerCommon{
298+ Image: "good",
299+ SecurityContext: &api.SecurityContext{},
300+ },
301+ },
302+ },
303+ },
304+ },
305+ wantAllowed: true,
306+ wantErr: false,
307+ subresource: "ephemeralcontainers",
308+ operation: admission.Update,
309+ },
310+ {
311+ test: "Good ephemeral container",
312+ pod: &api.Pod{
313+ Spec: api.PodSpec{
314+ ServiceAccountName: "default",
315+ SecurityContext: &api.PodSecurityContext{},
316+ EphemeralContainers: []api.EphemeralContainer{
317+ {
318+ EphemeralContainerCommon: api.EphemeralContainerCommon{
319+ Image: "good",
320+ SecurityContext: &api.SecurityContext{},
321+ },
322+ },
323+ },
324+ },
325+ },
326+ wantAllowed: true,
327+ wantErr: false,
328+ subresource: "ephemeralcontainers",
329+ operation: admission.Update,
330 },
331 }
332 for _, tt := range tests {
333@@ -759,7 +891,7 @@ func TestContainerCombinations(t *testing.T) {
334 return
335 }
336
337- attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
338+ attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), tt.subresource, tt.operation, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
339
340 err = wh.Validate(context.TODO(), attr, nil)
341 if tt.wantAllowed {
342diff --git a/plugin/pkg/admission/serviceaccount/admission.go b/plugin/pkg/admission/serviceaccount/admission.go
343index 035d54ea8ea..f6e25f3c19d 100644
344--- a/plugin/pkg/admission/serviceaccount/admission.go
345+++ b/plugin/pkg/admission/serviceaccount/admission.go
346@@ -100,7 +100,7 @@ var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&Plugin{})
347 // 5. If MountServiceAccountToken is true, it adds a VolumeMount with the pod's ServiceAccount's api token secret to containers
348 func NewServiceAccount() *Plugin {
349 return &Plugin{
350- Handler: admission.NewHandler(admission.Create),
351+ Handler: admission.NewHandler(admission.Create, admission.Update),
352 // TODO: enable this once we've swept secret usage to account for adding secret references to service accounts
353 LimitSecretReferences: false,
354 // Auto mount service account API token secrets
355@@ -140,7 +140,10 @@ func (s *Plugin) Admit(ctx context.Context, a admission.Attributes, o admission.
356 if shouldIgnore(a) {
357 return nil
358 }
359-
360+ if a.GetOperation() != admission.Create {
361+ // we only mutate pods during create requests
362+ return nil
363+ }
364 pod := a.GetObject().(*api.Pod)
365
366 // Don't modify the spec of mirror pods.
367@@ -157,7 +160,7 @@ func (s *Plugin) Admit(ctx context.Context, a admission.Attributes, o admission.
368
369 serviceAccount, err := s.getServiceAccount(a.GetNamespace(), pod.Spec.ServiceAccountName)
370 if err != nil {
371- return admission.NewForbidden(a, fmt.Errorf("error looking up service account %s/%s: %v", a.GetNamespace(), pod.Spec.ServiceAccountName, err))
372+ return admission.NewForbidden(a, fmt.Errorf("error looking up service account %s/%s: %w", a.GetNamespace(), pod.Spec.ServiceAccountName, err))
373 }
374 if s.MountServiceAccountToken && shouldAutomount(serviceAccount, pod) {
375 s.mountServiceAccountToken(serviceAccount, pod)
376@@ -180,6 +183,15 @@ func (s *Plugin) Validate(ctx context.Context, a admission.Attributes, o admissi
377
378 pod := a.GetObject().(*api.Pod)
379
380+ if a.GetOperation() == admission.Update && a.GetSubresource() == "ephemeralcontainers" {
381+ return s.limitEphemeralContainerSecretReferences(pod, a)
382+ }
383+
384+ if a.GetOperation() != admission.Create {
385+ // we only validate pod specs during create requests
386+ return nil
387+ }
388+
389 // Mirror pods have restrictions on what they can reference
390 if _, isMirrorPod := pod.Annotations[api.MirrorPodAnnotationKey]; isMirrorPod {
391 if len(pod.Spec.ServiceAccountName) != 0 {
392@@ -205,6 +217,10 @@ func (s *Plugin) Validate(ctx context.Context, a admission.Attributes, o admissi
393 return nil
394 }
395
396+ // Require container pods to have service accounts
397+ if len(pod.Spec.ServiceAccountName) == 0 {
398+ return admission.NewForbidden(a, fmt.Errorf("no service account specified for pod %s/%s", a.GetNamespace(), pod.Name))
399+ }
400 // Ensure the referenced service account exists
401 serviceAccount, err := s.getServiceAccount(a.GetNamespace(), pod.Spec.ServiceAccountName)
402 if err != nil {
403@@ -221,10 +237,7 @@ func (s *Plugin) Validate(ctx context.Context, a admission.Attributes, o admissi
404 }
405
406 func shouldIgnore(a admission.Attributes) bool {
407- if a.GetResource().GroupResource() != api.Resource("pods") {
408- return true
409- }
410- if a.GetSubresource() != "" {
411+ if a.GetResource().GroupResource() != api.Resource("pods") || (a.GetSubresource() != "" && a.GetSubresource() != "ephemeralcontainers") {
412 return true
413 }
414 obj := a.GetObject()
415@@ -350,6 +363,36 @@ func (s *Plugin) limitSecretReferences(serviceAccount *corev1.ServiceAccount, po
416 return nil
417 }
418
419+func (s *Plugin) limitEphemeralContainerSecretReferences(pod *api.Pod, a admission.Attributes) error {
420+ // Require ephemeral container pods to have service accounts
421+ if len(pod.Spec.ServiceAccountName) == 0 {
422+ return admission.NewForbidden(a, fmt.Errorf("no service account specified for pod %s/%s", a.GetNamespace(), pod.Name))
423+ }
424+ // Ensure the referenced service account exists
425+ serviceAccount, err := s.getServiceAccount(a.GetNamespace(), pod.Spec.ServiceAccountName)
426+ if err != nil {
427+ return admission.NewForbidden(a, fmt.Errorf("error looking up service account %s/%s: %w", a.GetNamespace(), pod.Spec.ServiceAccountName, err))
428+ }
429+ if !s.enforceMountableSecrets(serviceAccount) {
430+ return nil
431+ }
432+ // Ensure all secrets the ephemeral containers reference are allowed by the service account
433+ mountableSecrets := sets.NewString()
434+ for _, s := range serviceAccount.Secrets {
435+ mountableSecrets.Insert(s.Name)
436+ }
437+ for _, container := range pod.Spec.EphemeralContainers {
438+ for _, env := range container.Env {
439+ if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil {
440+ if !mountableSecrets.Has(env.ValueFrom.SecretKeyRef.Name) {
441+ return fmt.Errorf("ephemeral container %s with envVar %s referencing secret.secretName=\"%s\" is not allowed because service account %s does not reference that secret", container.Name, env.Name, env.ValueFrom.SecretKeyRef.Name, serviceAccount.Name)
442+ }
443+ }
444+ }
445+ }
446+ return nil
447+}
448+
449 func (s *Plugin) mountServiceAccountToken(serviceAccount *corev1.ServiceAccount, pod *api.Pod) {
450 // Find the volume and volume name for the ServiceAccountTokenSecret if it already exists
451 tokenVolumeName := ""
452diff --git a/plugin/pkg/admission/serviceaccount/admission_test.go b/plugin/pkg/admission/serviceaccount/admission_test.go
453index ca43abf9c3f..f5359253985 100644
454--- a/plugin/pkg/admission/serviceaccount/admission_test.go
455+++ b/plugin/pkg/admission/serviceaccount/admission_test.go
456@@ -545,6 +545,34 @@ func TestAllowsReferencedSecret(t *testing.T) {
457 if err := admissiontesting.WithReinvocationTesting(t, admit).Admit(context.TODO(), attrs, nil); err != nil {
458 t.Errorf("Unexpected error: %v", err)
459 }
460+
461+ pod2 = &api.Pod{
462+ Spec: api.PodSpec{
463+ ServiceAccountName: DefaultServiceAccountName,
464+ EphemeralContainers: []api.EphemeralContainer{
465+ {
466+ EphemeralContainerCommon: api.EphemeralContainerCommon{
467+ Name: "container-2",
468+ Env: []api.EnvVar{
469+ {
470+ Name: "env-1",
471+ ValueFrom: &api.EnvVarSource{
472+ SecretKeyRef: &api.SecretKeySelector{
473+ LocalObjectReference: api.LocalObjectReference{Name: "foo"},
474+ },
475+ },
476+ },
477+ },
478+ },
479+ },
480+ },
481+ },
482+ }
483+ // validate enforces restrictions on secret mounts when operation==create and subresource=='' or operation==update and subresource==ephemeralcontainers"
484+ attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "ephemeralcontainers", admission.Update, &metav1.UpdateOptions{}, false, nil)
485+ if err := admit.Validate(context.TODO(), attrs, nil); err != nil {
486+ t.Errorf("Unexpected error: %v", err)
487+ }
488 }
489
490 func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
491@@ -622,6 +650,66 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
492 if err := admissiontesting.WithReinvocationTesting(t, admit).Admit(context.TODO(), attrs, nil); err == nil || !strings.Contains(err.Error(), "with envVar") {
493 t.Errorf("Unexpected error: %v", err)
494 }
495+
496+ pod2 = &api.Pod{
497+ Spec: api.PodSpec{
498+ ServiceAccountName: DefaultServiceAccountName,
499+ InitContainers: []api.Container{
500+ {
501+ Name: "container-1",
502+ Env: []api.EnvVar{
503+ {
504+ Name: "env-1",
505+ ValueFrom: &api.EnvVarSource{
506+ SecretKeyRef: &api.SecretKeySelector{
507+ LocalObjectReference: api.LocalObjectReference{Name: "foo"},
508+ },
509+ },
510+ },
511+ },
512+ },
513+ },
514+ },
515+ }
516+ attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil)
517+ if err := admissiontesting.WithReinvocationTesting(t, admit).Admit(context.TODO(), attrs, nil); err != nil {
518+ t.Errorf("admit only enforces restrictions on secret mounts when operation==create. Unexpected error: %v", err)
519+ }
520+ attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
521+ if err := admit.Validate(context.TODO(), attrs, nil); err == nil || !strings.Contains(err.Error(), "with envVar") {
522+ t.Errorf("validate only enforces restrictions on secret mounts when operation==create and subresource==''. Unexpected error: %v", err)
523+ }
524+
525+ pod2 = &api.Pod{
526+ Spec: api.PodSpec{
527+ ServiceAccountName: DefaultServiceAccountName,
528+ EphemeralContainers: []api.EphemeralContainer{
529+ {
530+ EphemeralContainerCommon: api.EphemeralContainerCommon{
531+ Name: "container-2",
532+ Env: []api.EnvVar{
533+ {
534+ Name: "env-1",
535+ ValueFrom: &api.EnvVarSource{
536+ SecretKeyRef: &api.SecretKeySelector{
537+ LocalObjectReference: api.LocalObjectReference{Name: "foo"},
538+ },
539+ },
540+ },
541+ },
542+ },
543+ },
544+ },
545+ },
546+ }
547+ attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil)
548+ if err := admissiontesting.WithReinvocationTesting(t, admit).Admit(context.TODO(), attrs, nil); err != nil {
549+ t.Errorf("admit only enforces restrictions on secret mounts when operation==create and subresource==''. Unexpected error: %v", err)
550+ }
551+ attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "ephemeralcontainers", admission.Update, &metav1.UpdateOptions{}, false, nil)
552+ if err := admit.Validate(context.TODO(), attrs, nil); err == nil || !strings.Contains(err.Error(), "with envVar") {
553+ t.Errorf("validate enforces restrictions on secret mounts when operation==update and subresource==ephemeralcontainers. Unexpected error: %v", err)
554+ }
555 }
556
557 func TestAllowUnreferencedSecretVolumesForPermissiveSAs(t *testing.T) {
558--
5592.40.0
diff --git a/recipes-containers/kubernetes/kubernetes_git.bb b/recipes-containers/kubernetes/kubernetes_git.bb
index dc741bbf..b0c87c47 100644
--- a/recipes-containers/kubernetes/kubernetes_git.bb
+++ b/recipes-containers/kubernetes/kubernetes_git.bb
@@ -31,6 +31,7 @@ SRC_URI:append = " \
31 file://0001-build-golang.sh-convert-remaining-go-calls-to-use.patch;patchdir=src/import \ 31 file://0001-build-golang.sh-convert-remaining-go-calls-to-use.patch;patchdir=src/import \
32 file://0001-Makefile.generated_files-Fix-race-issue-for-installi.patch;patchdir=src/import \ 32 file://0001-Makefile.generated_files-Fix-race-issue-for-installi.patch;patchdir=src/import \
33 file://CVE-2023-2431.patch;patchdir=src/import \ 33 file://CVE-2023-2431.patch;patchdir=src/import \
34 file://CVE-2023-2727-CVE-2023-2728.patch;patchdir=src/import \
34 file://cni-containerd-net.conflist \ 35 file://cni-containerd-net.conflist \
35 file://k8s-init \ 36 file://k8s-init \
36 file://99-kubernetes.conf \ 37 file://99-kubernetes.conf \