From 76d31ffbe70ed0cd00f2fb1e892e7d98cf1d9f67 Mon Sep 17 00:00:00 2001 From: zhangxiaoyu Date: Thu, 29 Jun 2023 15:29:20 +0800 Subject: [PATCH] fix CVE-2023-2431 Signed-off-by: zhangxiaoyu (cherry picked from commit 537ffc8a7141b55644407431643d40a186bd1543) --- ...-localhost-seccomp-type-with-no-loca.patch | 516 ++++++++++++++++++ kubernetes.spec | 9 +- 2 files changed, 524 insertions(+), 1 deletion(-) create mode 100644 0012-Return-error-for-localhost-seccomp-type-with-no-loca.patch diff --git a/0012-Return-error-for-localhost-seccomp-type-with-no-loca.patch b/0012-Return-error-for-localhost-seccomp-type-with-no-loca.patch new file mode 100644 index 0000000..6ef4d4d --- /dev/null +++ b/0012-Return-error-for-localhost-seccomp-type-with-no-loca.patch @@ -0,0 +1,516 @@ +From 73174f870735251e7d4240cdc36983d1bef7db5f Mon Sep 17 00:00:00 2001 +From: Craig Ingram +Date: Fri, 24 Feb 2023 15:24:49 -0500 +Subject: [PATCH] Return error for localhost seccomp type with no localhost + profile defined + +--- + pkg/kubelet/kuberuntime/helpers.go | 54 +++--- + pkg/kubelet/kuberuntime/helpers_test.go | 175 ++++-------------- + .../kuberuntime_container_linux.go | 16 +- + .../kuberuntime_container_linux_test.go | 7 +- + pkg/kubelet/kuberuntime/security_context.go | 15 +- + 5 files changed, 98 insertions(+), 169 deletions(-) + +diff --git a/pkg/kubelet/kuberuntime/helpers.go b/pkg/kubelet/kuberuntime/helpers.go +index 6db2698c..99cc6764 100644 +--- a/pkg/kubelet/kuberuntime/helpers.go ++++ b/pkg/kubelet/kuberuntime/helpers.go +@@ -202,21 +202,25 @@ func toKubeRuntimeStatus(status *runtimeapi.RuntimeStatus) *kubecontainer.Runtim + return &kubecontainer.RuntimeStatus{Conditions: conditions} + } + +-func fieldProfile(scmp *v1.SeccompProfile, profileRootPath string) string { ++func fieldProfile(scmp *v1.SeccompProfile, profileRootPath string) (string, error) { + if scmp == nil { +- return "" ++ return "", nil + } + if scmp.Type == v1.SeccompProfileTypeRuntimeDefault { +- return v1.SeccompProfileRuntimeDefault ++ return v1.SeccompProfileRuntimeDefault, nil + } +- if scmp.Type == v1.SeccompProfileTypeLocalhost && scmp.LocalhostProfile != nil && len(*scmp.LocalhostProfile) > 0 { +- fname := filepath.Join(profileRootPath, *scmp.LocalhostProfile) +- return v1.SeccompLocalhostProfileNamePrefix + fname ++ 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 + } +- return "" ++ return "", nil + } + + func annotationProfile(profile, profileRootPath string) string { +@@ -229,7 +233,7 @@ func annotationProfile(profile, profileRootPath string) string { + } + + func (m *kubeGenericRuntimeManager) getSeccompProfilePath(annotations map[string]string, containerName string, +- podSecContext *v1.PodSecurityContext, containerSecContext *v1.SecurityContext) string { ++ podSecContext *v1.PodSecurityContext, containerSecContext *v1.SecurityContext) (string, error) { + // container fields are applied first + if containerSecContext != nil && containerSecContext.SeccompProfile != nil { + return fieldProfile(containerSecContext.SeccompProfile, m.seccompProfileRoot) +@@ -238,7 +242,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 + } + } + +@@ -249,39 +253,43 @@ 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 + } + +- return "" ++ return "", nil + } + +-func fieldSeccompProfile(scmp *v1.SeccompProfile, profileRootPath string) *runtimeapi.SecurityProfile { ++func fieldSeccompProfile(scmp *v1.SeccompProfile, profileRootPath string) (*runtimeapi.SecurityProfile, error) { + // TODO: Move to RuntimeDefault as the default instead of Unconfined after discussion + // with sig-node. + if scmp == 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) *runtimeapi.SecurityProfile { ++ podSecContext *v1.PodSecurityContext, containerSecContext *v1.SecurityContext) (*runtimeapi.SecurityProfile, error) { + // container fields are applied first + if containerSecContext != nil && containerSecContext.SeccompProfile != nil { + return fieldSeccompProfile(containerSecContext.SeccompProfile, m.seccompProfileRoot) +@@ -294,7 +302,7 @@ func (m *kubeGenericRuntimeManager) getSeccompProfile(annotations map[string]str + + 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 1628cb3c..6d5ef720 100644 +--- a/pkg/kubelet/kuberuntime/helpers_test.go ++++ b/pkg/kubelet/kuberuntime/helpers_test.go +@@ -176,17 +176,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", +@@ -213,7 +214,7 @@ func TestFieldProfile(t *testing.T) { + description: "SeccompProfileTypeLocalhost should return unconfined", + scmpProfile: &v1.SeccompProfile{ + Type: v1.SeccompProfileTypeLocalhost, +- LocalhostProfile: utilpointer.StringPtr("profile.json"), ++ LocalhostProfile: utilpointer.String("profile.json"), + }, + rootPath: "/test/", + expectedProfile: "localhost//test/profile.json", +@@ -221,8 +222,13 @@ func TestFieldProfile(t *testing.T) { + } + + for i, test := range tests { +- seccompProfile := fieldProfile(test.scmpProfile, test.rootPath) +- assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description) ++ seccompProfile, err := fieldProfile(test.scmpProfile, test.rootPath) ++ 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) ++ } + } + } + +@@ -237,6 +243,7 @@ func TestGetSeccompProfilePath(t *testing.T) { + containerSc *v1.SecurityContext + containerName string + expectedProfile string ++ expectedError string + }{ + { + description: "no seccomp should return empty", +@@ -247,91 +254,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: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "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: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "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: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "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: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "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}}, +@@ -358,14 +280,14 @@ func TestGetSeccompProfilePath(t *testing.T) { + expectedProfile: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "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", +@@ -378,41 +300,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: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "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: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "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: "localhost/" + filepath.Join(fakeSeccompProfileRoot, "field-pod-profile.json"), +- }, + } + + for i, test := range tests { +- seccompProfile := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc) +- assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description) ++ seccompProfile, err := m.getSeccompProfilePath(test.annotation, test.containerName, test.podSc, test.containerSc) ++ 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) ++ } + } + } + +@@ -435,6 +332,7 @@ func TestGetSeccompProfile(t *testing.T) { + containerSc *v1.SecurityContext + containerName string + expectedProfile *runtimeapi.SecurityProfile ++ expectedError string + }{ + { + description: "no seccomp should return unconfined", +@@ -469,14 +367,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", +@@ -505,8 +403,13 @@ func TestGetSeccompProfile(t *testing.T) { + } + + for i, test := range tests { +- seccompProfile := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc) +- assert.Equal(t, test.expectedProfile, seccompProfile, "TestCase[%d]: %s", i, test.description) ++ seccompProfile, err := m.getSeccompProfile(test.annotation, test.containerName, test.podSc, test.containerSc) ++ 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 0f4fab34..d7c22c86 100644 +--- a/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go ++++ b/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go +@@ -34,15 +34,23 @@ import ( + + // applyPlatformSpecificContainerConfig applies platform specific configurations to runtimeapi.ContainerConfig. + func (m *kubeGenericRuntimeManager) applyPlatformSpecificContainerConfig(config *runtimeapi.ContainerConfig, container *v1.Container, pod *v1.Pod, uid *int64, username string, nsTarget *kubecontainer.ContainerID) error { +- config.Linux = m.generateLinuxContainerConfig(container, pod, uid, username, nsTarget) ++ cl, err := m.generateLinuxContainerConfig(container, pod, uid, username, nsTarget) ++ 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) *runtimeapi.LinuxContainerConfig { ++func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *v1.Container, pod *v1.Pod, uid *int64, username string, nsTarget *kubecontainer.ContainerID) (*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 { +@@ -89,7 +97,7 @@ func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *v1.C + + lc.Resources.HugepageLimits = GetHugepageLimitsFromResources(container.Resources) + +- return lc ++ return lc, nil + } + + // GetHugepageLimitsFromResources returns limits of each hugepages from resources. +diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go b/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go +index 98203fef..3f145938 100644 +--- a/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go ++++ b/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go +@@ -44,6 +44,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) ++ + expectedConfig := &runtimeapi.ContainerConfig{ + Metadata: &runtimeapi.ContainerMetadata{ + Name: container.Name, +@@ -61,7 +63,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), ++ Linux: l, + Envs: envs, + } + return expectedConfig +@@ -360,7 +362,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) ++ got, err := m.generateLinuxContainerConfig(&tc.pod.Spec.Containers[0], tc.pod, nil, "", tc.target) ++ 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) + } +diff --git a/pkg/kubelet/kuberuntime/security_context.go b/pkg/kubelet/kuberuntime/security_context.go +index 45f0d599..aeacbead 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) ++ var err error ++ synthesized.SeccompProfilePath, err = m.getSeccompProfilePath(pod.Annotations, container.Name, pod.Spec.SecurityContext, container.SecurityContext) ++ if err != nil { ++ return nil, err ++ } + +- synthesized.Seccomp = m.getSeccompProfile(pod.Annotations, container.Name, pod.Spec.SecurityContext, container.SecurityContext) ++ synthesized.Seccomp, err = m.getSeccompProfile(pod.Annotations, container.Name, pod.Spec.SecurityContext, container.SecurityContext) ++ 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.25.1 + diff --git a/kubernetes.spec b/kubernetes.spec index 092c8b2..0998f50 100644 --- a/kubernetes.spec +++ b/kubernetes.spec @@ -3,7 +3,7 @@ Name: kubernetes Version: 1.20.2 -Release: 16 +Release: 17 Summary: Container cluster management License: ASL 2.0 URL: https://k8s.io/kubernetes @@ -35,6 +35,7 @@ Patch6007: 0008-kubelet-fix-websocket-reference-nil-pointer.patch Patch6008: 0009-timeout-wait-backend-to-frontend-complete.patch Patch6009: 0010-Escape-terminal-special-characters-in-kubectl-112553.patch Patch6010: 0011-Remove-Endpoints-write-access-from-aggregated-edit-r.patch +Patch6011: 0012-Return-error-for-localhost-seccomp-type-with-no-loca.patch %description Container cluster management. @@ -266,6 +267,12 @@ getent passwd kube >/dev/null || useradd -r -g kube -d / -s /sbin/nologin \ %systemd_postun kubelet kube-proxy %changelog +* Thu Jun 29 2023 zhangxiaoyu - 1.20.2-17 +- Type:bugfix +- CVE:NA +- SUG:NA +- DESC:fix CVE-2023-2431 + * Thu Dec 08 2022 zhangxiaoyu - 1.20.2-16 - Type:bugfix - CVE:NA -- Gitee