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 1/3] kubernetes: Fix CVE-2023-2431
Date: Tue, 7 Nov 2023 01:56:55 +0000	[thread overview]
Message-ID: <ZUmZZ3fYI7pduRHd@gmail.com> (raw)
In-Reply-To: <20231102130853.1285455-1-soumya.sambu@windriver.com>

I think I've mentioned this before, but these CVE patches should
also confirm that the versions in other supported branches are
not impacted by the CVE.

I'll wait for a v2 before merging.

Bruce

In message: [meta-virtualization][kirkstone][PATCH 1/3] kubernetes: Fix CVE-2023-2431
on 02/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.
> 
> 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 (#8411): https://lists.yoctoproject.org/g/meta-virtualization/message/8411
> Mute This Topic: https://lists.yoctoproject.org/mt/102341409/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-07  1:57 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-02 13:08 [meta-virtualization][kirkstone][PATCH 1/3] kubernetes: Fix CVE-2023-2431 ssambu
2023-11-07  1:56 ` 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=ZUmZZ3fYI7pduRHd@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).