From 4121c1fc79a34d664c6514946ed0e0399af8c154 Mon Sep 17 00:00:00 2001 From: Patrick Ohly Date: Thu, 13 Jul 2023 20:39:48 +0200 Subject: [PATCH] auth: don't allow kubelet to from modify ResourceClaimStatuses The status determines which claims kubelet is allowed to access when claims get created from a template. Therefore kubelet must not be allowed to modify that part of the status, because otherwise it could add an entry and then gain access to a claim it should have access to. --- .../admission/noderestriction/admission.go | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/plugin/pkg/admission/noderestriction/admission.go b/plugin/pkg/admission/noderestriction/admission.go index cb21f2360f4..9139fcc40cb 100644 --- a/plugin/pkg/admission/noderestriction/admission.go +++ b/plugin/pkg/admission/noderestriction/admission.go @@ -288,6 +288,9 @@ func (p *Plugin) admitPodStatus(nodeName string, a admission.Attributes) error { if !labels.Equals(oldPod.Labels, newPod.Labels) { return admission.NewForbidden(a, fmt.Errorf("node %q cannot update labels through pod status", nodeName)) } + if !resourceClaimStatusesEqual(oldPod.Status.ResourceClaimStatuses, newPod.Status.ResourceClaimStatuses) { + return admission.NewForbidden(a, fmt.Errorf("node %q cannot update resource claim statues", nodeName)) + } return nil default: @@ -295,6 +298,29 @@ func (p *Plugin) admitPodStatus(nodeName string, a admission.Attributes) error { } } +func resourceClaimStatusesEqual(statusA, statusB []api.PodResourceClaimStatus) bool { + if len(statusA) != len(statusB) { + return false + } + // In most cases, status entries only get added once and not modified. + // But this cannot be guaranteed, so for the sake of correctness in all + // cases this code here has to check. + for i := range statusA { + if statusA[i].Name != statusB[i].Name { + return false + } + claimNameA := statusA[i].ResourceClaimName + claimNameB := statusB[i].ResourceClaimName + if (claimNameA == nil) != (claimNameB == nil) { + return false + } + if claimNameA != nil && *claimNameA != *claimNameB { + return false + } + } + return true +} + // admitPodEviction allows to evict a pod if it is assigned to the current node. func (p *Plugin) admitPodEviction(nodeName string, a admission.Attributes) error { switch a.GetOperation() {