Kubernetes node disk Denial of Service by writing to container /etc/hosts
Description
The Kubernetes kubelet component in versions 1.1-1.16.12, 1.17.0-1.17.8 and 1.18.0-1.18.5 do not account for disk usage by a pod which writes to its own /etc/hosts file. The /etc/hosts file mounted in a pod by kubelet is not included by the kubelet eviction manager when calculating ephemeral storage usage by a pod. If a pod writes a large amount of data to the /etc/hosts file, it could fill the storage space of the node and cause the node to fail.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
k8s.io/kubernetes/pkg/kubeletGo | >= 1.1.0, < 1.16.13 | 1.16.13 |
k8s.io/kubernetes/pkg/kubeletGo | >= 1.17.0, < 1.17.9 | 1.17.9 |
k8s.io/kubernetes/pkg/kubeletGo | >= 1.18.0, < 1.18.6 | 1.18.6 |
Affected products
1- Range: 1.15
Patches
3530f199b6e07Include pod /etc/hosts in ephemeral storage calculation for eviction
7 files changed · +27 −6
pkg/kubelet/eviction/BUILD+1 −0 modified@@ -65,6 +65,7 @@ go_library( "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library",
pkg/kubelet/eviction/eviction_manager.go+6 −1 modified@@ -26,6 +26,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/clock" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/tools/record" @@ -98,6 +99,8 @@ type managerImpl struct { thresholdNotifiers []ThresholdNotifier // thresholdsLastUpdated is the last time the thresholdNotifiers were updated. thresholdsLastUpdated time.Time + // etcHostsPath is a function that will get the etc-hosts file's path for a pod given its UID + etcHostsPath func(podUID types.UID) string } // ensure it implements the required interface @@ -114,6 +117,7 @@ func NewManager( recorder record.EventRecorder, nodeRef *v1.ObjectReference, clock clock.Clock, + etcHostsPath func(types.UID) string, ) (Manager, lifecycle.PodAdmitHandler) { manager := &managerImpl{ clock: clock, @@ -129,6 +133,7 @@ func NewManager( thresholdsFirstObservedAt: thresholdsObservedAt{}, dedicatedImageFs: nil, thresholdNotifiers: []ThresholdNotifier{}, + etcHostsPath: etcHostsPath, } return manager, manager } @@ -515,7 +520,7 @@ func (m *managerImpl) podEphemeralStorageLimitEviction(podStats statsapi.PodStat } else { fsStatsSet = []fsStatsType{fsStatsRoot, fsStatsLogs, fsStatsLocalVolumeSource} } - podEphemeralUsage, err := podLocalEphemeralStorageUsage(podStats, pod, fsStatsSet) + podEphemeralUsage, err := podLocalEphemeralStorageUsage(podStats, pod, fsStatsSet, m.etcHostsPath(pod.UID)) if err != nil { klog.Errorf("eviction manager: error getting pod disk usage %v", err) return false
pkg/kubelet/eviction/helpers.go+8 −1 modified@@ -18,6 +18,7 @@ package eviction import ( "fmt" + "os" "sort" "strconv" "strings" @@ -415,7 +416,7 @@ func localEphemeralVolumeNames(pod *v1.Pod) []string { } // podLocalEphemeralStorageUsage aggregates pod local ephemeral storage usage and inode consumption for the specified stats to measure. -func podLocalEphemeralStorageUsage(podStats statsapi.PodStats, pod *v1.Pod, statsToMeasure []fsStatsType) (v1.ResourceList, error) { +func podLocalEphemeralStorageUsage(podStats statsapi.PodStats, pod *v1.Pod, statsToMeasure []fsStatsType, etcHostsPath string) (v1.ResourceList, error) { disk := resource.Quantity{Format: resource.BinarySI} inodes := resource.Quantity{Format: resource.DecimalSI} @@ -429,6 +430,12 @@ func podLocalEphemeralStorageUsage(podStats statsapi.PodStats, pod *v1.Pod, stat disk.Add(podLocalVolumeUsageList[v1.ResourceEphemeralStorage]) inodes.Add(podLocalVolumeUsageList[resourceInodes]) } + if len(etcHostsPath) > 0 { + if stat, err := os.Stat(etcHostsPath); err == nil { + disk.Add(*resource.NewQuantity(int64(stat.Size()), resource.BinarySI)) + inodes.Add(*resource.NewQuantity(int64(1), resource.DecimalSI)) + } + } return v1.ResourceList{ v1.ResourceEphemeralStorage: disk, resourceInodes: inodes,
pkg/kubelet/kubelet.go+2 −1 modified@@ -843,8 +843,9 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, klet.backOff = flowcontrol.NewBackOff(backOffPeriod, MaxContainerBackOff) klet.podKillingCh = make(chan *kubecontainer.PodPair, podKillingChannelCapacity) + etcHostsPathFunc := func(podUID types.UID) string { return getEtcHostsPath(klet.getPodDir(podUID)) } // setup eviction manager - evictionManager, evictionAdmitHandler := eviction.NewManager(klet.resourceAnalyzer, evictionConfig, killPodNow(klet.podWorkers, kubeDeps.Recorder), klet.podManager.GetMirrorPodByPod, klet.imageManager, klet.containerGC, kubeDeps.Recorder, nodeRef, klet.clock) + evictionManager, evictionAdmitHandler := eviction.NewManager(klet.resourceAnalyzer, evictionConfig, killPodNow(klet.podWorkers, kubeDeps.Recorder), klet.podManager.GetMirrorPodByPod, klet.imageManager, klet.containerGC, kubeDeps.Recorder, nodeRef, klet.clock, etcHostsPathFunc) klet.evictionManager = evictionManager klet.admitHandlers.AddPodAdmitHandler(evictionAdmitHandler)
pkg/kubelet/kubelet_pods.go+6 −1 modified@@ -291,11 +291,16 @@ func translateMountPropagation(mountMode *v1.MountPropagationMode) (runtimeapi.M } } +// getEtcHostsPath returns the full host-side path to a pod's generated /etc/hosts file +func getEtcHostsPath(podDir string) string { + return path.Join(podDir, "etc-hosts") +} + // makeHostsMount makes the mountpoint for the hosts file that the containers // in a pod are injected with. podIPs is provided instead of podIP as podIPs // are present even if dual-stack feature flag is not enabled. func makeHostsMount(podDir string, podIPs []string, hostName, hostDomainName string, hostAliases []v1.HostAlias, useHostNetwork bool) (*kubecontainer.Mount, error) { - hostsFilePath := path.Join(podDir, "etc-hosts") + hostsFilePath := getEtcHostsPath(podDir) if err := ensureHostsFile(hostsFilePath, podIPs, hostName, hostDomainName, hostAliases, useHostNetwork); err != nil { return nil, err }
pkg/kubelet/kubelet_test.go+2 −1 modified@@ -291,8 +291,9 @@ func newTestKubeletWithImageList( UID: types.UID(kubelet.nodeName), Namespace: "", } + etcHostsPathFunc := func(podUID types.UID) string { return getEtcHostsPath(kubelet.getPodDir(podUID)) } // setup eviction manager - evictionManager, evictionAdmitHandler := eviction.NewManager(kubelet.resourceAnalyzer, eviction.Config{}, killPodNow(kubelet.podWorkers, fakeRecorder), kubelet.podManager.GetMirrorPodByPod, kubelet.imageManager, kubelet.containerGC, fakeRecorder, nodeRef, kubelet.clock) + evictionManager, evictionAdmitHandler := eviction.NewManager(kubelet.resourceAnalyzer, eviction.Config{}, killPodNow(kubelet.podWorkers, fakeRecorder), kubelet.podManager.GetMirrorPodByPod, kubelet.imageManager, kubelet.containerGC, fakeRecorder, nodeRef, kubelet.clock, etcHostsPathFunc) kubelet.evictionManager = evictionManager kubelet.admitHandlers.AddPodAdmitHandler(evictionAdmitHandler)
pkg/kubelet/runonce_test.go+2 −1 modified@@ -126,7 +126,8 @@ func TestRunOnce(t *testing.T) { return nil } fakeMirrodPodFunc := func(*v1.Pod) (*v1.Pod, bool) { return nil, false } - evictionManager, evictionAdmitHandler := eviction.NewManager(kb.resourceAnalyzer, eviction.Config{}, fakeKillPodFunc, fakeMirrodPodFunc, nil, nil, kb.recorder, nodeRef, kb.clock) + etcHostsPathFunc := func(podUID types.UID) string { return getEtcHostsPath(kb.getPodDir(podUID)) } + evictionManager, evictionAdmitHandler := eviction.NewManager(kb.resourceAnalyzer, eviction.Config{}, fakeKillPodFunc, fakeMirrodPodFunc, nil, nil, kb.recorder, nodeRef, kb.clock, etcHostsPathFunc) kb.evictionManager = evictionManager kb.admitHandlers.AddPodAdmitHandler(evictionAdmitHandler)
68750fefd3dfInclude pod /etc/hosts in ephemeral storage calculation for eviction
7 files changed · +27 −6
pkg/kubelet/eviction/BUILD+1 −0 modified@@ -66,6 +66,7 @@ go_library( "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library",
pkg/kubelet/eviction/eviction_manager.go+6 −1 modified@@ -26,6 +26,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/clock" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/tools/record" @@ -90,6 +91,8 @@ type managerImpl struct { thresholdNotifiers []ThresholdNotifier // thresholdsLastUpdated is the last time the thresholdNotifiers were updated. thresholdsLastUpdated time.Time + // etcHostsPath is a function that will get the etc-hosts file's path for a pod given its UID + etcHostsPath func(podUID types.UID) string } // ensure it implements the required interface @@ -106,6 +109,7 @@ func NewManager( recorder record.EventRecorder, nodeRef *v1.ObjectReference, clock clock.Clock, + etcHostsPath func(types.UID) string, ) (Manager, lifecycle.PodAdmitHandler) { manager := &managerImpl{ clock: clock, @@ -121,6 +125,7 @@ func NewManager( thresholdsFirstObservedAt: thresholdsObservedAt{}, dedicatedImageFs: nil, thresholdNotifiers: []ThresholdNotifier{}, + etcHostsPath: etcHostsPath, } return manager, manager } @@ -503,7 +508,7 @@ func (m *managerImpl) podEphemeralStorageLimitEviction(podStats statsapi.PodStat } else { fsStatsSet = []fsStatsType{fsStatsRoot, fsStatsLogs, fsStatsLocalVolumeSource} } - podEphemeralUsage, err := podLocalEphemeralStorageUsage(podStats, pod, fsStatsSet) + podEphemeralUsage, err := podLocalEphemeralStorageUsage(podStats, pod, fsStatsSet, m.etcHostsPath(pod.UID)) if err != nil { klog.Errorf("eviction manager: error getting pod disk usage %v", err) return false
pkg/kubelet/eviction/helpers.go+8 −1 modified@@ -18,6 +18,7 @@ package eviction import ( "fmt" + "os" "sort" "strconv" "strings" @@ -415,7 +416,7 @@ func localEphemeralVolumeNames(pod *v1.Pod) []string { } // podLocalEphemeralStorageUsage aggregates pod local ephemeral storage usage and inode consumption for the specified stats to measure. -func podLocalEphemeralStorageUsage(podStats statsapi.PodStats, pod *v1.Pod, statsToMeasure []fsStatsType) (v1.ResourceList, error) { +func podLocalEphemeralStorageUsage(podStats statsapi.PodStats, pod *v1.Pod, statsToMeasure []fsStatsType, etcHostsPath string) (v1.ResourceList, error) { disk := resource.Quantity{Format: resource.BinarySI} inodes := resource.Quantity{Format: resource.DecimalSI} @@ -429,6 +430,12 @@ func podLocalEphemeralStorageUsage(podStats statsapi.PodStats, pod *v1.Pod, stat disk.Add(podLocalVolumeUsageList[v1.ResourceEphemeralStorage]) inodes.Add(podLocalVolumeUsageList[resourceInodes]) } + if len(etcHostsPath) > 0 { + if stat, err := os.Stat(etcHostsPath); err == nil { + disk.Add(*resource.NewQuantity(int64(stat.Size()), resource.BinarySI)) + inodes.Add(*resource.NewQuantity(int64(1), resource.DecimalSI)) + } + } return v1.ResourceList{ v1.ResourceEphemeralStorage: disk, resourceInodes: inodes,
pkg/kubelet/kubelet.go+2 −1 modified@@ -831,8 +831,9 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, klet.backOff = flowcontrol.NewBackOff(backOffPeriod, MaxContainerBackOff) klet.podKillingCh = make(chan *kubecontainer.PodPair, podKillingChannelCapacity) + etcHostsPathFunc := func(podUID types.UID) string { return getEtcHostsPath(klet.getPodDir(podUID)) } // setup eviction manager - evictionManager, evictionAdmitHandler := eviction.NewManager(klet.resourceAnalyzer, evictionConfig, killPodNow(klet.podWorkers, kubeDeps.Recorder), klet.podManager.GetMirrorPodByPod, klet.imageManager, klet.containerGC, kubeDeps.Recorder, nodeRef, klet.clock) + evictionManager, evictionAdmitHandler := eviction.NewManager(klet.resourceAnalyzer, evictionConfig, killPodNow(klet.podWorkers, kubeDeps.Recorder), klet.podManager.GetMirrorPodByPod, klet.imageManager, klet.containerGC, kubeDeps.Recorder, nodeRef, klet.clock, etcHostsPathFunc) klet.evictionManager = evictionManager klet.admitHandlers.AddPodAdmitHandler(evictionAdmitHandler)
pkg/kubelet/kubelet_pods.go+6 −1 modified@@ -291,10 +291,15 @@ func translateMountPropagation(mountMode *v1.MountPropagationMode) (runtimeapi.M } } +// getEtcHostsPath returns the full host-side path to a pod's generated /etc/hosts file +func getEtcHostsPath(podDir string) string { + return path.Join(podDir, "etc-hosts") +} + // makeHostsMount makes the mountpoint for the hosts file that the containers // in a pod are injected with. func makeHostsMount(podDir, podIP, hostName, hostDomainName string, hostAliases []v1.HostAlias, useHostNetwork bool) (*kubecontainer.Mount, error) { - hostsFilePath := path.Join(podDir, "etc-hosts") + hostsFilePath := getEtcHostsPath(podDir) if err := ensureHostsFile(hostsFilePath, podIP, hostName, hostDomainName, hostAliases, useHostNetwork); err != nil { return nil, err }
pkg/kubelet/kubelet_test.go+2 −1 modified@@ -291,8 +291,9 @@ func newTestKubeletWithImageList( UID: types.UID(kubelet.nodeName), Namespace: "", } + etcHostsPathFunc := func(podUID types.UID) string { return getEtcHostsPath(kubelet.getPodDir(podUID)) } // setup eviction manager - evictionManager, evictionAdmitHandler := eviction.NewManager(kubelet.resourceAnalyzer, eviction.Config{}, killPodNow(kubelet.podWorkers, fakeRecorder), kubelet.podManager.GetMirrorPodByPod, kubelet.imageManager, kubelet.containerGC, fakeRecorder, nodeRef, kubelet.clock) + evictionManager, evictionAdmitHandler := eviction.NewManager(kubelet.resourceAnalyzer, eviction.Config{}, killPodNow(kubelet.podWorkers, fakeRecorder), kubelet.podManager.GetMirrorPodByPod, kubelet.imageManager, kubelet.containerGC, fakeRecorder, nodeRef, kubelet.clock, etcHostsPathFunc) kubelet.evictionManager = evictionManager kubelet.admitHandlers.AddPodAdmitHandler(evictionAdmitHandler)
pkg/kubelet/runonce_test.go+2 −1 modified@@ -125,7 +125,8 @@ func TestRunOnce(t *testing.T) { return nil } fakeMirrodPodFunc := func(*v1.Pod) (*v1.Pod, bool) { return nil, false } - evictionManager, evictionAdmitHandler := eviction.NewManager(kb.resourceAnalyzer, eviction.Config{}, fakeKillPodFunc, fakeMirrodPodFunc, nil, nil, kb.recorder, nodeRef, kb.clock) + etcHostsPathFunc := func(podUID types.UID) string { return getEtcHostsPath(kb.getPodDir(podUID)) } + evictionManager, evictionAdmitHandler := eviction.NewManager(kb.resourceAnalyzer, eviction.Config{}, fakeKillPodFunc, fakeMirrodPodFunc, nil, nil, kb.recorder, nodeRef, kb.clock, etcHostsPathFunc) kb.evictionManager = evictionManager kb.admitHandlers.AddPodAdmitHandler(evictionAdmitHandler)
7fd849cffa2fInclude pod /etc/hosts in ephemeral storage calculation for eviction
7 files changed · +27 −6
pkg/kubelet/eviction/BUILD+1 −0 modified@@ -65,6 +65,7 @@ go_library( "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", + "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/clock:go_default_library", "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library",
pkg/kubelet/eviction/eviction_manager.go+6 −1 modified@@ -26,6 +26,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/clock" utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/tools/record" @@ -89,6 +90,8 @@ type managerImpl struct { thresholdNotifiers []ThresholdNotifier // thresholdsLastUpdated is the last time the thresholdNotifiers were updated. thresholdsLastUpdated time.Time + // etcHostsPath is a function that will get the etc-hosts file's path for a pod given its UID + etcHostsPath func(podUID types.UID) string } // ensure it implements the required interface @@ -105,6 +108,7 @@ func NewManager( recorder record.EventRecorder, nodeRef *v1.ObjectReference, clock clock.Clock, + etcHostsPath func(types.UID) string, ) (Manager, lifecycle.PodAdmitHandler) { manager := &managerImpl{ clock: clock, @@ -120,6 +124,7 @@ func NewManager( thresholdsFirstObservedAt: thresholdsObservedAt{}, dedicatedImageFs: nil, thresholdNotifiers: []ThresholdNotifier{}, + etcHostsPath: etcHostsPath, } return manager, manager } @@ -503,7 +508,7 @@ func (m *managerImpl) podEphemeralStorageLimitEviction(podStats statsapi.PodStat } else { fsStatsSet = []fsStatsType{fsStatsRoot, fsStatsLogs, fsStatsLocalVolumeSource} } - podEphemeralUsage, err := podLocalEphemeralStorageUsage(podStats, pod, fsStatsSet) + podEphemeralUsage, err := podLocalEphemeralStorageUsage(podStats, pod, fsStatsSet, m.etcHostsPath(pod.UID)) if err != nil { klog.Errorf("eviction manager: error getting pod disk usage %v", err) return false
pkg/kubelet/eviction/helpers.go+8 −1 modified@@ -18,6 +18,7 @@ package eviction import ( "fmt" + "os" "sort" "strconv" "strings" @@ -415,7 +416,7 @@ func localEphemeralVolumeNames(pod *v1.Pod) []string { } // podLocalEphemeralStorageUsage aggregates pod local ephemeral storage usage and inode consumption for the specified stats to measure. -func podLocalEphemeralStorageUsage(podStats statsapi.PodStats, pod *v1.Pod, statsToMeasure []fsStatsType) (v1.ResourceList, error) { +func podLocalEphemeralStorageUsage(podStats statsapi.PodStats, pod *v1.Pod, statsToMeasure []fsStatsType, etcHostsPath string) (v1.ResourceList, error) { disk := resource.Quantity{Format: resource.BinarySI} inodes := resource.Quantity{Format: resource.DecimalSI} @@ -429,6 +430,12 @@ func podLocalEphemeralStorageUsage(podStats statsapi.PodStats, pod *v1.Pod, stat disk.Add(podLocalVolumeUsageList[v1.ResourceEphemeralStorage]) inodes.Add(podLocalVolumeUsageList[resourceInodes]) } + if len(etcHostsPath) > 0 { + if stat, err := os.Stat(etcHostsPath); err == nil { + disk.Add(*resource.NewQuantity(int64(stat.Size()), resource.BinarySI)) + inodes.Add(*resource.NewQuantity(int64(1), resource.DecimalSI)) + } + } return v1.ResourceList{ v1.ResourceEphemeralStorage: disk, resourceInodes: inodes,
pkg/kubelet/kubelet.go+2 −1 modified@@ -833,8 +833,9 @@ func NewMainKubelet(kubeCfg *kubeletconfiginternal.KubeletConfiguration, klet.backOff = flowcontrol.NewBackOff(backOffPeriod, MaxContainerBackOff) klet.podKillingCh = make(chan *kubecontainer.PodPair, podKillingChannelCapacity) + etcHostsPathFunc := func(podUID types.UID) string { return getEtcHostsPath(klet.getPodDir(podUID)) } // setup eviction manager - evictionManager, evictionAdmitHandler := eviction.NewManager(klet.resourceAnalyzer, evictionConfig, killPodNow(klet.podWorkers, kubeDeps.Recorder), klet.podManager.GetMirrorPodByPod, klet.imageManager, klet.containerGC, kubeDeps.Recorder, nodeRef, klet.clock) + evictionManager, evictionAdmitHandler := eviction.NewManager(klet.resourceAnalyzer, evictionConfig, killPodNow(klet.podWorkers, kubeDeps.Recorder), klet.podManager.GetMirrorPodByPod, klet.imageManager, klet.containerGC, kubeDeps.Recorder, nodeRef, klet.clock, etcHostsPathFunc) klet.evictionManager = evictionManager klet.admitHandlers.AddPodAdmitHandler(evictionAdmitHandler)
pkg/kubelet/kubelet_pods.go+6 −1 modified@@ -291,11 +291,16 @@ func translateMountPropagation(mountMode *v1.MountPropagationMode) (runtimeapi.M } } +// getEtcHostsPath returns the full host-side path to a pod's generated /etc/hosts file +func getEtcHostsPath(podDir string) string { + return path.Join(podDir, "etc-hosts") +} + // makeHostsMount makes the mountpoint for the hosts file that the containers // in a pod are injected with. podIPs is provided instead of podIP as podIPs // are present even if dual-stack feature flag is not enabled. func makeHostsMount(podDir string, podIPs []string, hostName, hostDomainName string, hostAliases []v1.HostAlias, useHostNetwork bool) (*kubecontainer.Mount, error) { - hostsFilePath := path.Join(podDir, "etc-hosts") + hostsFilePath := getEtcHostsPath(podDir) if err := ensureHostsFile(hostsFilePath, podIPs, hostName, hostDomainName, hostAliases, useHostNetwork); err != nil { return nil, err }
pkg/kubelet/kubelet_test.go+2 −1 modified@@ -292,8 +292,9 @@ func newTestKubeletWithImageList( UID: types.UID(kubelet.nodeName), Namespace: "", } + etcHostsPathFunc := func(podUID types.UID) string { return getEtcHostsPath(kubelet.getPodDir(podUID)) } // setup eviction manager - evictionManager, evictionAdmitHandler := eviction.NewManager(kubelet.resourceAnalyzer, eviction.Config{}, killPodNow(kubelet.podWorkers, fakeRecorder), kubelet.podManager.GetMirrorPodByPod, kubelet.imageManager, kubelet.containerGC, fakeRecorder, nodeRef, kubelet.clock) + evictionManager, evictionAdmitHandler := eviction.NewManager(kubelet.resourceAnalyzer, eviction.Config{}, killPodNow(kubelet.podWorkers, fakeRecorder), kubelet.podManager.GetMirrorPodByPod, kubelet.imageManager, kubelet.containerGC, fakeRecorder, nodeRef, kubelet.clock, etcHostsPathFunc) kubelet.evictionManager = evictionManager kubelet.admitHandlers.AddPodAdmitHandler(evictionAdmitHandler)
pkg/kubelet/runonce_test.go+2 −1 modified@@ -126,7 +126,8 @@ func TestRunOnce(t *testing.T) { return nil } fakeMirrodPodFunc := func(*v1.Pod) (*v1.Pod, bool) { return nil, false } - evictionManager, evictionAdmitHandler := eviction.NewManager(kb.resourceAnalyzer, eviction.Config{}, fakeKillPodFunc, fakeMirrodPodFunc, nil, nil, kb.recorder, nodeRef, kb.clock) + etcHostsPathFunc := func(podUID types.UID) string { return getEtcHostsPath(kb.getPodDir(podUID)) } + evictionManager, evictionAdmitHandler := eviction.NewManager(kb.resourceAnalyzer, eviction.Config{}, fakeKillPodFunc, fakeMirrodPodFunc, nil, nil, kb.recorder, nodeRef, kb.clock, etcHostsPathFunc) kb.evictionManager = evictionManager kb.admitHandlers.AddPodAdmitHandler(evictionAdmitHandler)
Vulnerability mechanics
Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
11- github.com/advisories/GHSA-55qj-gj3x-jq9rghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2020-8557ghsaADVISORY
- github.com/kubernetes/kubernetes/commit/530f199b6e07cdaab32361e39709ac45f3fdc446ghsaWEB
- github.com/kubernetes/kubernetes/commit/68750fefd3df76b7b008ef7b18e8acd18d5c2f2eghsaWEB
- github.com/kubernetes/kubernetes/commit/7fd849cffa2f93061fbcb0a6ae4efd0539b1e981ghsaWEB
- github.com/kubernetes/kubernetes/issues/93032ghsax_refsource_CONFIRMWEB
- github.com/kubernetes/kubernetes/pull/92921ghsaWEB
- groups.google.com/g/kubernetes-security-announce/c/cB_JUsYEKyY/m/vVSO61AhBwAJghsamailing-listx_refsource_MLISTWEB
- pkg.go.dev/vuln/GO-2024-2753ghsaWEB
- security.netapp.com/advisory/ntap-20200821-0002ghsaWEB
- security.netapp.com/advisory/ntap-20200821-0002/mitrex_refsource_CONFIRM
News mentions
0No linked articles in our index yet.