meta-virtualization.lists.yoctoproject.org archive mirror
 help / color / mirror / Atom feed
From: Bruce Ashfield <bruce.ashfield@gmail.com>
To: soumya.sambu@windriver.com
Cc: meta-virtualization@lists.yoctoproject.org
Subject: Re: [meta-virtualization][kirkstone][PATCH v2 2/2] kubernetes: Fix CVE-2023-2727, CVE-2023-2728
Date: Tue, 21 Nov 2023 04:09:03 +0000	[thread overview]
Message-ID: <ZVwtX7t6Vame2/3o@gmail.com> (raw)
In-Reply-To: <20231113035848.1875360-1-soumya.sambu@windriver.com> <20231113041609.1888228-1-soumya.sambu@windriver.com> <20231113041641.1888686-1-soumya.sambu@windriver.com>


All three are now merged.

Thanks for the CVE information in the commit, it makes it
much easier and faster to merge.

Bruce

In message: [meta-virtualization][kirkstone][PATCH v2 2/2] kubernetes: Fix CVE-2023-2727, CVE-2023-2728
on 13/11/2023 Soumya via lists.yoctoproject.org wrote:

> From: Soumya Sambu <soumya.sambu@windriver.com>
> 
> Users may be able to launch containers using images that are restricted by
> ImagePolicyWebhook when using ephemeral containers, Kubernetes clusters are
> only affected if the ImagePolicyWebhook admission plugin is used together
> with ephemeral containers.
> 
> Users may be able to launch containers that bypass the mountable secrets
> policy enforced by the ServiceAccount admission plugin when using ephemeral
> containers. The policy ensures pods running with a service account may only
> reference secrets specified in the service account's secrets field. Kuberenetes
> clusters are only affected if the ServiceAccount admission plugin and the
> `kubernetes.io/enforce-mountab'le-secrets` annotation are used teogether with
> ephemeralcontainers.
> 
> CVE: CVE-2023-2727, CVE-2023-2728
> 
> Affected Versions
> 1.27.0 - v1.27.2
> v1.26.0 - v1.26.5
> v1.25.0 - v1.25.10
> <= v1.24.14
> 
> master branch(kubernetes v1.28.2) is not impacted
> mickledore branch(kubernetes v1.27.5) is not impacted
> 
> References:
> https://nvd.nist.gov/vuln/detail/CVE-2023-2727
> https://nvd.nist.gov/vuln/detail/CVE-2023-2728
> 
> Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
> ---
>  .../CVE-2023-2727-CVE-2023-2728.patch         | 559 ++++++++++++++++++
>  .../kubernetes/kubernetes_git.bb              |   1 +
>  2 files changed, 560 insertions(+)
>  create mode 100644 recipes-containers/kubernetes/kubernetes/CVE-2023-2727-CVE-2023-2728.patch
> 
> 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 @@
> +From f754a4dee31455a0d7fc0f51cb85348af9ea5e1f Mon Sep 17 00:00:00 2001
> +From: Rita Zhang <rita.z.zhang@gmail.com>
> +Date: Tue, 30 May 2023 20:35:33 +0000
> +Subject: [PATCH] Add ephemeralcontainer to imagepolicy securityaccount
> + admission plugin
> +
> +Signed-off-by: Rita Zhang <rita.z.zhang@gmail.com>
> +
> +CVE: CVE-2023-2727, CVE-2023-2728
> +
> +Upstream-Status: Backport [https://github.com/kubernetes/kubernetes/commit/f754a4dee31455a0d7fc0f51cb85348af9ea5e1f]
> +
> +Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
> +---
> + plugin/pkg/admission/imagepolicy/admission.go |  28 ++--
> + .../admission/imagepolicy/admission_test.go   | 148 +++++++++++++++++-
> + .../pkg/admission/serviceaccount/admission.go |  57 ++++++-
> + .../serviceaccount/admission_test.go          |  88 +++++++++++
> + 4 files changed, 297 insertions(+), 24 deletions(-)
> +
> +diff --git a/plugin/pkg/admission/imagepolicy/admission.go b/plugin/pkg/admission/imagepolicy/admission.go
> +index aea4f713eb5..3dfcbf95eef 100644
> +--- a/plugin/pkg/admission/imagepolicy/admission.go
> ++++ b/plugin/pkg/admission/imagepolicy/admission.go
> +@@ -46,6 +46,7 @@ import (
> +
> + // PluginName indicates name of admission plugin.
> + const PluginName = "ImagePolicyWebhook"
> ++const ephemeralcontainers = "ephemeralcontainers"
> +
> + // AuditKeyPrefix is used as the prefix for all audit keys handled by this
> + // pluggin. Some well known suffixes are listed below.
> +@@ -132,8 +133,9 @@ func (a *Plugin) webhookError(pod *api.Pod, attributes admission.Attributes, err
> +
> + // Validate makes an admission decision based on the request attributes
> + func (a *Plugin) Validate(ctx context.Context, attributes admission.Attributes, o admission.ObjectInterfaces) (err error) {
> +-	// Ignore all calls to subresources or resources other than pods.
> +-	if attributes.GetSubresource() != "" || attributes.GetResource().GroupResource() != api.Resource("pods") {
> ++	// Ignore all calls to subresources other than ephemeralcontainers or calls to resources other than pods.
> ++	subresource := attributes.GetSubresource()
> ++	if (subresource != "" && subresource != ephemeralcontainers) || attributes.GetResource().GroupResource() != api.Resource("pods") {
> +		return nil
> +	}
> +
> +@@ -144,13 +146,21 @@ func (a *Plugin) Validate(ctx context.Context, attributes admission.Attributes,
> +
> +	// Build list of ImageReviewContainerSpec
> +	var imageReviewContainerSpecs []v1alpha1.ImageReviewContainerSpec
> +-	containers := make([]api.Container, 0, len(pod.Spec.Containers)+len(pod.Spec.InitContainers))
> +-	containers = append(containers, pod.Spec.Containers...)
> +-	containers = append(containers, pod.Spec.InitContainers...)
> +-	for _, c := range containers {
> +-		imageReviewContainerSpecs = append(imageReviewContainerSpecs, v1alpha1.ImageReviewContainerSpec{
> +-			Image: c.Image,
> +-		})
> ++	if subresource == "" {
> ++		containers := make([]api.Container, 0, len(pod.Spec.Containers)+len(pod.Spec.InitContainers))
> ++		containers = append(containers, pod.Spec.Containers...)
> ++		containers = append(containers, pod.Spec.InitContainers...)
> ++		for _, c := range containers {
> ++			imageReviewContainerSpecs = append(imageReviewContainerSpecs, v1alpha1.ImageReviewContainerSpec{
> ++				Image: c.Image,
> ++			})
> ++		}
> ++	} else if subresource == ephemeralcontainers {
> ++		for _, c := range pod.Spec.EphemeralContainers {
> ++			imageReviewContainerSpecs = append(imageReviewContainerSpecs, v1alpha1.ImageReviewContainerSpec{
> ++				Image: c.Image,
> ++			})
> ++		}
> +	}
> +	imageReview := v1alpha1.ImageReview{
> +		Spec: v1alpha1.ImageReviewSpec{
> +diff --git a/plugin/pkg/admission/imagepolicy/admission_test.go b/plugin/pkg/admission/imagepolicy/admission_test.go
> +index d1f81d51950..a9188462fb9 100644
> +--- a/plugin/pkg/admission/imagepolicy/admission_test.go
> ++++ b/plugin/pkg/admission/imagepolicy/admission_test.go
> +@@ -37,7 +37,6 @@ import (
> +	api "k8s.io/kubernetes/pkg/apis/core"
> +
> +	"fmt"
> +-	"io/ioutil"
> +	"os"
> +	"path/filepath"
> +	"text/template"
> +@@ -67,7 +66,7 @@ imagePolicy:
> + `
> +
> + func TestNewFromConfig(t *testing.T) {
> +-	dir, err := ioutil.TempDir("", "")
> ++	dir, err := os.MkdirTemp("", "")
> +	if err != nil {
> +		t.Fatal(err)
> +	}
> +@@ -92,7 +91,7 @@ func TestNewFromConfig(t *testing.T) {
> +		{data.Key, clientKey},
> +	}
> +	for _, file := range files {
> +-		if err := ioutil.WriteFile(file.name, file.data, 0400); err != nil {
> ++		if err := os.WriteFile(file.name, file.data, 0400); err != nil {
> +			t.Fatal(err)
> +		}
> +	}
> +@@ -196,7 +195,7 @@ current-context: default
> +		// Use a closure so defer statements trigger between loop iterations.
> +		t.Run(tt.msg, func(t *testing.T) {
> +			err := func() error {
> +-				tempfile, err := ioutil.TempFile("", "")
> ++				tempfile, err := os.CreateTemp("", "")
> +				if err != nil {
> +					return err
> +				}
> +@@ -211,7 +210,7 @@ current-context: default
> +					return fmt.Errorf("failed to execute test template: %v", err)
> +				}
> +
> +-				tempconfigfile, err := ioutil.TempFile("", "")
> ++				tempconfigfile, err := os.CreateTemp("", "")
> +				if err != nil {
> +					return err
> +				}
> +@@ -359,7 +358,7 @@ func (m *mockService) HTTPStatusCode() int { return m.statusCode }
> + // newImagePolicyWebhook creates a temporary kubeconfig file from the provided arguments and attempts to load
> + // a new newImagePolicyWebhook from it.
> + func newImagePolicyWebhook(callbackURL string, clientCert, clientKey, ca []byte, cacheTime time.Duration, defaultAllow bool) (*Plugin, error) {
> +-	tempfile, err := ioutil.TempFile("", "")
> ++	tempfile, err := os.CreateTemp("", "")
> +	if err != nil {
> +		return nil, err
> +	}
> +@@ -381,7 +380,7 @@ func newImagePolicyWebhook(callbackURL string, clientCert, clientKey, ca []byte,
> +		return nil, err
> +	}
> +
> +-	tempconfigfile, err := ioutil.TempFile("", "")
> ++	tempconfigfile, err := os.CreateTemp("", "")
> +	if err != nil {
> +		return nil, err
> +	}
> +@@ -595,17 +594,23 @@ func TestContainerCombinations(t *testing.T) {
> +		test                 string
> +		pod                  *api.Pod
> +		wantAllowed, wantErr bool
> ++		subresource          string
> ++		operation            admission.Operation
> +	}{
> +		{
> +			test:        "Single container allowed",
> +			pod:         goodPod("good"),
> +			wantAllowed: true,
> ++			subresource: "",
> ++			operation:   admission.Create,
> +		},
> +		{
> +			test:        "Single container denied",
> +			pod:         goodPod("bad"),
> +			wantAllowed: false,
> +			wantErr:     true,
> ++			subresource: "",
> ++			operation:   admission.Create,
> +		},
> +		{
> +			test: "One good container, one bad",
> +@@ -627,6 +632,8 @@ func TestContainerCombinations(t *testing.T) {
> +			},
> +			wantAllowed: false,
> +			wantErr:     true,
> ++			subresource: "",
> ++			operation:   admission.Create,
> +		},
> +		{
> +			test: "Multiple good containers",
> +@@ -648,6 +655,8 @@ func TestContainerCombinations(t *testing.T) {
> +			},
> +			wantAllowed: true,
> +			wantErr:     false,
> ++			subresource: "",
> ++			operation:   admission.Create,
> +		},
> +		{
> +			test: "Multiple bad containers",
> +@@ -669,6 +678,8 @@ func TestContainerCombinations(t *testing.T) {
> +			},
> +			wantAllowed: false,
> +			wantErr:     true,
> ++			subresource: "",
> ++			operation:   admission.Create,
> +		},
> +		{
> +			test: "Good container, bad init container",
> +@@ -692,6 +703,8 @@ func TestContainerCombinations(t *testing.T) {
> +			},
> +			wantAllowed: false,
> +			wantErr:     true,
> ++			subresource: "",
> ++			operation:   admission.Create,
> +		},
> +		{
> +			test: "Bad container, good init container",
> +@@ -715,6 +728,8 @@ func TestContainerCombinations(t *testing.T) {
> +			},
> +			wantAllowed: false,
> +			wantErr:     true,
> ++			subresource: "",
> ++			operation:   admission.Create,
> +		},
> +		{
> +			test: "Good container, good init container",
> +@@ -738,6 +753,123 @@ func TestContainerCombinations(t *testing.T) {
> +			},
> +			wantAllowed: true,
> +			wantErr:     false,
> ++			subresource: "",
> ++			operation:   admission.Create,
> ++		},
> ++		{
> ++			test: "Good container, good init container, bad ephemeral container when updating ephemeralcontainers subresource",
> ++			pod: &api.Pod{
> ++				Spec: api.PodSpec{
> ++					ServiceAccountName: "default",
> ++					SecurityContext:    &api.PodSecurityContext{},
> ++					Containers: []api.Container{
> ++						{
> ++							Image:           "good",
> ++							SecurityContext: &api.SecurityContext{},
> ++						},
> ++					},
> ++					InitContainers: []api.Container{
> ++						{
> ++							Image:           "good",
> ++							SecurityContext: &api.SecurityContext{},
> ++						},
> ++					},
> ++					EphemeralContainers: []api.EphemeralContainer{
> ++						{
> ++							EphemeralContainerCommon: api.EphemeralContainerCommon{
> ++								Image:           "bad",
> ++								SecurityContext: &api.SecurityContext{},
> ++							},
> ++						},
> ++					},
> ++				},
> ++			},
> ++			wantAllowed: false,
> ++			wantErr:     true,
> ++			subresource: "ephemeralcontainers",
> ++			operation:   admission.Update,
> ++		},
> ++		{
> ++			test: "Good container, good init container, bad ephemeral container when updating subresource=='' which sets initContainer and container only",
> ++			pod: &api.Pod{
> ++				Spec: api.PodSpec{
> ++					ServiceAccountName: "default",
> ++					SecurityContext:    &api.PodSecurityContext{},
> ++					Containers: []api.Container{
> ++						{
> ++							Image:           "good",
> ++							SecurityContext: &api.SecurityContext{},
> ++						},
> ++					},
> ++					InitContainers: []api.Container{
> ++						{
> ++							Image:           "good",
> ++							SecurityContext: &api.SecurityContext{},
> ++						},
> ++					},
> ++					EphemeralContainers: []api.EphemeralContainer{
> ++						{
> ++							EphemeralContainerCommon: api.EphemeralContainerCommon{
> ++								Image:           "bad",
> ++								SecurityContext: &api.SecurityContext{},
> ++							},
> ++						},
> ++					},
> ++				},
> ++			},
> ++			wantAllowed: true,
> ++			wantErr:     false,
> ++			subresource: "",
> ++			operation:   admission.Update,
> ++		},
> ++
> ++		{
> ++			test: "Bad container, good ephemeral container when updating subresource=='ephemeralcontainers' which sets ephemeralcontainers only",
> ++			pod: &api.Pod{
> ++				Spec: api.PodSpec{
> ++					ServiceAccountName: "default",
> ++					SecurityContext:    &api.PodSecurityContext{},
> ++					Containers: []api.Container{
> ++						{
> ++							Image:           "bad",
> ++							SecurityContext: &api.SecurityContext{},
> ++						},
> ++					},
> ++					EphemeralContainers: []api.EphemeralContainer{
> ++						{
> ++							EphemeralContainerCommon: api.EphemeralContainerCommon{
> ++								Image:           "good",
> ++								SecurityContext: &api.SecurityContext{},
> ++							},
> ++						},
> ++					},
> ++				},
> ++			},
> ++			wantAllowed: true,
> ++			wantErr:     false,
> ++			subresource: "ephemeralcontainers",
> ++			operation:   admission.Update,
> ++		},
> ++		{
> ++			test: "Good ephemeral container",
> ++			pod: &api.Pod{
> ++				Spec: api.PodSpec{
> ++					ServiceAccountName: "default",
> ++					SecurityContext:    &api.PodSecurityContext{},
> ++					EphemeralContainers: []api.EphemeralContainer{
> ++						{
> ++							EphemeralContainerCommon: api.EphemeralContainerCommon{
> ++								Image:           "good",
> ++								SecurityContext: &api.SecurityContext{},
> ++							},
> ++						},
> ++					},
> ++				},
> ++			},
> ++			wantAllowed: true,
> ++			wantErr:     false,
> ++			subresource: "ephemeralcontainers",
> ++			operation:   admission.Update,
> +		},
> +	}
> +	for _, tt := range tests {
> +@@ -759,7 +891,7 @@ func TestContainerCombinations(t *testing.T) {
> +				return
> +			}
> +
> +-			attr := admission.NewAttributesRecord(tt.pod, nil, api.Kind("Pod").WithVersion("version"), "namespace", "", api.Resource("pods").WithVersion("version"), "", admission.Create, &metav1.CreateOptions{}, false, &user.DefaultInfo{})
> ++			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{})
> +
> +			err = wh.Validate(context.TODO(), attr, nil)
> +			if tt.wantAllowed {
> +diff --git a/plugin/pkg/admission/serviceaccount/admission.go b/plugin/pkg/admission/serviceaccount/admission.go
> +index 035d54ea8ea..f6e25f3c19d 100644
> +--- a/plugin/pkg/admission/serviceaccount/admission.go
> ++++ b/plugin/pkg/admission/serviceaccount/admission.go
> +@@ -100,7 +100,7 @@ var _ = genericadmissioninitializer.WantsExternalKubeInformerFactory(&Plugin{})
> + // 5. If MountServiceAccountToken is true, it adds a VolumeMount with the pod's ServiceAccount's api token secret to containers
> + func NewServiceAccount() *Plugin {
> +	return &Plugin{
> +-		Handler: admission.NewHandler(admission.Create),
> ++		Handler: admission.NewHandler(admission.Create, admission.Update),
> +		// TODO: enable this once we've swept secret usage to account for adding secret references to service accounts
> +		LimitSecretReferences: false,
> +		// Auto mount service account API token secrets
> +@@ -140,7 +140,10 @@ func (s *Plugin) Admit(ctx context.Context, a admission.Attributes, o admission.
> +	if shouldIgnore(a) {
> +		return nil
> +	}
> +-
> ++	if a.GetOperation() != admission.Create {
> ++		// we only mutate pods during create requests
> ++		return nil
> ++	}
> +	pod := a.GetObject().(*api.Pod)
> +
> +	// Don't modify the spec of mirror pods.
> +@@ -157,7 +160,7 @@ func (s *Plugin) Admit(ctx context.Context, a admission.Attributes, o admission.
> +
> +	serviceAccount, err := s.getServiceAccount(a.GetNamespace(), pod.Spec.ServiceAccountName)
> +	if err != nil {
> +-		return admission.NewForbidden(a, fmt.Errorf("error looking up service account %s/%s: %v", a.GetNamespace(), pod.Spec.ServiceAccountName, err))
> ++		return admission.NewForbidden(a, fmt.Errorf("error looking up service account %s/%s: %w", a.GetNamespace(), pod.Spec.ServiceAccountName, err))
> +	}
> +	if s.MountServiceAccountToken && shouldAutomount(serviceAccount, pod) {
> +		s.mountServiceAccountToken(serviceAccount, pod)
> +@@ -180,6 +183,15 @@ func (s *Plugin) Validate(ctx context.Context, a admission.Attributes, o admissi
> +
> +	pod := a.GetObject().(*api.Pod)
> +
> ++	if a.GetOperation() == admission.Update && a.GetSubresource() == "ephemeralcontainers" {
> ++		return s.limitEphemeralContainerSecretReferences(pod, a)
> ++	}
> ++
> ++	if a.GetOperation() != admission.Create {
> ++		// we only validate pod specs during create requests
> ++		return nil
> ++	}
> ++
> +	// Mirror pods have restrictions on what they can reference
> +	if _, isMirrorPod := pod.Annotations[api.MirrorPodAnnotationKey]; isMirrorPod {
> +		if len(pod.Spec.ServiceAccountName) != 0 {
> +@@ -205,6 +217,10 @@ func (s *Plugin) Validate(ctx context.Context, a admission.Attributes, o admissi
> +		return nil
> +	}
> +
> ++	// Require container pods to have service accounts
> ++	if len(pod.Spec.ServiceAccountName) == 0 {
> ++		return admission.NewForbidden(a, fmt.Errorf("no service account specified for pod %s/%s", a.GetNamespace(), pod.Name))
> ++	}
> +	// Ensure the referenced service account exists
> +	serviceAccount, err := s.getServiceAccount(a.GetNamespace(), pod.Spec.ServiceAccountName)
> +	if err != nil {
> +@@ -221,10 +237,7 @@ func (s *Plugin) Validate(ctx context.Context, a admission.Attributes, o admissi
> + }
> +
> + func shouldIgnore(a admission.Attributes) bool {
> +-	if a.GetResource().GroupResource() != api.Resource("pods") {
> +-		return true
> +-	}
> +-	if a.GetSubresource() != "" {
> ++	if a.GetResource().GroupResource() != api.Resource("pods") || (a.GetSubresource() != "" && a.GetSubresource() != "ephemeralcontainers") {
> +		return true
> +	}
> +	obj := a.GetObject()
> +@@ -350,6 +363,36 @@ func (s *Plugin) limitSecretReferences(serviceAccount *corev1.ServiceAccount, po
> +	return nil
> + }
> +
> ++func (s *Plugin) limitEphemeralContainerSecretReferences(pod *api.Pod, a admission.Attributes) error {
> ++	// Require ephemeral container pods to have service accounts
> ++	if len(pod.Spec.ServiceAccountName) == 0 {
> ++		return admission.NewForbidden(a, fmt.Errorf("no service account specified for pod %s/%s", a.GetNamespace(), pod.Name))
> ++	}
> ++	// Ensure the referenced service account exists
> ++	serviceAccount, err := s.getServiceAccount(a.GetNamespace(), pod.Spec.ServiceAccountName)
> ++	if err != nil {
> ++		return admission.NewForbidden(a, fmt.Errorf("error looking up service account %s/%s: %w", a.GetNamespace(), pod.Spec.ServiceAccountName, err))
> ++	}
> ++	if !s.enforceMountableSecrets(serviceAccount) {
> ++		return nil
> ++	}
> ++	// Ensure all secrets the ephemeral containers reference are allowed by the service account
> ++	mountableSecrets := sets.NewString()
> ++	for _, s := range serviceAccount.Secrets {
> ++		mountableSecrets.Insert(s.Name)
> ++	}
> ++	for _, container := range pod.Spec.EphemeralContainers {
> ++		for _, env := range container.Env {
> ++			if env.ValueFrom != nil && env.ValueFrom.SecretKeyRef != nil {
> ++				if !mountableSecrets.Has(env.ValueFrom.SecretKeyRef.Name) {
> ++					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)
> ++				}
> ++			}
> ++		}
> ++	}
> ++	return nil
> ++}
> ++
> + func (s *Plugin) mountServiceAccountToken(serviceAccount *corev1.ServiceAccount, pod *api.Pod) {
> +	// Find the volume and volume name for the ServiceAccountTokenSecret if it already exists
> +	tokenVolumeName := ""
> +diff --git a/plugin/pkg/admission/serviceaccount/admission_test.go b/plugin/pkg/admission/serviceaccount/admission_test.go
> +index ca43abf9c3f..f5359253985 100644
> +--- a/plugin/pkg/admission/serviceaccount/admission_test.go
> ++++ b/plugin/pkg/admission/serviceaccount/admission_test.go
> +@@ -545,6 +545,34 @@ func TestAllowsReferencedSecret(t *testing.T) {
> +	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,
> ++			EphemeralContainers: []api.EphemeralContainer{
> ++				{
> ++					EphemeralContainerCommon: api.EphemeralContainerCommon{
> ++						Name: "container-2",
> ++						Env: []api.EnvVar{
> ++							{
> ++								Name: "env-1",
> ++								ValueFrom: &api.EnvVarSource{
> ++									SecretKeyRef: &api.SecretKeySelector{
> ++										LocalObjectReference: api.LocalObjectReference{Name: "foo"},
> ++									},
> ++								},
> ++							},
> ++						},
> ++					},
> ++				},
> ++			},
> ++		},
> ++	}
> ++	// validate enforces restrictions on secret mounts when operation==create and subresource=='' or 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) {
> +@@ -622,6 +650,66 @@ func TestRejectsUnreferencedSecretVolumes(t *testing.T) {
> +	if err := admissiontesting.WithReinvocationTesting(t, admit).Admit(context.TODO(), attrs, nil); err == nil || !strings.Contains(err.Error(), "with envVar") {
> +		t.Errorf("Unexpected error: %v", err)
> +	}
> ++
> ++	pod2 = &api.Pod{
> ++		Spec: api.PodSpec{
> ++			ServiceAccountName: DefaultServiceAccountName,
> ++			InitContainers: []api.Container{
> ++				{
> ++					Name: "container-1",
> ++					Env: []api.EnvVar{
> ++						{
> ++							Name: "env-1",
> ++							ValueFrom: &api.EnvVarSource{
> ++								SecretKeyRef: &api.SecretKeySelector{
> ++									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 envVar") {
> ++		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,
> ++			EphemeralContainers: []api.EphemeralContainer{
> ++				{
> ++					EphemeralContainerCommon: api.EphemeralContainerCommon{
> ++						Name: "container-2",
> ++						Env: []api.EnvVar{
> ++							{
> ++								Name: "env-1",
> ++								ValueFrom: &api.EnvVarSource{
> ++									SecretKeyRef: &api.SecretKeySelector{
> ++										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 and subresource==''. Unexpected error: %v", err)
> ++	}
> ++	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 envVar") {
> ++		t.Errorf("validate enforces restrictions on secret mounts when operation==update and subresource==ephemeralcontainers. Unexpected error: %v", err)
> ++	}
> + }
> +
> + func TestAllowUnreferencedSecretVolumesForPermissiveSAs(t *testing.T) {
> +--
> +2.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 = " \
>             file://0001-build-golang.sh-convert-remaining-go-calls-to-use.patch;patchdir=src/import \
>             file://0001-Makefile.generated_files-Fix-race-issue-for-installi.patch;patchdir=src/import \
>             file://CVE-2023-2431.patch;patchdir=src/import \
> +           file://CVE-2023-2727-CVE-2023-2728.patch;patchdir=src/import \
>             file://cni-containerd-net.conflist \
>             file://k8s-init \
>             file://99-kubernetes.conf \
> -- 
> 2.40.0
> 

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


In message: [meta-virtualization][kirkstone][PATCH v2 1/2] kubernetes: Fix CVE-2023-2431
on 13/11/2023 Soumya via lists.yoctoproject.org wrote:

> From: Soumya Sambu <soumya.sambu@windriver.com>
> 
> A security issue was discovered in Kubelet that allows pods to bypass the
> seccomp profile enforcement. Pods that use localhost type for seccomp profile
> but specify an empty profile field, are affected by this issue. In this
> scenario, this vulnerability allows the pod to run in unconfined (seccomp
> disabled) mode. This bug affects Kubelet.
> 
> CVE: CVE-2023-2431
> Affected Versions
> v1.27.0 - v1.27.1
> v1.26.0 - v1.26.4
> v1.25.0 - v1.25.9
> <= v1.24.13
> 
> master branch(kubernetes v1.28.2) is not impacted
> mickledore branch(kubernetes v1.27.5) is not impacted
> 
> References:
> https://nvd.nist.gov/vuln/detail/CVE-2023-2431
> 
> Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
> ---
>  .../kubernetes/kubernetes/CVE-2023-2431.patch | 863 ++++++++++++++++++
>  .../kubernetes/kubernetes_git.bb              |   1 +
>  2 files changed, 864 insertions(+)
>  create mode 100644 recipes-containers/kubernetes/kubernetes/CVE-2023-2431.patch
> 
> diff --git a/recipes-containers/kubernetes/kubernetes/CVE-2023-2431.patch b/recipes-containers/kubernetes/kubernetes/CVE-2023-2431.patch
> new file mode 100644
> index 00000000..56c3a6e1
> --- /dev/null
> +++ b/recipes-containers/kubernetes/kubernetes/CVE-2023-2431.patch
> @@ -0,0 +1,863 @@
> +From 73174f870735251e7d4240cdc36983d1bef7db5f Mon Sep 17 00:00:00 2001
> +From: Craig Ingram <cjingram@google.com>
> +Date: Fri, 24 Feb 2023 15:24:49 -0500
> +Subject: [PATCH] Return error for localhost seccomp type with no localhost
> + profile defined
> +
> +CVE: CVE-2023-2431
> +
> +Upstream-Status: Backport [https://github.com/kubernetes/kubernetes/commit/73174f870735251e7d4240cdc36983d1bef7db5f]
> +
> +Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
> +---
> + pkg/kubelet/kuberuntime/helpers.go            |  66 ++--
> + pkg/kubelet/kuberuntime/helpers_test.go       | 350 ++++--------------
> + .../kuberuntime_container_linux.go            |  16 +-
> + .../kuberuntime_container_linux_test.go       |  22 +-
> + pkg/kubelet/kuberuntime/security_context.go   |  15 +-
> + 5 files changed, 153 insertions(+), 316 deletions(-)
> +
> +diff --git a/pkg/kubelet/kuberuntime/helpers.go b/pkg/kubelet/kuberuntime/helpers.go
> +index fa580335cf8..b36e01166f8 100644
> +--- a/pkg/kubelet/kuberuntime/helpers.go
> ++++ b/pkg/kubelet/kuberuntime/helpers.go
> +@@ -209,28 +209,32 @@ func toKubeRuntimeStatus(status *runtimeapi.RuntimeStatus) *kubecontainer.Runtim
> +	return &kubecontainer.RuntimeStatus{Conditions: conditions}
> + }
> +
> +-func fieldProfile(scmp *v1.SeccompProfile, profileRootPath string, fallbackToRuntimeDefault bool) string {
> ++func fieldProfile(scmp *v1.SeccompProfile, profileRootPath string, fallbackToRuntimeDefault bool) (string, error) {
> +	if scmp == nil {
> +		if fallbackToRuntimeDefault {
> +-			return v1.SeccompProfileRuntimeDefault
> ++			return v1.SeccompProfileRuntimeDefault, nil
> +		}
> +-		return ""
> ++		return "", nil
> +	}
> +	if scmp.Type == v1.SeccompProfileTypeRuntimeDefault {
> +-		return v1.SeccompProfileRuntimeDefault
> +-	}
> +-	if scmp.Type == v1.SeccompProfileTypeLocalhost && scmp.LocalhostProfile != nil && len(*scmp.LocalhostProfile) > 0 {
> +-		fname := filepath.Join(profileRootPath, *scmp.LocalhostProfile)
> +-		return v1.SeccompLocalhostProfileNamePrefix + fname
> ++		return v1.SeccompProfileRuntimeDefault, nil
> ++	}
> ++	if scmp.Type == v1.SeccompProfileTypeLocalhost {
> ++		if scmp.LocalhostProfile != nil && len(*scmp.LocalhostProfile) > 0 {
> ++			fname := filepath.Join(profileRootPath, *scmp.LocalhostProfile)
> ++			return v1.SeccompLocalhostProfileNamePrefix + fname, nil
> ++		} else {
> ++			return "", fmt.Errorf("localhostProfile must be set if seccompProfile type is Localhost.")
> ++		}
> +	}
> +	if scmp.Type == v1.SeccompProfileTypeUnconfined {
> +-		return v1.SeccompProfileNameUnconfined
> ++		return v1.SeccompProfileNameUnconfined, nil
> +	}
> +
> +	if fallbackToRuntimeDefault {
> +-		return v1.SeccompProfileRuntimeDefault
> ++		return v1.SeccompProfileRuntimeDefault, nil
> +	}
> +-	return ""
> ++	return "", nil
> + }
> +
> + func annotationProfile(profile, profileRootPath string) string {
> +@@ -243,7 +247,7 @@ func annotationProfile(profile, profileRootPath string) string {
> + }
> +
> + func (m *kubeGenericRuntimeManager) getSeccompProfilePath(annotations map[string]string, containerName string,
> +-	podSecContext *v1.PodSecurityContext, containerSecContext *v1.SecurityContext, fallbackToRuntimeDefault bool) string {
> ++	podSecContext *v1.PodSecurityContext, containerSecContext *v1.SecurityContext, fallbackToRuntimeDefault bool) (string, error) {
> +	// container fields are applied first
> +	if containerSecContext != nil && containerSecContext.SeccompProfile != nil {
> +		return fieldProfile(containerSecContext.SeccompProfile, m.seccompProfileRoot, fallbackToRuntimeDefault)
> +@@ -252,7 +256,7 @@ func (m *kubeGenericRuntimeManager) getSeccompProfilePath(annotations map[string
> +	// if container field does not exist, try container annotation (deprecated)
> +	if containerName != "" {
> +		if profile, ok := annotations[v1.SeccompContainerAnnotationKeyPrefix+containerName]; ok {
> +-			return annotationProfile(profile, m.seccompProfileRoot)
> ++			return annotationProfile(profile, m.seccompProfileRoot), nil
> +		}
> +	}
> +
> +@@ -263,46 +267,50 @@ func (m *kubeGenericRuntimeManager) getSeccompProfilePath(annotations map[string
> +
> +	// as last resort, try to apply pod annotation (deprecated)
> +	if profile, ok := annotations[v1.SeccompPodAnnotationKey]; ok {
> +-		return annotationProfile(profile, m.seccompProfileRoot)
> ++		return annotationProfile(profile, m.seccompProfileRoot), nil
> +	}
> +
> +	if fallbackToRuntimeDefault {
> +-		return v1.SeccompProfileRuntimeDefault
> ++		return v1.SeccompProfileRuntimeDefault, nil
> +	}
> +
> +-	return ""
> ++	return "", nil
> + }
> +
> +-func fieldSeccompProfile(scmp *v1.SeccompProfile, profileRootPath string, fallbackToRuntimeDefault bool) *runtimeapi.SecurityProfile {
> ++func fieldSeccompProfile(scmp *v1.SeccompProfile, profileRootPath string, fallbackToRuntimeDefault bool) (*runtimeapi.SecurityProfile, error) {
> +	if scmp == nil {
> +		if fallbackToRuntimeDefault {
> +			return &runtimeapi.SecurityProfile{
> +				ProfileType: runtimeapi.SecurityProfile_RuntimeDefault,
> +-			}
> ++			}, nil
> +		}
> +		return &runtimeapi.SecurityProfile{
> +			ProfileType: runtimeapi.SecurityProfile_Unconfined,
> +-		}
> ++		}, nil
> +	}
> +	if scmp.Type == v1.SeccompProfileTypeRuntimeDefault {
> +		return &runtimeapi.SecurityProfile{
> +			ProfileType: runtimeapi.SecurityProfile_RuntimeDefault,
> +-		}
> ++		}, nil
> +	}
> +-	if scmp.Type == v1.SeccompProfileTypeLocalhost && scmp.LocalhostProfile != nil && len(*scmp.LocalhostProfile) > 0 {
> +-		fname := filepath.Join(profileRootPath, *scmp.LocalhostProfile)
> +-		return &runtimeapi.SecurityProfile{
> +-			ProfileType:  runtimeapi.SecurityProfile_Localhost,
> +-			LocalhostRef: fname,
> ++	if scmp.Type == v1.SeccompProfileTypeLocalhost {
> ++		if scmp.LocalhostProfile != nil && len(*scmp.LocalhostProfile) > 0 {
> ++			fname := filepath.Join(profileRootPath, *scmp.LocalhostProfile)
> ++			return &runtimeapi.SecurityProfile{
> ++				ProfileType:  runtimeapi.SecurityProfile_Localhost,
> ++				LocalhostRef: fname,
> ++			}, nil
> ++		} else {
> ++			return nil, fmt.Errorf("localhostProfile must be set if seccompProfile type is Localhost.")
> +		}
> +	}
> +	return &runtimeapi.SecurityProfile{
> +		ProfileType: runtimeapi.SecurityProfile_Unconfined,
> +-	}
> ++	}, nil
> + }
> +
> + func (m *kubeGenericRuntimeManager) getSeccompProfile(annotations map[string]string, containerName string,
> +-	podSecContext *v1.PodSecurityContext, containerSecContext *v1.SecurityContext, fallbackToRuntimeDefault bool) *runtimeapi.SecurityProfile {
> ++	podSecContext *v1.PodSecurityContext, containerSecContext *v1.SecurityContext, fallbackToRuntimeDefault bool) (*runtimeapi.SecurityProfile, error) {
> +	// container fields are applied first
> +	if containerSecContext != nil && containerSecContext.SeccompProfile != nil {
> +		return fieldSeccompProfile(containerSecContext.SeccompProfile, m.seccompProfileRoot, fallbackToRuntimeDefault)
> +@@ -316,12 +324,12 @@ func (m *kubeGenericRuntimeManager) getSeccompProfile(annotations map[string]str
> +	if fallbackToRuntimeDefault {
> +		return &runtimeapi.SecurityProfile{
> +			ProfileType: runtimeapi.SecurityProfile_RuntimeDefault,
> +-		}
> ++		}, nil
> +	}
> +
> +	return &runtimeapi.SecurityProfile{
> +		ProfileType: runtimeapi.SecurityProfile_Unconfined,
> +-	}
> ++	}, nil
> + }
> +
> + func ipcNamespaceForPod(pod *v1.Pod) runtimeapi.NamespaceMode {
> +diff --git a/pkg/kubelet/kuberuntime/helpers_test.go b/pkg/kubelet/kuberuntime/helpers_test.go
> +index 25065f30411..70ad7250ce2 100644
> +--- a/pkg/kubelet/kuberuntime/helpers_test.go
> ++++ b/pkg/kubelet/kuberuntime/helpers_test.go
> +@@ -242,17 +242,18 @@ func TestFieldProfile(t *testing.T) {
> +		scmpProfile     *v1.SeccompProfile
> +		rootPath        string
> +		expectedProfile string
> ++		expectedError   string
> +	}{
> +		{
> +			description:     "no seccompProfile should return empty",
> +			expectedProfile: "",
> +		},
> +		{
> +-			description: "type localhost without profile should return empty",
> ++			description: "type localhost without profile should return error",
> +			scmpProfile: &v1.SeccompProfile{
> +				Type: v1.SeccompProfileTypeLocalhost,
> +			},
> +-			expectedProfile: "",
> ++			expectedError: "localhostProfile must be set if seccompProfile type is Localhost.",
> +		},
> +		{
> +			description: "unknown type should return empty",
> +@@ -279,7 +280,7 @@ func TestFieldProfile(t *testing.T) {
> +			description: "SeccompProfileTypeLocalhost should return localhost",
> +			scmpProfile: &v1.SeccompProfile{
> +				Type:             v1.SeccompProfileTypeLocalhost,
> +-				LocalhostProfile: utilpointer.StringPtr("profile.json"),
> ++				LocalhostProfile: utilpointer.String("profile.json"),
> +			},
> +			rootPath:        "/test/",
> +			expectedProfile: "localhost//test/profile.json",
> +@@ -287,8 +288,13 @@ func TestFieldProfile(t *testing.T) {
> +	}
> +
> +	for i, test := range tests {
> +-		seccompProfile := fieldProfile(test.scmpProfile, test.rootPath, false)
> +-		assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
> ++		seccompProfile, err := fieldProfile(test.scmpProfile, test.rootPath, false)
> ++		if test.expectedError != "" {
> ++			assert.EqualError(t, err, test.expectedError, "TestCase[%d]: %s", i, test.description)
> ++		} else {
> ++			assert.NoError(t, err, "TestCase[%d]: %s", i, test.description)
> ++			assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
> ++		}
> +	}
> + }
> +
> +@@ -298,17 +304,18 @@ func TestFieldProfileDefaultSeccomp(t *testing.T) {
> +		scmpProfile     *v1.SeccompProfile
> +		rootPath        string
> +		expectedProfile string
> ++		expectedError   string
> +	}{
> +		{
> +			description:     "no seccompProfile should return runtime/default",
> +			expectedProfile: v1.SeccompProfileRuntimeDefault,
> +		},
> +		{
> +-			description: "type localhost without profile should return runtime/default",
> ++			description: "type localhost without profile should return error",
> +			scmpProfile: &v1.SeccompProfile{
> +				Type: v1.SeccompProfileTypeLocalhost,
> +			},
> +-			expectedProfile: v1.SeccompProfileRuntimeDefault,
> ++			expectedError: "localhostProfile must be set if seccompProfile type is Localhost.",
> +		},
> +		{
> +			description: "unknown type should return runtime/default",
> +@@ -335,7 +342,7 @@ func TestFieldProfileDefaultSeccomp(t *testing.T) {
> +			description: "SeccompProfileTypeLocalhost should return localhost",
> +			scmpProfile: &v1.SeccompProfile{
> +				Type:             v1.SeccompProfileTypeLocalhost,
> +-				LocalhostProfile: utilpointer.StringPtr("profile.json"),
> ++				LocalhostProfile: utilpointer.String("profile.json"),
> +			},
> +			rootPath:        "/test/",
> +			expectedProfile: "localhost//test/profile.json",
> +@@ -343,8 +350,13 @@ func TestFieldProfileDefaultSeccomp(t *testing.T) {
> +	}
> +
> +	for i, test := range tests {
> +-		seccompProfile := fieldProfile(test.scmpProfile, test.rootPath, true)
> +-		assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
> ++		seccompProfile, err := fieldProfile(test.scmpProfile, test.rootPath, true)
> ++		if test.expectedError != "" {
> ++			assert.EqualError(t, err, test.expectedError, "TestCase[%d]: %s", i, test.description)
> ++		} else {
> ++			assert.NoError(t, err, "TestCase[%d]: %s", i, test.description)
> ++			assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
> ++		}
> +	}
> + }
> +
> +@@ -359,6 +371,7 @@ func TestGetSeccompProfilePath(t *testing.T) {
> +		containerSc     *v1.SecurityContext
> +		containerName   string
> +		expectedProfile string
> ++		expectedError   string
> +	}{
> +		{
> +			description:     "no seccomp should return empty",
> +@@ -369,91 +382,6 @@ func TestGetSeccompProfilePath(t *testing.T) {
> +			containerName:   "container1",
> +			expectedProfile: "",
> +		},
> +-		{
> +-			description: "annotations: pod runtime/default seccomp profile should return runtime/default",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault,
> +-			},
> +-			expectedProfile: "runtime/default",
> +-		},
> +-		{
> +-			description: "annotations: pod docker/default seccomp profile should return docker/default",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: v1.DeprecatedSeccompProfileDockerDefault,
> +-			},
> +-			expectedProfile: "docker/default",
> +-		},
> +-		{
> +-			description: "annotations: pod runtime/default seccomp profile with containerName should return runtime/default",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault,
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: "runtime/default",
> +-		},
> +-		{
> +-			description: "annotations: pod docker/default seccomp profile with containerName should return docker/default",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: v1.DeprecatedSeccompProfileDockerDefault,
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: "docker/default",
> +-		},
> +-		{
> +-			description: "annotations: pod unconfined seccomp profile should return unconfined",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined,
> +-			},
> +-			expectedProfile: "unconfined",
> +-		},
> +-		{
> +-			description: "annotations: pod unconfined seccomp profile with containerName should return unconfined",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined,
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: "unconfined",
> +-		},
> +-		{
> +-			description: "annotations: pod localhost seccomp profile should return local profile path",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: "localhost/chmod.json",
> +-			},
> +-			expectedProfile: seccompLocalhostPath("chmod.json"),
> +-		},
> +-		{
> +-			description: "annotations: pod localhost seccomp profile with containerName should return local profile path",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: "localhost/chmod.json",
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: seccompLocalhostPath("chmod.json"),
> +-		},
> +-		{
> +-			description: "annotations: container localhost seccomp profile with containerName should return local profile path",
> +-			annotation: map[string]string{
> +-				v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json",
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: seccompLocalhostPath("chmod.json"),
> +-		},
> +-		{
> +-			description: "annotations: container localhost seccomp profile should override pod profile",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey:                            v1.SeccompProfileNameUnconfined,
> +-				v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json",
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: seccompLocalhostPath("chmod.json"),
> +-		},
> +-		{
> +-			description: "annotations: container localhost seccomp profile with unmatched containerName should return empty",
> +-			annotation: map[string]string{
> +-				v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json",
> +-			},
> +-			containerName:   "container2",
> +-			expectedProfile: "",
> +-		},
> +		{
> +			description:     "pod seccomp profile set to unconfined returns unconfined",
> +			podSc:           &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
> +@@ -480,14 +408,14 @@ func TestGetSeccompProfilePath(t *testing.T) {
> +			expectedProfile: seccompLocalhostPath("filename"),
> +		},
> +		{
> +-			description:     "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns empty",
> +-			podSc:           &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> +-			expectedProfile: "",
> ++			description:   "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns error",
> ++			podSc:         &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> ++			expectedError: "localhostProfile must be set if seccompProfile type is Localhost.",
> +		},
> +		{
> +-			description:     "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns empty",
> +-			containerSc:     &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> +-			expectedProfile: "",
> ++			description:   "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns error",
> ++			containerSc:   &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> ++			expectedError: "localhostProfile must be set if seccompProfile type is Localhost.",
> +		},
> +		{
> +			description:     "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
> +@@ -500,41 +428,16 @@ func TestGetSeccompProfilePath(t *testing.T) {
> +			containerSc:     &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
> +			expectedProfile: "runtime/default",
> +		},
> +-		{
> +-			description: "prioritise container field over container annotation, pod field and pod annotation",
> +-			podSc:       &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
> +-			containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-cont-profile.json")}},
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey:                            "localhost/annota-pod-profile.json",
> +-				v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/annota-cont-profile.json",
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: seccompLocalhostPath("field-cont-profile.json"),
> +-		},
> +-		{
> +-			description: "prioritise container annotation over pod field",
> +-			podSc:       &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey:                            "localhost/annota-pod-profile.json",
> +-				v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/annota-cont-profile.json",
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: seccompLocalhostPath("annota-cont-profile.json"),
> +-		},
> +-		{
> +-			description: "prioritise pod field over pod annotation",
> +-			podSc:       &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: "localhost/annota-pod-profile.json",
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: seccompLocalhostPath("field-pod-profile.json"),
> +-		},
> +	}
> +
> +	for i, test := range tests {
> +-		seccompProfile := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc, false)
> +-		assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
> ++		seccompProfile, err := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc, false)
> ++		if test.expectedError != "" {
> ++			assert.EqualError(t, err, test.expectedError, "TestCase[%d]: %s", i, test.description)
> ++		} else {
> ++			assert.NoError(t, err, "TestCase[%d]: %s", i, test.description)
> ++			assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
> ++		}
> +	}
> + }
> +
> +@@ -549,6 +452,7 @@ func TestGetSeccompProfilePathDefaultSeccomp(t *testing.T) {
> +		containerSc     *v1.SecurityContext
> +		containerName   string
> +		expectedProfile string
> ++		expectedError   string
> +	}{
> +		{
> +			description:     "no seccomp should return runtime/default",
> +@@ -559,91 +463,6 @@ func TestGetSeccompProfilePathDefaultSeccomp(t *testing.T) {
> +			containerName:   "container1",
> +			expectedProfile: v1.SeccompProfileRuntimeDefault,
> +		},
> +-		{
> +-			description: "annotations: pod runtime/default seccomp profile should return runtime/default",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault,
> +-			},
> +-			expectedProfile: v1.SeccompProfileRuntimeDefault,
> +-		},
> +-		{
> +-			description: "annotations: pod docker/default seccomp profile should return docker/default",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: v1.DeprecatedSeccompProfileDockerDefault,
> +-			},
> +-			expectedProfile: "docker/default",
> +-		},
> +-		{
> +-			description: "annotations: pod runtime/default seccomp profile with containerName should return runtime/default",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault,
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: v1.SeccompProfileRuntimeDefault,
> +-		},
> +-		{
> +-			description: "annotations: pod docker/default seccomp profile with containerName should return docker/default",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: v1.DeprecatedSeccompProfileDockerDefault,
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: "docker/default",
> +-		},
> +-		{
> +-			description: "annotations: pod unconfined seccomp profile should return unconfined",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined,
> +-			},
> +-			expectedProfile: "unconfined",
> +-		},
> +-		{
> +-			description: "annotations: pod unconfined seccomp profile with containerName should return unconfined",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined,
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: "unconfined",
> +-		},
> +-		{
> +-			description: "annotations: pod localhost seccomp profile should return local profile path",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: "localhost/chmod.json",
> +-			},
> +-			expectedProfile: seccompLocalhostPath("chmod.json"),
> +-		},
> +-		{
> +-			description: "annotations: pod localhost seccomp profile with containerName should return local profile path",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: "localhost/chmod.json",
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: seccompLocalhostPath("chmod.json"),
> +-		},
> +-		{
> +-			description: "annotations: container localhost seccomp profile with containerName should return local profile path",
> +-			annotation: map[string]string{
> +-				v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json",
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: seccompLocalhostPath("chmod.json"),
> +-		},
> +-		{
> +-			description: "annotations: container localhost seccomp profile should override pod profile",
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey:                            v1.SeccompProfileNameUnconfined,
> +-				v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json",
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: seccompLocalhostPath("chmod.json"),
> +-		},
> +-		{
> +-			description: "annotations: container localhost seccomp profile with unmatched containerName should return runtime/default",
> +-			annotation: map[string]string{
> +-				v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json",
> +-			},
> +-			containerName:   "container2",
> +-			expectedProfile: v1.SeccompProfileRuntimeDefault,
> +-		},
> +		{
> +			description:     "pod seccomp profile set to unconfined returns unconfined",
> +			podSc:           &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}},
> +@@ -670,14 +489,14 @@ func TestGetSeccompProfilePathDefaultSeccomp(t *testing.T) {
> +			expectedProfile: seccompLocalhostPath("filename"),
> +		},
> +		{
> +-			description:     "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns runtime/default",
> +-			podSc:           &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> +-			expectedProfile: v1.SeccompProfileRuntimeDefault,
> ++			description:   "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns error",
> ++			podSc:         &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> ++			expectedError: "localhostProfile must be set if seccompProfile type is Localhost.",
> +		},
> +		{
> +-			description:     "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns runtime/default",
> +-			containerSc:     &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> +-			expectedProfile: v1.SeccompProfileRuntimeDefault,
> ++			description:   "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns error",
> ++			containerSc:   &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> ++			expectedError: "localhostProfile must be set if seccompProfile type is Localhost.",
> +		},
> +		{
> +			description:     "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
> +@@ -690,41 +509,16 @@ func TestGetSeccompProfilePathDefaultSeccomp(t *testing.T) {
> +			containerSc:     &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}},
> +			expectedProfile: "runtime/default",
> +		},
> +-		{
> +-			description: "prioritise container field over container annotation, pod field and pod annotation",
> +-			podSc:       &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
> +-			containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-cont-profile.json")}},
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey:                            "localhost/annota-pod-profile.json",
> +-				v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/annota-cont-profile.json",
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: seccompLocalhostPath("field-cont-profile.json"),
> +-		},
> +-		{
> +-			description: "prioritise container annotation over pod field",
> +-			podSc:       &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey:                            "localhost/annota-pod-profile.json",
> +-				v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/annota-cont-profile.json",
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: seccompLocalhostPath("annota-cont-profile.json"),
> +-		},
> +-		{
> +-			description: "prioritise pod field over pod annotation",
> +-			podSc:       &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}},
> +-			annotation: map[string]string{
> +-				v1.SeccompPodAnnotationKey: "localhost/annota-pod-profile.json",
> +-			},
> +-			containerName:   "container1",
> +-			expectedProfile: seccompLocalhostPath("field-pod-profile.json"),
> +-		},
> +	}
> +
> +	for i, test := range tests {
> +-		seccompProfile := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc, true)
> +-		assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
> ++		seccompProfile, err := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc, true)
> ++		if test.expectedError != "" {
> ++			assert.EqualError(t, err, test.expectedError, "TestCase[%d]: %s", i, test.description)
> ++		} else {
> ++			assert.NoError(t, err, "TestCase[%d]: %s", i, test.description)
> ++			assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
> ++		}
> +	}
> + }
> +
> +@@ -747,6 +541,7 @@ func TestGetSeccompProfile(t *testing.T) {
> +		containerSc     *v1.SecurityContext
> +		containerName   string
> +		expectedProfile *runtimeapi.SecurityProfile
> ++		expectedError   string
> +	}{
> +		{
> +			description:     "no seccomp should return unconfined",
> +@@ -781,14 +576,14 @@ func TestGetSeccompProfile(t *testing.T) {
> +			},
> +		},
> +		{
> +-			description:     "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
> +-			podSc:           &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> +-			expectedProfile: unconfinedProfile,
> ++			description:   "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns error",
> ++			podSc:         &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> ++			expectedError: "localhostProfile must be set if seccompProfile type is Localhost.",
> +		},
> +		{
> +-			description:     "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
> +-			containerSc:     &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> +-			expectedProfile: unconfinedProfile,
> ++			description:   "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns error",
> ++			containerSc:   &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> ++			expectedError: "localhostProfile must be set if seccompProfile type is Localhost.",
> +		},
> +		{
> +			description: "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
> +@@ -817,8 +612,13 @@ func TestGetSeccompProfile(t *testing.T) {
> +	}
> +
> +	for i, test := range tests {
> +-		seccompProfile := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc, false)
> +-		assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
> ++		seccompProfile, err := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc, false)
> ++		if test.expectedError != "" {
> ++			assert.EqualError(t, err, test.expectedError, "TestCase[%d]: %s", i, test.description)
> ++		} else {
> ++			assert.NoError(t, err, "TestCase[%d]: %s", i, test.description)
> ++			assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
> ++		}
> +	}
> + }
> +
> +@@ -841,6 +641,7 @@ func TestGetSeccompProfileDefaultSeccomp(t *testing.T) {
> +		containerSc     *v1.SecurityContext
> +		containerName   string
> +		expectedProfile *runtimeapi.SecurityProfile
> ++		expectedError   string
> +	}{
> +		{
> +			description:     "no seccomp should return RuntimeDefault",
> +@@ -875,14 +676,14 @@ func TestGetSeccompProfileDefaultSeccomp(t *testing.T) {
> +			},
> +		},
> +		{
> +-			description:     "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
> +-			podSc:           &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> +-			expectedProfile: unconfinedProfile,
> ++			description:   "pod seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns error",
> ++			podSc:         &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> ++			expectedError: "localhostProfile must be set if seccompProfile type is Localhost.",
> +		},
> +		{
> +-			description:     "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns unconfined",
> +-			containerSc:     &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> +-			expectedProfile: unconfinedProfile,
> ++			description:   "container seccomp profile set to SeccompProfileTypeLocalhost with empty LocalhostProfile returns error",
> ++			containerSc:   &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost}},
> ++			expectedError: "localhostProfile must be set if seccompProfile type is Localhost.",
> +		},
> +		{
> +			description: "container seccomp profile set to SeccompProfileTypeLocalhost returns 'localhost/' + LocalhostProfile",
> +@@ -911,8 +712,13 @@ func TestGetSeccompProfileDefaultSeccomp(t *testing.T) {
> +	}
> +
> +	for i, test := range tests {
> +-		seccompProfile := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc, true)
> +-		assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
> ++		seccompProfile, err := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc, true)
> ++		if test.expectedError != "" {
> ++			assert.EqualError(t, err, test.expectedError, "TestCase[%d]: %s", i, test.description)
> ++		} else {
> ++			assert.NoError(t, err, "TestCase[%d]: %s", i, test.description)
> ++			assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description)
> ++		}
> +	}
> + }
> +
> +diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go b/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go
> +index 6cb9e54729e..54670673bcd 100644
> +--- a/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go
> ++++ b/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go
> +@@ -46,15 +46,23 @@ func (m *kubeGenericRuntimeManager) applyPlatformSpecificContainerConfig(config
> +		libcontainercgroups.IsCgroup2UnifiedMode() {
> +		enforceMemoryQoS = true
> +	}
> +-	config.Linux = m.generateLinuxContainerConfig(container, pod, uid, username, nsTarget, enforceMemoryQoS)
> ++	cl, err := m.generateLinuxContainerConfig(container, pod, uid, username, nsTarget, enforceMemoryQoS)
> ++	if err != nil {
> ++		return err
> ++	}
> ++	config.Linux = cl
> +	return nil
> + }
> +
> + // generateLinuxContainerConfig generates linux container config for kubelet runtime v1.
> +-func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *v1.Container, pod *v1.Pod, uid *int64, username string, nsTarget *kubecontainer.ContainerID, enforceMemoryQoS bool) *runtimeapi.LinuxContainerConfig {
> ++func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *v1.Container, pod *v1.Pod, uid *int64, username string, nsTarget *kubecontainer.ContainerID, enforceMemoryQoS bool) (*runtimeapi.LinuxContainerConfig, error) {
> ++	sc, err := m.determineEffectiveSecurityContext(pod, container, uid, username)
> ++	if err != nil {
> ++		return nil, err
> ++	}
> +	lc := &runtimeapi.LinuxContainerConfig{
> +		Resources:       &runtimeapi.LinuxContainerResources{},
> +-		SecurityContext: m.determineEffectiveSecurityContext(pod, container, uid, username),
> ++		SecurityContext: sc,
> +	}
> +
> +	if nsTarget != nil && lc.SecurityContext.NamespaceOptions.Pid == runtimeapi.NamespaceMode_CONTAINER {
> +@@ -125,7 +133,7 @@ func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *v1.C
> +		}
> +	}
> +
> +-	return lc
> ++	return lc, nil
> + }
> +
> + // calculateLinuxResources will create the linuxContainerResources type based on the provided CPU and memory resource requests, limits
> +diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go b/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go
> +index 46817e00fb0..98f635cc932 100644
> +--- a/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go
> ++++ b/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go
> +@@ -47,6 +47,8 @@ func makeExpectedConfig(m *kubeGenericRuntimeManager, pod *v1.Pod, containerInde
> +	restartCountUint32 := uint32(restartCount)
> +	envs := make([]*runtimeapi.KeyValue, len(opts.Envs))
> +
> ++	l, _ := m.generateLinuxContainerConfig(container, pod, new(int64), "", nil, enforceMemoryQoS)
> ++
> +	expectedConfig := &runtimeapi.ContainerConfig{
> +		Metadata: &runtimeapi.ContainerMetadata{
> +			Name:    container.Name,
> +@@ -64,7 +66,7 @@ func makeExpectedConfig(m *kubeGenericRuntimeManager, pod *v1.Pod, containerInde
> +		Stdin:       container.Stdin,
> +		StdinOnce:   container.StdinOnce,
> +		Tty:         container.TTY,
> +-		Linux:       m.generateLinuxContainerConfig(container, pod, new(int64), "", nil, enforceMemoryQoS),
> ++		Linux:       l,
> +		Envs:        envs,
> +	}
> +	return expectedConfig
> +@@ -215,7 +217,8 @@ func TestGenerateLinuxContainerConfigResources(t *testing.T) {
> +			},
> +		}
> +
> +-		linuxConfig := m.generateLinuxContainerConfig(&pod.Spec.Containers[0], pod, new(int64), "", nil, false)
> ++		linuxConfig, err := m.generateLinuxContainerConfig(&pod.Spec.Containers[0], pod, new(int64), "", nil, false)
> ++		assert.NoError(t, err)
> +		assert.Equal(t, test.expected.CpuPeriod, linuxConfig.GetResources().CpuPeriod, test.name)
> +		assert.Equal(t, test.expected.CpuQuota, linuxConfig.GetResources().CpuQuota, test.name)
> +		assert.Equal(t, test.expected.CpuShares, linuxConfig.GetResources().CpuShares, test.name)
> +@@ -329,6 +332,8 @@ func TestGenerateContainerConfigWithMemoryQoSEnforced(t *testing.T) {
> +		memoryLow       int64
> +		memoryHigh      int64
> +	}
> ++	l1, _ := m.generateLinuxContainerConfig(&pod1.Spec.Containers[0], pod1, new(int64), "", nil, true)
> ++	l2, _ := m.generateLinuxContainerConfig(&pod2.Spec.Containers[0], pod2, new(int64), "", nil, true)
> +	tests := []struct {
> +		name     string
> +		pod      *v1.Pod
> +@@ -338,7 +343,7 @@ func TestGenerateContainerConfigWithMemoryQoSEnforced(t *testing.T) {
> +			name: "Request128MBLimit256MB",
> +			pod:  pod1,
> +			expected: &expectedResult{
> +-				m.generateLinuxContainerConfig(&pod1.Spec.Containers[0], pod1, new(int64), "", nil, true),
> ++				l1,
> +				128 * 1024 * 1024,
> +				int64(float64(256*1024*1024) * m.memoryThrottlingFactor),
> +			},
> +@@ -347,7 +352,7 @@ func TestGenerateContainerConfigWithMemoryQoSEnforced(t *testing.T) {
> +			name: "Request128MBWithoutLimit",
> +			pod:  pod2,
> +			expected: &expectedResult{
> +-				m.generateLinuxContainerConfig(&pod2.Spec.Containers[0], pod2, new(int64), "", nil, true),
> ++				l2,
> +				128 * 1024 * 1024,
> +				int64(pod2MemoryHigh),
> +			},
> +@@ -355,7 +360,8 @@ func TestGenerateContainerConfigWithMemoryQoSEnforced(t *testing.T) {
> +	}
> +
> +	for _, test := range tests {
> +-		linuxConfig := m.generateLinuxContainerConfig(&test.pod.Spec.Containers[0], test.pod, new(int64), "", nil, true)
> ++		linuxConfig, err := m.generateLinuxContainerConfig(&test.pod.Spec.Containers[0], test.pod, new(int64), "", nil, true)
> ++		assert.NoError(t, err)
> +		assert.Equal(t, test.expected.containerConfig, linuxConfig, test.name)
> +		assert.Equal(t, linuxConfig.GetResources().GetUnified()["memory.min"], strconv.FormatInt(test.expected.memoryLow, 10), test.name)
> +		assert.Equal(t, linuxConfig.GetResources().GetUnified()["memory.high"], strconv.FormatInt(test.expected.memoryHigh, 10), test.name)
> +@@ -578,7 +584,8 @@ func TestGenerateLinuxContainerConfigNamespaces(t *testing.T) {
> +		},
> +	} {
> +		t.Run(tc.name, func(t *testing.T) {
> +-			got := m.generateLinuxContainerConfig(&tc.pod.Spec.Containers[0], tc.pod, nil, "", tc.target, false)
> ++			got, err := m.generateLinuxContainerConfig(&tc.pod.Spec.Containers[0], tc.pod, nil, "", tc.target, false)
> ++			assert.NoError(t, err)
> +			if diff := cmp.Diff(tc.want, got.SecurityContext.NamespaceOptions); diff != "" {
> +				t.Errorf("%v: diff (-want +got):\n%v", t.Name(), diff)
> +			}
> +@@ -669,7 +676,8 @@ func TestGenerateLinuxContainerConfigSwap(t *testing.T) {
> +	} {
> +		t.Run(tc.name, func(t *testing.T) {
> +			m.memorySwapBehavior = tc.swapSetting
> +-			actual := m.generateLinuxContainerConfig(&tc.pod.Spec.Containers[0], tc.pod, nil, "", nil, false)
> ++			actual, err := m.generateLinuxContainerConfig(&tc.pod.Spec.Containers[0], tc.pod, nil, "", nil, false)
> ++			assert.NoError(t, err)
> +			assert.Equal(t, tc.expected, actual.Resources.MemorySwapLimitInBytes, "memory swap config for %s", tc.name)
> +		})
> +	}
> +diff --git a/pkg/kubelet/kuberuntime/security_context.go b/pkg/kubelet/kuberuntime/security_context.go
> +index c9d33e44305..3b575c8e974 100644
> +--- a/pkg/kubelet/kuberuntime/security_context.go
> ++++ b/pkg/kubelet/kuberuntime/security_context.go
> +@@ -24,7 +24,7 @@ import (
> + )
> +
> + // determineEffectiveSecurityContext gets container's security context from v1.Pod and v1.Container.
> +-func (m *kubeGenericRuntimeManager) determineEffectiveSecurityContext(pod *v1.Pod, container *v1.Container, uid *int64, username string) *runtimeapi.LinuxContainerSecurityContext {
> ++func (m *kubeGenericRuntimeManager) determineEffectiveSecurityContext(pod *v1.Pod, container *v1.Container, uid *int64, username string) (*runtimeapi.LinuxContainerSecurityContext, error) {
> +	effectiveSc := securitycontext.DetermineEffectiveSecurityContext(pod, container)
> +	synthesized := convertToRuntimeSecurityContext(effectiveSc)
> +	if synthesized == nil {
> +@@ -36,9 +36,16 @@ func (m *kubeGenericRuntimeManager) determineEffectiveSecurityContext(pod *v1.Po
> +
> +	// TODO: Deprecated, remove after we switch to Seccomp field
> +	// set SeccompProfilePath.
> +-	synthesized.SeccompProfilePath = m.getSeccompProfilePath(pod.Annotations, container.Name, pod.Spec.SecurityContext, container.SecurityContext, m.seccompDefault)
> ++	var err error
> ++	synthesized.SeccompProfilePath, err = m.getSeccompProfilePath(pod.Annotations, container.Name, pod.Spec.SecurityContext, container.SecurityContext, m.seccompDefault)
> ++	if err != nil {
> ++		return nil, err
> ++	}
> +
> +-	synthesized.Seccomp = m.getSeccompProfile(pod.Annotations, container.Name, pod.Spec.SecurityContext, container.SecurityContext, m.seccompDefault)
> ++	synthesized.Seccomp, err = m.getSeccompProfile(pod.Annotations, container.Name, pod.Spec.SecurityContext, container.SecurityContext, m.seccompDefault)
> ++	if err != nil {
> ++		return nil, err
> ++	}
> +
> +	// set ApparmorProfile.
> +	synthesized.ApparmorProfile = apparmor.GetProfileNameFromPodAnnotations(pod.Annotations, container.Name)
> +@@ -74,7 +81,7 @@ func (m *kubeGenericRuntimeManager) determineEffectiveSecurityContext(pod *v1.Po
> +	synthesized.MaskedPaths = securitycontext.ConvertToRuntimeMaskedPaths(effectiveSc.ProcMount)
> +	synthesized.ReadonlyPaths = securitycontext.ConvertToRuntimeReadonlyPaths(effectiveSc.ProcMount)
> +
> +-	return synthesized
> ++	return synthesized, nil
> + }
> +
> + // convertToRuntimeSecurityContext converts v1.SecurityContext to runtimeapi.SecurityContext.
> +--
> +2.40.0
> diff --git a/recipes-containers/kubernetes/kubernetes_git.bb b/recipes-containers/kubernetes/kubernetes_git.bb
> index 59892c92..dc741bbf 100644
> --- a/recipes-containers/kubernetes/kubernetes_git.bb
> +++ b/recipes-containers/kubernetes/kubernetes_git.bb
> @@ -30,6 +30,7 @@ SRC_URI:append = " \
>             file://0001-cross-don-t-build-tests-by-default.patch;patchdir=src/import \
>             file://0001-build-golang.sh-convert-remaining-go-calls-to-use.patch;patchdir=src/import \
>             file://0001-Makefile.generated_files-Fix-race-issue-for-installi.patch;patchdir=src/import \
> +           file://CVE-2023-2431.patch;patchdir=src/import \
>             file://cni-containerd-net.conflist \
>             file://k8s-init \
>             file://99-kubernetes.conf \
> -- 
> 2.40.0
> 

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


In message: [meta-virtualization][kirkstone][PATCH v2 1/1] kubernetes: Adjust patches to resolve error that occur with devtool
on 13/11/2023 Soumya via lists.yoctoproject.org wrote:

> From: Soumya Sambu <soumya.sambu@windriver.com>
> 
> Adjust patches and .bb to fix  below error which occurs with devtool modify command -
> 
> ERROR: Applying patch '0001-hack-lib-golang.sh-use-CC-from-environment.patch' on
> target directory
> CmdError('sh -c \'PATCHFILE="0001-hack-lib-golang.sh-use-CC-from-environment.patch"
> git -c user.name="OpenEmbedded" -c user.email="oe.patch@oe" commit -F /tmp/tmp_ptvioq3
> --author="Koen Kooi <koen.kooi@linaro.org>"
> --date="Mon, 23 Jul 2018 15:28:02 +0200"\'', 0, 'stdout: On branch devtool
> Changes not staged for commit:
>   (use "git add <file>..." to update what will be committed)
>   (use "git restore <file>..." to discard changes in working directory)
>   (commit or discard the untracked or modified content in submodules)
> \tmodified:   src/import (modified content)
> 
> no changes added to commit (use "git add" and/or "git commit -a")
> 
> stderr: ')
> 
> This error is not seen on master branch, fixed with below commit -
> [https://git.yoctoproject.org/meta-virtualization/commit/?id=d9af46db9aa9060c1ec10118b2cccabfc8264904]
> 
> Signed-off-by: Soumya Sambu <soumya.sambu@windriver.com>
> ---
>  ...rated_files-Fix-race-issue-for-installi.patch | 16 +++++++++-------
>  ...ng.sh-convert-remaining-go-calls-to-use.patch | 16 ++++++++--------
>  ...0001-cross-don-t-build-tests-by-default.patch | 10 +++++-----
>  ...k-lib-golang.sh-use-CC-from-environment.patch | 12 +++++++-----
>  recipes-containers/kubernetes/kubernetes_git.bb  |  8 ++++----
>  5 files changed, 33 insertions(+), 29 deletions(-)
> 
> diff --git a/recipes-containers/kubernetes/kubernetes/0001-Makefile.generated_files-Fix-race-issue-for-installi.patch b/recipes-containers/kubernetes/kubernetes/0001-Makefile.generated_files-Fix-race-issue-for-installi.patch
> index 02bb5e91..1b08b8c3 100644
> --- a/recipes-containers/kubernetes/kubernetes/0001-Makefile.generated_files-Fix-race-issue-for-installi.patch
> +++ b/recipes-containers/kubernetes/kubernetes/0001-Makefile.generated_files-Fix-race-issue-for-installi.patch
> @@ -1,7 +1,7 @@
>  From 441df8a24a2c80e320f140b5d9bc352c7ce8a64a Mon Sep 17 00:00:00 2001
>  From: Robert Yang <liezhi.yang@windriver.com>
>  Date: Thu, 15 Oct 2020 07:27:35 +0000
> -Subject: [PATCH] src/import/build/root/Makefile.generated_files: Fix race issue for installing
> +Subject: [PATCH] src/import/build/root/Makefile.generated_files: Fix race issue for installing 
>   go2make
>  
>  The src/import/build/root/Makefile.generated_files are called several times during the build, so the
> @@ -25,14 +25,14 @@ Upstream-Status: Pending
>  
>  Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
>  ---
> - src/import/build/root/Makefile.generated_files | 4 +++-
> + build/root/Makefile.generated_files | 4 +++-
>   1 file changed, 3 insertions(+), 1 deletion(-)
>  
> -Index: kubernetes-v1.21.1+git45da3fc33872083fb225c1a8c4d03e530d6f7630/src/import/build/root/Makefile.generated_files
> -===================================================================
> ---- kubernetes-v1.21.1+git45da3fc33872083fb225c1a8c4d03e530d6f7630.orig/src/import/build/root/Makefile.generated_files
> -+++ kubernetes-v1.21.1+git45da3fc33872083fb225c1a8c4d03e530d6f7630/src/import/build/root/Makefile.generated_files
> -@@ -67,7 +67,9 @@
> +diff --git a/build/root/Makefile.generated_files b/build/root/Makefile.generated_files
> +index d86a90cbb39..19a3d332476 100644
> +--- a/build/root/Makefile.generated_files
> ++++ b/build/root/Makefile.generated_files
> +@@ -67,7 +67,9 @@ $(META_DIR)/$(GO_PKGDEPS_FILE): FORCE
>   	if [[ "$(DBG_CODEGEN)" == 1 ]]; then          \
>   	    echo "DBG: calculating Go dependencies";  \
>   	fi
> @@ -43,3 +43,5 @@ Index: kubernetes-v1.21.1+git45da3fc33872083fb225c1a8c4d03e530d6f7630/src/import
>   	hack/run-in-gopath.sh go2make                       \
>   	    k8s.io/kubernetes/...                           \
>   	    --prune  k8s.io/kubernetes/staging              \
> +--
> +2.40.0
> diff --git a/recipes-containers/kubernetes/kubernetes/0001-build-golang.sh-convert-remaining-go-calls-to-use.patch b/recipes-containers/kubernetes/kubernetes/0001-build-golang.sh-convert-remaining-go-calls-to-use.patch
> index 8adbafb3..00425c7d 100644
> --- a/recipes-containers/kubernetes/kubernetes/0001-build-golang.sh-convert-remaining-go-calls-to-use.patch
> +++ b/recipes-containers/kubernetes/kubernetes/0001-build-golang.sh-convert-remaining-go-calls-to-use.patch
> @@ -8,11 +8,11 @@ Signed-off-by: Bruce Ashfield <bruce.ashfield@gmail.com>
>   hack/lib/golang.sh | 8 ++++----
>   1 file changed, 4 insertions(+), 4 deletions(-)
>  
> -diff --git a/src/import/hack/lib/golang.sh b/src/import/hack/lib/golang.sh
> -index e9148ec08fa..71d3c987563 100755
> ---- a/src/import/hack/lib/golang.sh
> -+++ b/src/import/hack/lib/golang.sh
> -@@ -651,7 +651,7 @@ kube::golang::build_some_binaries() {
> +diff --git a/hack/lib/golang.sh b/hack/lib/golang.sh
> +index d0f4b00dadf..cef0c2075a3 100755
> +--- a/hack/lib/golang.sh
> ++++ b/hack/lib/golang.sh
> +@@ -654,7 +654,7 @@ kube::golang::build_some_binaries() {
>           kube::golang::create_coverage_dummy_test "${package}"
>           kube::util::trap_add "kube::golang::delete_coverage_dummy_test \"${package}\"" EXIT
>   
> @@ -21,7 +21,7 @@ index e9148ec08fa..71d3c987563 100755
>             -covermode count \
>             -coverpkg k8s.io/...,k8s.io/kubernetes/vendor/k8s.io/... \
>             "${build_args[@]}" \
> -@@ -663,13 +663,13 @@ kube::golang::build_some_binaries() {
> +@@ -666,13 +666,13 @@ kube::golang::build_some_binaries() {
>       done
>       if [[ "${#uncovered[@]}" != 0 ]]; then
>         V=2 kube::log::info "Building ${uncovered[*]} without coverage..."
> @@ -37,7 +37,7 @@ index e9148ec08fa..71d3c987563 100755
>      fi
>   }
>   
> -@@ -725,7 +725,7 @@ kube::golang::build_binaries_for_platform() {
> +@@ -730,7 +730,7 @@ kube::golang::build_binaries_for_platform() {
>       testpkg=$(dirname "${test}")
>   
>       mkdir -p "$(dirname "${outfile}")"
> @@ -47,5 +47,5 @@ index e9148ec08fa..71d3c987563 100755
>         -gcflags "${gogcflags:-}" \
>         -asmflags "${goasmflags:-}" \
>  -- 
> -2.19.1
> +2.40.0
>  
> diff --git a/recipes-containers/kubernetes/kubernetes/0001-cross-don-t-build-tests-by-default.patch b/recipes-containers/kubernetes/kubernetes/0001-cross-don-t-build-tests-by-default.patch
> index 659e3013..cd5e46f1 100644
> --- a/recipes-containers/kubernetes/kubernetes/0001-cross-don-t-build-tests-by-default.patch
> +++ b/recipes-containers/kubernetes/kubernetes/0001-cross-don-t-build-tests-by-default.patch
> @@ -15,10 +15,10 @@ Signed-off-by: Bruce Ashfield <bruce.ashfield@windriver.com>
>   hack/make-rules/cross.sh | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
>  
> -diff --git a/src/import/hack/make-rules/cross.sh b/hack/make-rules/cross.sh
> -index 8e1e938..0898c5c 100755
> ---- a/src/import/hack/make-rules/cross.sh
> -+++ b/src/import/hack/make-rules/cross.sh
> +diff --git a/hack/make-rules/cross.sh b/hack/make-rules/cross.sh
> +index f8a6d0dbf5e..d22bf52b1cc 100755
> +--- a/hack/make-rules/cross.sh
> ++++ b/hack/make-rules/cross.sh
>  @@ -33,6 +33,6 @@ make all WHAT="${KUBE_NODE_TARGETS[*]}" KUBE_BUILD_PLATFORMS="${KUBE_NODE_PLATFO
>   
>   make all WHAT="${KUBE_CLIENT_TARGETS[*]}" KUBE_BUILD_PLATFORMS="${KUBE_CLIENT_PLATFORMS[*]}"
> @@ -29,5 +29,5 @@ index 8e1e938..0898c5c 100755
>  -make all WHAT="${KUBE_TEST_SERVER_TARGETS[*]}" KUBE_BUILD_PLATFORMS="${KUBE_TEST_SERVER_PLATFORMS[*]}"
>  +#make all WHAT="${KUBE_TEST_SERVER_TARGETS[*]}" KUBE_BUILD_PLATFORMS="${KUBE_TEST_SERVER_PLATFORMS[*]}"
>  -- 
> -2.7.4
> +2.40.0
>  
> diff --git a/recipes-containers/kubernetes/kubernetes/0001-hack-lib-golang.sh-use-CC-from-environment.patch b/recipes-containers/kubernetes/kubernetes/0001-hack-lib-golang.sh-use-CC-from-environment.patch
> index 3a22a2ef..8684a94a 100644
> --- a/recipes-containers/kubernetes/kubernetes/0001-hack-lib-golang.sh-use-CC-from-environment.patch
> +++ b/recipes-containers/kubernetes/kubernetes/0001-hack-lib-golang.sh-use-CC-from-environment.patch
> @@ -11,11 +11,11 @@ Signed-off-by: Koen Kooi <koen.kooi@linaro.org>
>   hack/lib/golang.sh | 4 ----
>   1 file changed, 4 deletions(-)
>  
> -Index: kubernetes-v1.21.1+git45da3fc33872083fb225c1a8c4d03e530d6f7630/src/import/hack/lib/golang.sh
> -===================================================================
> ---- kubernetes-v1.21.1+git45da3fc33872083fb225c1a8c4d03e530d6f7630.orig/src/import/hack/lib/golang.sh
> -+++ kubernetes-v1.21.1+git45da3fc33872083fb225c1a8c4d03e530d6f7630/src/import/hack/lib/golang.sh
> -@@ -414,19 +414,15 @@
> +diff --git a/hack/lib/golang.sh b/hack/lib/golang.sh
> +index e16a60d1867..d0f4b00dadf 100755
> +--- a/hack/lib/golang.sh
> ++++ b/hack/lib/golang.sh
> +@@ -420,19 +420,15 @@ kube::golang::set_platform_envs() {
>           ;;
>         "linux/arm")
>           export CGO_ENABLED=1
> @@ -35,3 +35,5 @@ Index: kubernetes-v1.21.1+git45da3fc33872083fb225c1a8c4d03e530d6f7630/src/import
>           ;;
>       esac
>     fi
> +--
> +2.40.0
> diff --git a/recipes-containers/kubernetes/kubernetes_git.bb b/recipes-containers/kubernetes/kubernetes_git.bb
> index f475bd73..59892c92 100644
> --- a/recipes-containers/kubernetes/kubernetes_git.bb
> +++ b/recipes-containers/kubernetes/kubernetes_git.bb
> @@ -26,10 +26,10 @@ SRC_URI = "git://github.com/kubernetes/kubernetes.git;branch=release-1.23;name=k
>             git://github.com/kubernetes/release;branch=master;name=kubernetes-release;destsuffix=git/release;protocol=https"
>  
>  SRC_URI:append = " \
> -           file://0001-hack-lib-golang.sh-use-CC-from-environment.patch \
> -           file://0001-cross-don-t-build-tests-by-default.patch \
> -           file://0001-build-golang.sh-convert-remaining-go-calls-to-use.patch \
> -           file://0001-Makefile.generated_files-Fix-race-issue-for-installi.patch \
> +           file://0001-hack-lib-golang.sh-use-CC-from-environment.patch;patchdir=src/import \
> +           file://0001-cross-don-t-build-tests-by-default.patch;patchdir=src/import \
> +           file://0001-build-golang.sh-convert-remaining-go-calls-to-use.patch;patchdir=src/import \
> +           file://0001-Makefile.generated_files-Fix-race-issue-for-installi.patch;patchdir=src/import \
>             file://cni-containerd-net.conflist \
>             file://k8s-init \
>             file://99-kubernetes.conf \
> -- 
> 2.40.0
> 

> 
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#8456): https://lists.yoctoproject.org/g/meta-virtualization/message/8456
> Mute This Topic: https://lists.yoctoproject.org/mt/102555494/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:[~2023-11-21  4:09 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-13  3:58 [meta-virtualization][kirkstone][PATCH v2 1/1] kubernetes: Adjust patches to resolve error that occur with devtool ssambu
2023-11-13  4:16 ` [meta-virtualization][kirkstone][PATCH v2 1/2] kubernetes: Fix CVE-2023-2431 ssambu
2023-11-13  4:16   ` [meta-virtualization][kirkstone][PATCH v2 2/2] kubernetes: Fix CVE-2023-2727, CVE-2023-2728 ssambu
2023-11-21  4:09     ` Bruce Ashfield [this message]

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=ZVwtX7t6Vame2/3o@gmail.com \
    --to=bruce.ashfield@gmail.com \
    --cc=meta-virtualization@lists.yoctoproject.org \
    --cc=soumya.sambu@windriver.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).