All of lore.kernel.org
 help / color / mirror / Atom feed
From: Bruce Ashfield <bruce.ashfield@gmail.com>
To: asharma@mvista.com
Cc: meta-virtualization@lists.yoctoproject.org
Subject: Re: [meta-virtualization][kirkstone][PATCH] kubernetes: Backport fix for CVE-2024-3177
Date: Mon, 13 May 2024 22:28:11 -0400	[thread overview]
Message-ID: <ZkLMO/fg1d5Skn4B@gmail.com> (raw)
In-Reply-To: <20240503034953.8903-1-asharma@mvista.com>

merged to kirkstone

Bruce

In message: [meta-virtualization][kirkstone][PATCH] kubernetes: Backport fix for CVE-2024-3177
on 03/05/2024 Ashish Sharma via lists.yoctoproject.org wrote:

> Upstream-Status: Backport [https://github.com/kubernetes/kubernetes/pull/124325/commits/3f0922513d235d8bdebe79f0d07da769c04211b8]
> 
> Signed-off-by: Ashish Sharma <asharma@mvista.com>
> ---
>  .../kubernetes/kubernetes/CVE-2024-3177.patch | 237 ++++++++++++++++++
>  .../kubernetes/kubernetes_git.bb              |   1 +
>  2 files changed, 238 insertions(+)
>  create mode 100644 recipes-containers/kubernetes/kubernetes/CVE-2024-3177.patch
> 
> diff --git a/recipes-containers/kubernetes/kubernetes/CVE-2024-3177.patch b/recipes-containers/kubernetes/kubernetes/CVE-2024-3177.patch
> new file mode 100644
> index 00000000..20b2ea8a
> --- /dev/null
> +++ b/recipes-containers/kubernetes/kubernetes/CVE-2024-3177.patch
> @@ -0,0 +1,237 @@
> +From 3f0922513d235d8bdebe79f0d07da769c04211b8 Mon Sep 17 00:00:00 2001
> +From: Rita Zhang <rita.z.zhang@gmail.com>
> +Date: Mon, 25 Mar 2024 10:33:41 -0700
> +Subject: [PATCH] Add envFrom to serviceaccount admission plugin
> +
> +Signed-off-by: Rita Zhang <rita.z.zhang@gmail.com>
> +
> +Upstream-Status: Backport [https://github.com/kubernetes/kubernetes/pull/124325/commits/3f0922513d235d8bdebe79f0d07da769c04211b8]
> +CVE: CVE-2024-3177
> +Signed-off-by: Ashish Sharma <asharma@mvista.com>
> +
> + .../pkg/admission/serviceaccount/admission.go |  21 +++
> + .../serviceaccount/admission_test.go          | 122 ++++++++++++++++--
> + 2 files changed, 132 insertions(+), 11 deletions(-)
> +
> +diff --git a/plugin/pkg/admission/serviceaccount/admission.go b/plugin/pkg/admission/serviceaccount/admission.go
> +index c844a051c24b..3f4338128e53 100644
> +--- a/plugin/pkg/admission/serviceaccount/admission.go
> ++++ b/plugin/pkg/admission/serviceaccount/admission.go
> +@@ -337,6 +337,13 @@ func (s *Plugin) limitSecretReferences(serviceAccount *corev1.ServiceAccount, po
> + 				}
> + 			}
> + 		}
> ++		for _, envFrom := range container.EnvFrom {
> ++			if envFrom.SecretRef != nil {
> ++				if !mountableSecrets.Has(envFrom.SecretRef.Name) {
> ++					return fmt.Errorf("init container %s with envFrom referencing secret.secretName=\"%s\" is not allowed because service account %s does not reference that secret", container.Name, envFrom.SecretRef.Name, serviceAccount.Name)
> ++				}
> ++			}
> ++		}
> + 	}
> + 
> + 	for _, container := range pod.Spec.Containers {
> +@@ -347,6 +354,13 @@ func (s *Plugin) limitSecretReferences(serviceAccount *corev1.ServiceAccount, po
> + 				}
> + 			}
> + 		}
> ++		for _, envFrom := range container.EnvFrom {
> ++			if envFrom.SecretRef != nil {
> ++				if !mountableSecrets.Has(envFrom.SecretRef.Name) {
> ++					return fmt.Errorf("container %s with envFrom referencing secret.secretName=\"%s\" is not allowed because service account %s does not reference that secret", container.Name, envFrom.SecretRef.Name, serviceAccount.Name)
> ++				}
> ++			}
> ++		}
> + 	}
> + 
> + 	// limit pull secret references as well
> +@@ -388,6 +402,13 @@ func (s *Plugin) limitEphemeralContainerSecretReferences(pod *api.Pod, a admissi
> + 				}
> + 			}
> + 		}
> ++		for _, envFrom := range container.EnvFrom {
> ++			if envFrom.SecretRef != nil {
> ++				if !mountableSecrets.Has(envFrom.SecretRef.Name) {
> ++					return fmt.Errorf("ephemeral container %s with envFrom referencing secret.secretName=\"%s\" is not allowed because service account %s does not reference that secret", container.Name, envFrom.SecretRef.Name, serviceAccount.Name)
> ++				}
> ++			}
> ++		}
> + 	}
> + 	return nil
> + }
> +diff --git a/plugin/pkg/admission/serviceaccount/admission_test.go b/plugin/pkg/admission/serviceaccount/admission_test.go
> +index bf15f870d75a..4dba6cd8b13e 100644
> +--- a/plugin/pkg/admission/serviceaccount/admission_test.go
> ++++ b/plugin/pkg/admission/serviceaccount/admission_test.go
> +@@ -521,6 +521,25 @@ func TestAllowsReferencedSecret(t *testing.T) {
> + 		t.Errorf("Unexpected error: %v", err)
> + 	}
> + 
> ++	pod2 = &api.Pod{
> ++		Spec: api.PodSpec{
> ++			Containers: []api.Container{
> ++				{
> ++					Name: "container-1",
> ++					EnvFrom: []api.EnvFromSource{
> ++						{
> ++							SecretRef: &api.SecretEnvSource{
> ++								LocalObjectReference: api.LocalObjectReference{
> ++									Name: "foo"}}}},
> ++				},
> ++			},
> ++		},
> ++	}
> ++	attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
> ++	if err := admissiontesting.WithReinvocationTesting(t, admit).Admit(context.TODO(), attrs, nil); err != nil {
> ++		t.Errorf("Unexpected error: %v", err)
> ++	}
> ++
> + 	pod2 = &api.Pod{
> + 		Spec: api.PodSpec{
> + 			InitContainers: []api.Container{
> +@@ -545,6 +564,25 @@ func TestAllowsReferencedSecret(t *testing.T) {
> + 		t.Errorf("Unexpected error: %v", err)
> + 	}
> + 
> ++	pod2 = &api.Pod{
> ++		Spec: api.PodSpec{
> ++			InitContainers: []api.Container{
> ++				{
> ++					Name: "container-1",
> ++					EnvFrom: []api.EnvFromSource{
> ++						{
> ++							SecretRef: &api.SecretEnvSource{
> ++								LocalObjectReference: api.LocalObjectReference{
> ++									Name: "foo"}}}},
> ++				},
> ++			},
> ++		},
> ++	}
> ++	attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
> ++	if err := admissiontesting.WithReinvocationTesting(t, admit).Admit(context.TODO(), attrs, nil); err != nil {
> ++		t.Errorf("Unexpected error: %v", err)
> ++	}
> ++
> + 	pod2 = &api.Pod{
> + 		Spec: api.PodSpec{
> + 			ServiceAccountName: DefaultServiceAccountName,
> +@@ -572,6 +610,28 @@ func TestAllowsReferencedSecret(t *testing.T) {
> + 	if err := admit.Validate(context.TODO(), attrs, nil); err != nil {
> + 		t.Errorf("Unexpected error: %v", err)
> + 	}
> ++
> ++	pod2 = &api.Pod{
> ++		Spec: api.PodSpec{
> ++			ServiceAccountName: DefaultServiceAccountName,
> ++			EphemeralContainers: []api.EphemeralContainer{
> ++				{
> ++					EphemeralContainerCommon: api.EphemeralContainerCommon{
> ++						Name: "container-2",
> ++						EnvFrom: []api.EnvFromSource{{
> ++							SecretRef: &api.SecretEnvSource{
> ++								LocalObjectReference: api.LocalObjectReference{
> ++									Name: "foo"}}}},
> ++					},
> ++				},
> ++			},
> ++		},
> ++	}
> ++	// validate enforces restrictions on secret mounts when operation==update and subresource==ephemeralcontainers"
> ++	attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "ephemeralcontainers", admission.Update, &metav1.UpdateOptions{}, false, nil)
> ++	if err := admit.Validate(context.TODO(), attrs, nil); err != nil {
> ++		t.Errorf("Unexpected error: %v", err)
> ++	}
> + }
> + 
> + func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
> +@@ -628,25 +688,20 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
> + 
> + 	pod2 = &api.Pod{
> + 		Spec: api.PodSpec{
> +-			InitContainers: []api.Container{
> ++			Containers: []api.Container{
> + 				{
> + 					Name: "container-1",
> +-					Env: []api.EnvVar{
> ++					EnvFrom: []api.EnvFromSource{
> + 						{
> +-							Name: "env-1",
> +-							ValueFrom: &api.EnvVarSource{
> +-								SecretKeyRef: &api.SecretKeySelector{
> +-									LocalObjectReference: api.LocalObjectReference{Name: "foo"},
> +-								},
> +-							},
> +-						},
> +-					},
> ++							SecretRef: &api.SecretEnvSource{
> ++								LocalObjectReference: api.LocalObjectReference{
> ++									Name: "foo"}}}},
> + 				},
> + 			},
> + 		},
> + 	}
> + 	attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
> +-	if err := admissiontesting.WithReinvocationTesting(t, admit).Admit(context.TODO(), attrs, nil); err == nil || !strings.Contains(err.Error(), "with envVar") {
> ++	if err := admissiontesting.WithReinvocationTesting(t, admit).Admit(context.TODO(), attrs, nil); err == nil || !strings.Contains(err.Error(), "with envFrom") {
> + 		t.Errorf("Unexpected error: %v", err)
> + 	}
> + 
> +@@ -679,6 +734,30 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
> + 		t.Errorf("validate only enforces restrictions on secret mounts when operation==create and subresource==''. Unexpected error: %v", err)
> + 	}
> + 
> ++	pod2 = &api.Pod{
> ++		Spec: api.PodSpec{
> ++			ServiceAccountName: DefaultServiceAccountName,
> ++			InitContainers: []api.Container{
> ++				{
> ++					Name: "container-1",
> ++					EnvFrom: []api.EnvFromSource{
> ++						{
> ++							SecretRef: &api.SecretEnvSource{
> ++								LocalObjectReference: api.LocalObjectReference{
> ++									Name: "foo"}}}},
> ++				},
> ++			},
> ++		},
> ++	}
> ++	attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Update, &metav1.UpdateOptions{}, false, nil)
> ++	if err := admissiontesting.WithReinvocationTesting(t, admit).Admit(context.TODO(), attrs, nil); err != nil {
> ++		t.Errorf("admit only enforces restrictions on secret mounts when operation==create. Unexpected error: %v", err)
> ++	}
> ++	attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, nil)
> ++	if err := admit.Validate(context.TODO(), attrs, nil); err == nil || !strings.Contains(err.Error(), "with envFrom") {
> ++		t.Errorf("validate only enforces restrictions on secret mounts when operation==create and subresource==''. Unexpected error: %v", err)
> ++	}
> ++
> + 	pod2 = &api.Pod{
> + 		Spec: api.PodSpec{
> + 			ServiceAccountName: DefaultServiceAccountName,
> +@@ -709,6 +788,27 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
> + 	if err := admit.Validate(context.TODO(), attrs, nil); err == nil || !strings.Contains(err.Error(), "with envVar") {
> + 		t.Errorf("validate enforces restrictions on secret mounts when operation==update and subresource==ephemeralcontainers. Unexpected error: %v", err)
> + 	}
> ++
> ++	pod2 = &api.Pod{
> ++		Spec: api.PodSpec{
> ++			ServiceAccountName: DefaultServiceAccountName,
> ++			EphemeralContainers: []api.EphemeralContainer{
> ++				{
> ++					EphemeralContainerCommon: api.EphemeralContainerCommon{
> ++						Name: "container-2",
> ++						EnvFrom: []api.EnvFromSource{{
> ++							SecretRef: &api.SecretEnvSource{
> ++								LocalObjectReference: api.LocalObjectReference{
> ++									Name: "foo"}}}},
> ++					},
> ++				},
> ++			},
> ++		},
> ++	}
> ++	attrs = admission.NewAttributesRecord(pod2, nil, api.Kind("Pod").WithVersion("version"), ns, "myname", api.Resource("pods").WithVersion("version"), "ephemeralcontainers", admission.Update, &metav1.UpdateOptions{}, false, nil)
> ++	if err := admit.Validate(context.TODO(), attrs, nil); err == nil || !strings.Contains(err.Error(), "with envFrom") {
> ++		t.Errorf("validate enforces restrictions on secret mounts when operation==update and subresource==ephemeralcontainers. Unexpected error: %v", err)
> ++	}
> + }
> + 
> + func TestAllowUnreferencedSecretVolumesForPermissiveSAs(t *testing.T) {
> diff --git a/recipes-containers/kubernetes/kubernetes_git.bb b/recipes-containers/kubernetes/kubernetes_git.bb
> index b0c87c47..78d1cd2a 100644
> --- a/recipes-containers/kubernetes/kubernetes_git.bb
> +++ b/recipes-containers/kubernetes/kubernetes_git.bb
> @@ -35,6 +35,7 @@ SRC_URI:append = " \
>             file://cni-containerd-net.conflist \
>             file://k8s-init \
>             file://99-kubernetes.conf \
> +           file://CVE-2024-3177.patch \
>            "
>  
>  DEPENDS += "rsync-native \
> -- 
> 2.35.7
> 

> 
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#8715): https://lists.yoctoproject.org/g/meta-virtualization/message/8715
> Mute This Topic: https://lists.yoctoproject.org/mt/105882014/1050810
> Group Owner: meta-virtualization+owner@lists.yoctoproject.org
> Unsubscribe: https://lists.yoctoproject.org/g/meta-virtualization/unsub [bruce.ashfield@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
> 



  reply	other threads:[~2024-05-14  2:28 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-05-03  3:49 [meta-virtualization][kirkstone][PATCH] kubernetes: Backport fix for CVE-2024-3177 Ashish Sharma
2024-05-14  2:28 ` Bruce Ashfield [this message]
2024-05-17  6:18   ` Martin Jansa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZkLMO/fg1d5Skn4B@gmail.com \
    --to=bruce.ashfield@gmail.com \
    --cc=asharma@mvista.com \
    --cc=meta-virtualization@lists.yoctoproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.