mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-12-07 18:06:21 +00:00
node authorizer: limit kubelet access to ResourceClaim objects
As discussed during the KEP and code review of dynamic resource allocation for Kubernetes 1.26, to increase security kubelet should only get read access to those ResourceClaim objects that are needed by a pod on the node. This can be enforced easily by the node authorizer: - the names of the objects are defined by the pod status - there is no indirection as with volumes (pod -> pvc -> pv) Normally the graph only gets updated when a pod is not scheduled yet. Resource claim status changes can still happen after that, so they also must trigger an update.
This commit is contained in:
@@ -78,8 +78,9 @@ func (g *graphPopulator) updatePod(oldObj, obj interface{}) {
|
||||
return
|
||||
}
|
||||
if oldPod, ok := oldObj.(*corev1.Pod); ok && oldPod != nil {
|
||||
if (pod.Spec.NodeName == oldPod.Spec.NodeName) && (pod.UID == oldPod.UID) {
|
||||
// Node and uid are unchanged, all object references in the pod spec are immutable
|
||||
if (pod.Spec.NodeName == oldPod.Spec.NodeName) && (pod.UID == oldPod.UID) &&
|
||||
resourceClaimStatusesEqual(oldPod.Status.ResourceClaimStatuses, pod.Status.ResourceClaimStatuses) {
|
||||
// Node and uid are unchanged, all object references in the pod spec are immutable respectively unmodified (claim statuses).
|
||||
klog.V(5).Infof("updatePod %s/%s, node unchanged", pod.Namespace, pod.Name)
|
||||
return
|
||||
}
|
||||
@@ -91,6 +92,29 @@ func (g *graphPopulator) updatePod(oldObj, obj interface{}) {
|
||||
klog.V(5).Infof("updatePod %s/%s for node %s completed in %v", pod.Namespace, pod.Name, pod.Spec.NodeName, time.Since(startTime))
|
||||
}
|
||||
|
||||
func resourceClaimStatusesEqual(statusA, statusB []corev1.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
|
||||
}
|
||||
|
||||
func (g *graphPopulator) deletePod(obj interface{}) {
|
||||
if tombstone, ok := obj.(cache.DeletedFinalStateUnknown); ok {
|
||||
obj = tombstone.Obj
|
||||
|
||||
Reference in New Issue
Block a user