Skip to content

Commit 8efb1a3

Browse files
[Low] Patch kubernetes for CVE-2025-4563 (#14147)
1 parent 101be89 commit 8efb1a3

File tree

2 files changed

+204
-1
lines changed

2 files changed

+204
-1
lines changed

SPECS/kubernetes/CVE-2025-4563.patch

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
From 3f3e38728b8cff51c68fcae662488edb59184a9e Mon Sep 17 00:00:00 2001
2+
From: dj_palli <[email protected]>
3+
Date: Mon, 30 Jun 2025 11:15:01 +0000
4+
Subject: [PATCH] Address CVE-2025-4563
5+
6+
Upstream patch reference: https://github.com/kubernetes/kubernetes/pull/131876/commits/1fde2b884c7110c5e253db7143b24bfd91202c4d
7+
8+
---
9+
pkg/apis/core/validation/validation.go | 7 +++
10+
pkg/apis/core/validation/validation_test.go | 11 +++-
11+
pkg/kubelet/config/common.go | 6 ++
12+
pkg/kubelet/config/common_test.go | 56 +++++++++++++++++++
13+
.../admission/noderestriction/admission.go | 4 ++
14+
.../noderestriction/admission_test.go | 9 +++
15+
6 files changed, 92 insertions(+), 1 deletion(-)
16+
17+
diff --git a/pkg/apis/core/validation/validation.go b/pkg/apis/core/validation/validation.go
18+
index ecccf969..98da9166 100644
19+
--- a/pkg/apis/core/validation/validation.go
20+
+++ b/pkg/apis/core/validation/validation.go
21+
@@ -3011,6 +3011,13 @@ func gatherPodResourceClaimNames(claims []core.PodResourceClaim) sets.Set[string
22+
}
23+
24+
func validatePodResourceClaim(podMeta *metav1.ObjectMeta, claim core.PodResourceClaim, podClaimNames *sets.Set[string], fldPath *field.Path) field.ErrorList {
25+
+ // static pods don't support resource claims
26+
+ if podMeta != nil {
27+
+ if _, ok := podMeta.Annotations[core.MirrorPodAnnotationKey]; ok {
28+
+ return field.ErrorList{field.Forbidden(field.NewPath(""), "static pods do not support resource claims")}
29+
+ }
30+
+ }
31+
+
32+
var allErrs field.ErrorList
33+
if claim.Name == "" {
34+
allErrs = append(allErrs, field.Required(fldPath.Child("name"), ""))
35+
diff --git a/pkg/apis/core/validation/validation_test.go b/pkg/apis/core/validation/validation_test.go
36+
index 6b837f21..ba1210fa 100644
37+
--- a/pkg/apis/core/validation/validation_test.go
38+
+++ b/pkg/apis/core/validation/validation_test.go
39+
@@ -26016,6 +26016,8 @@ func TestValidateDynamicResourceAllocation(t *testing.T) {
40+
}
41+
42+
failureCases := map[string]core.PodSpec{
43+
+ "static pod with resource claim reference": goodClaimReference,
44+
+ "static pod with resource claim template": goodClaimTemplate,
45+
"pod claim name with prefix": {
46+
Containers: []core.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent", TerminationMessagePolicy: "File"}},
47+
RestartPolicy: core.RestartPolicyAlways,
48+
@@ -26144,7 +26146,14 @@ func TestValidateDynamicResourceAllocation(t *testing.T) {
49+
}(),
50+
}
51+
for k, v := range failureCases {
52+
- if errs := ValidatePodSpec(&v, nil, field.NewPath("field"), PodValidationOptions{}); len(errs) == 0 {
53+
+ podMeta := shortPodName
54+
+ if strings.HasPrefix(k, "static pod") {
55+
+ podMeta = podMeta.DeepCopy()
56+
+ podMeta.Annotations = map[string]string{
57+
+ core.MirrorPodAnnotationKey: "True",
58+
+ }
59+
+ }
60+
+ if errs := ValidatePodSpec(&v.Spec, podMeta, field.NewPath("field"), PodValidationOptions{}); len(errs) == 0 {
61+
t.Errorf("expected failure for %q", k)
62+
}
63+
}
64+
diff --git a/pkg/kubelet/config/common.go b/pkg/kubelet/config/common.go
65+
index 69d67126..a73d6372 100644
66+
--- a/pkg/kubelet/config/common.go
67+
+++ b/pkg/kubelet/config/common.go
68+
@@ -106,6 +106,9 @@ type defaultFunc func(pod *api.Pod) error
69+
// A static pod tried to use a ClusterTrustBundle projected volume source.
70+
var ErrStaticPodTriedToUseClusterTrustBundle = errors.New("static pods may not use ClusterTrustBundle projected volume sources")
71+
72+
+// A static pod tried to use a resource claim.
73+
+var ErrStaticPodTriedToUseResourceClaims = errors.New("static pods may not use ResourceClaims")
74+
+
75+
// tryDecodeSinglePod takes data and tries to extract valid Pod config information from it.
76+
func tryDecodeSinglePod(data []byte, defaultFn defaultFunc) (parsed bool, pod *v1.Pod, err error) {
77+
// JSON is valid YAML, so this should work for everything.
78+
@@ -152,6 +155,9 @@ func tryDecodeSinglePod(data []byte, defaultFn defaultFunc) (parsed bool, pod *v
79+
}
80+
}
81+
}
82+
+ if len(v1Pod.Spec.ResourceClaims) > 0 {
83+
+ return true, nil, ErrStaticPodTriedToUseResourceClaims
84+
+ }
85+
86+
return true, v1Pod, nil
87+
}
88+
diff --git a/pkg/kubelet/config/common_test.go b/pkg/kubelet/config/common_test.go
89+
index f390b6f9..ae4f4473 100644
90+
--- a/pkg/kubelet/config/common_test.go
91+
+++ b/pkg/kubelet/config/common_test.go
92+
@@ -179,6 +179,62 @@ func TestDecodeSinglePodRejectsClusterTrustBundleVolumes(t *testing.T) {
93+
}
94+
}
95+
96+
+func TestDecodeSinglePodRejectsResourceClaims(t *testing.T) {
97+
+ grace := int64(30)
98+
+ enableServiceLinks := v1.DefaultEnableServiceLinks
99+
+ pod := &v1.Pod{
100+
+ TypeMeta: metav1.TypeMeta{
101+
+ APIVersion: "",
102+
+ },
103+
+ ObjectMeta: metav1.ObjectMeta{
104+
+ Name: "test",
105+
+ UID: "12345",
106+
+ Namespace: "mynamespace",
107+
+ },
108+
+ Spec: v1.PodSpec{
109+
+ RestartPolicy: v1.RestartPolicyAlways,
110+
+ DNSPolicy: v1.DNSClusterFirst,
111+
+ TerminationGracePeriodSeconds: &grace,
112+
+ Containers: []v1.Container{{
113+
+ Name: "image",
114+
+ Image: "test/image",
115+
+ ImagePullPolicy: "IfNotPresent",
116+
+ TerminationMessagePath: "/dev/termination-log",
117+
+ TerminationMessagePolicy: v1.TerminationMessageReadFile,
118+
+ SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
119+
+ Resources: v1.ResourceRequirements{
120+
+ Claims: []v1.ResourceClaim{{
121+
+ Name: "my-claim",
122+
+ }},
123+
+ },
124+
+ }},
125+
+ ResourceClaims: []v1.PodResourceClaim{{
126+
+ Name: "my-claim",
127+
+ ResourceClaimName: ptr.To("some-external-claim"),
128+
+ }},
129+
+ SecurityContext: &v1.PodSecurityContext{},
130+
+ SchedulerName: v1.DefaultSchedulerName,
131+
+ EnableServiceLinks: &enableServiceLinks,
132+
+ },
133+
+ Status: v1.PodStatus{
134+
+ PodIP: "1.2.3.4",
135+
+ PodIPs: []v1.PodIP{
136+
+ {
137+
+ IP: "1.2.3.4",
138+
+ },
139+
+ },
140+
+ },
141+
+ }
142+
+ json, err := runtime.Encode(clientscheme.Codecs.LegacyCodec(v1.SchemeGroupVersion), pod)
143+
+ if err != nil {
144+
+ t.Errorf("unexpected error: %v", err)
145+
+ }
146+
+ _, _, err = tryDecodeSinglePod(json, noDefault)
147+
+ if !errors.Is(err, ErrStaticPodTriedToUseResourceClaims) {
148+
+ t.Errorf("Got error %q, want %q", err, ErrStaticPodTriedToUseResourceClaims)
149+
+ }
150+
+}
151+
+
152+
func TestDecodePodList(t *testing.T) {
153+
grace := int64(30)
154+
enableServiceLinks := v1.DefaultEnableServiceLinks
155+
diff --git a/plugin/pkg/admission/noderestriction/admission.go b/plugin/pkg/admission/noderestriction/admission.go
156+
index 9388ac52..c58dbc34 100644
157+
--- a/plugin/pkg/admission/noderestriction/admission.go
158+
+++ b/plugin/pkg/admission/noderestriction/admission.go
159+
@@ -283,6 +283,10 @@ func (p *Plugin) admitPodCreate(nodeName string, a admission.Attributes) error {
160+
}
161+
}
162+
163+
+ if len(pod.Spec.ResourceClaims) > 0 {
164+
+ return admission.NewForbidden(a, fmt.Errorf("node %q can not create pods that reference resourceclaims", nodeName))
165+
+ }
166+
+
167+
return nil
168+
}
169+
170+
diff --git a/plugin/pkg/admission/noderestriction/admission_test.go b/plugin/pkg/admission/noderestriction/admission_test.go
171+
index 17bb2f50..10a8d99b 100644
172+
--- a/plugin/pkg/admission/noderestriction/admission_test.go
173+
+++ b/plugin/pkg/admission/noderestriction/admission_test.go
174+
@@ -401,6 +401,9 @@ func Test_nodePlugin_Admit(t *testing.T) {
175+
pvcpod, _ := makeTestPod("ns", "mypvcpod", "mynode", true)
176+
pvcpod.Spec.Volumes = []api.Volume{{VolumeSource: api.VolumeSource{PersistentVolumeClaim: &api.PersistentVolumeClaimVolumeSource{ClaimName: "foo"}}}}
177+
178+
+ claimpod, _ := makeTestPod("ns", "myclaimpod", "mynode", true)
179+
+ claimpod.Spec.ResourceClaims = []api.PodResourceClaim{{Name: "myclaim", ResourceClaimName: pointer.String("myexternalclaim")}}
180+
+
181+
tests := []admitTestCase{
182+
// Mirror pods bound to us
183+
{
184+
@@ -882,6 +885,12 @@ func Test_nodePlugin_Admit(t *testing.T) {
185+
attributes: admission.NewAttributesRecord(pvcpod, nil, podKind, pvcpod.Namespace, pvcpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
186+
err: "reference persistentvolumeclaims",
187+
},
188+
+ {
189+
+ name: "forbid create of pod referencing resourceclaim",
190+
+ podsGetter: noExistingPods,
191+
+ attributes: admission.NewAttributesRecord(claimpod, nil, podKind, claimpod.Namespace, claimpod.Name, podResource, "", admission.Create, &metav1.CreateOptions{}, false, mynode),
192+
+ err: "reference resourceclaim",
193+
+ },
194+
195+
// My node object
196+
{
197+
--
198+
2.45.2
199+

SPECS/kubernetes/kubernetes.spec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
Summary: Microsoft Kubernetes
1111
Name: kubernetes
1212
Version: 1.30.10
13-
Release: 8%{?dist}
13+
Release: 9%{?dist}
1414
License: ASL 2.0
1515
Vendor: Microsoft Corporation
1616
Distribution: Azure Linux
@@ -26,6 +26,7 @@ Patch4: CVE-2025-22869.patch
2626
Patch5: CVE-2024-51744.patch
2727
Patch6: CVE-2025-30204.patch
2828
Patch7: CVE-2025-22872.patch
29+
Patch8: CVE-2025-4563.patch
2930
BuildRequires: flex-devel
3031
BuildRequires: glibc-static >= 2.38-11%{?dist}
3132
BuildRequires: golang
@@ -277,6 +278,9 @@ fi
277278
%{_exec_prefix}/local/bin/pause
278279

279280
%changelog
281+
* Mon Jun 30 2025 Durga Jagadeesh Palli <[email protected]> - 1.30.10-9
282+
- Patch CVE-2025-4563
283+
280284
* Thu May 22 2025 Kanishk Bansal <[email protected]> - 1.30.10-8
281285
- Bump to rebuild with updated glibc
282286

0 commit comments

Comments
 (0)