Kubernetes - Windows nodes - Insufficient input sanitization leads to privilege escalation
Description
A security issue was discovered in Kubernetes where a user that can create pods on Windows nodes may be able to escalate to admin privileges on those nodes. Kubernetes clusters are only affected if they include Windows nodes.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Kubernetes vulnerability (CVSS 8.8) allows a user with pod creation privileges on Windows nodes to escalate to admin privileges due to insufficient input sanitization.
Vulnerability
Overview CVE-2023-3955 is a high-severity privilege escalation vulnerability in Kubernetes that affects clusters containing Windows nodes. The root cause is insufficient input sanitization when passing parameters to PowerShell scripts in the kubelet component. An attacker who can create pods on a Windows node can inject arbitrary PowerShell commands, leading to full administrative control over the node [1][3].
Exploitation
Conditions Exploitation requires the attacker to have pod creation privileges on a Windows node in a Kubernetes cluster. No additional authentication is needed beyond the standard Kubernetes RBAC permissions for creating pods. The vulnerability is present in kubelet versions up to and including v1.28.0, v1.27.4, v1.26.7, v1.25.12, and v1.24.16 [3][4]. Clusters without Windows nodes are not affected [1].
Impact
A successful attack grants the attacker administrative privileges (SYSTEM level) on the affected Windows node. This can lead to complete compromise of the node, including access to sensitive data, the ability to modify cluster operations, and potential lateral movement within the Kubernetes environment [3][4].
Mitigation and
Fixes The vulnerability is patched in kubelet versions v1.28.1, v1.27.5, v1.26.8, v1.25.13, and v1.24.17. The fix involves passing parameters to PowerShell via environment variables instead of command-line arguments, preventing injection [2][3]. A minor impact of the fix is that passing disk format options to in-tree Windows volume plugins will result in an error, though no known use cases rely on this functionality [3][4]. No other mitigations are available [3].
- NVD - CVE-2023-3955
- Use environment variables for parameters in Powershell by ritazh · Pull Request #120128 · kubernetes/kubernetes
- CVE-2023-3955: Insufficient input sanitization on Windows nodes leads to privilege escalation
- [Security Advisory] CVE-2023-3955: Insufficient input sanitization on Windows nodes leads to privilege escalation
AI Insight generated on May 20, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
k8s.io/kubernetesGo | >= 1.28.0, < 1.28.1 | 1.28.1 |
k8s.io/kubernetesGo | >= 1.27.0, < 1.27.5 | 1.27.5 |
k8s.io/kubernetesGo | >= 1.26.0, < 1.26.8 | 1.26.8 |
k8s.io/kubernetesGo | >= 1.25.0, < 1.25.13 | 1.25.13 |
k8s.io/kubernetesGo | < 1.24.17 | 1.24.17 |
Affected products
119- osv-coords118 versionspkg:apk/chainguard/argo-cd-2.7pkg:apk/chainguard/argo-cd-2.7-compatpkg:apk/chainguard/argo-cd-2.7-repo-serverpkg:apk/chainguard/argo-cd-2.8pkg:apk/chainguard/argo-cd-2.8-compatpkg:apk/chainguard/argo-cd-2.8-repo-serverpkg:apk/chainguard/aws-ebs-csi-driver-1.18pkg:apk/chainguard/aws-ebs-csi-driver-1.19pkg:apk/chainguard/aws-efs-csi-driverpkg:apk/chainguard/aws-efs-csi-driver-fipspkg:apk/chainguard/aws-efs-csi-driver-fips-1.6pkg:apk/chainguard/calicopkg:apk/chainguard/calico-apiserverpkg:apk/chainguard/calico-app-policypkg:apk/chainguard/calico-cnipkg:apk/chainguard/calico-cni-compatpkg:apk/chainguard/calico-cni-fips-3.25-compatpkg:apk/chainguard/calico-cni-fips-compatpkg:apk/chainguard/calicoctlpkg:apk/chainguard/calicoctl-fipspkg:apk/chainguard/calicoctl-fips-3.25pkg:apk/chainguard/calico-felixpkg:apk/chainguard/calico-fipspkg:apk/chainguard/calico-fips-3.25pkg:apk/chainguard/calico-fips-apiserverpkg:apk/chainguard/calico-fips-apiserver-3.25pkg:apk/chainguard/calico-fips-app-policypkg:apk/chainguard/calico-fips-app-policy-3.25pkg:apk/chainguard/calico-fips-cnipkg:apk/chainguard/calico-fips-cni-3.25pkg:apk/chainguard/calico-fips-felixpkg:apk/chainguard/calico-fips-felix-3.25pkg:apk/chainguard/calico-fips-key-cert-provisionerpkg:apk/chainguard/calico-fips-kube-controllerspkg:apk/chainguard/calico-fips-kube-controllers-3.25pkg:apk/chainguard/calico-fips-nodepkg:apk/chainguard/calico-fips-node-3.25pkg:apk/chainguard/calico-fips-pod2daemonpkg:apk/chainguard/calico-fips-pod2daemon-3.25pkg:apk/chainguard/calico-fips-typha-clientpkg:apk/chainguard/calico-fips-typha-client-3.25pkg:apk/chainguard/calico-fips-typhadpkg:apk/chainguard/calico-fips-typhad-3.25pkg:apk/chainguard/calico-key-cert-provisionerpkg:apk/chainguard/calico-kube-controllerspkg:apk/chainguard/calico-nodepkg:apk/chainguard/calico-pod2daemonpkg:apk/chainguard/calico-pod2daemon-flexvol-compatpkg:apk/chainguard/calico-typha-clientpkg:apk/chainguard/calico-typhadpkg:apk/chainguard/cluster-autoscaler-1.25pkg:apk/chainguard/cluster-autoscaler-1.25-compatpkg:apk/chainguard/cluster-autoscaler-1.26pkg:apk/chainguard/cluster-autoscaler-1.26-compatpkg:apk/chainguard/cluster-autoscaler-fips-1.25pkg:apk/chainguard/cluster-autoscaler-fips-1.25-compatpkg:apk/chainguard/cluster-autoscaler-fips-1.28pkg:apk/chainguard/cluster-autoscaler-fips-1.28-compatpkg:apk/chainguard/kubeflow-pipelinespkg:apk/chainguard/kubeflow-pipelines-apiserverpkg:apk/chainguard/kubeflow-pipelines-cache-deployerpkg:apk/chainguard/kubeflow-pipelines-cache-deployer-compatpkg:apk/chainguard/kubeflow-pipelines-cache_serverpkg:apk/chainguard/kubeflow-pipelines-frontendpkg:apk/chainguard/kubeflow-pipelines-metadata-envoy-configpkg:apk/chainguard/kubeflow-pipelines-metadata-writerpkg:apk/chainguard/kubeflow-pipelines-metadata-writer-compatpkg:apk/chainguard/kubeflow-pipelines-persistence_agentpkg:apk/chainguard/kubeflow-pipelines-scheduledworkflowpkg:apk/chainguard/kubeflow-pipelines-viewer-crd-controllerpkg:apk/chainguard/kubernetes-dns-node-cache-1.17pkg:apk/chainguard/nodetaintpkg:apk/chainguard/sparkctlpkg:apk/chainguard/spark-operatorpkg:apk/chainguard/spark-operator-oci-entrypointpkg:apk/wolfi/argo-cd-2.7pkg:apk/wolfi/argo-cd-2.7-compatpkg:apk/wolfi/argo-cd-2.7-repo-serverpkg:apk/wolfi/argo-cd-2.8pkg:apk/wolfi/argo-cd-2.8-compatpkg:apk/wolfi/argo-cd-2.8-repo-serverpkg:apk/wolfi/aws-efs-csi-driverpkg:apk/wolfi/calicopkg:apk/wolfi/calico-apiserverpkg:apk/wolfi/calico-app-policypkg:apk/wolfi/calico-cnipkg:apk/wolfi/calico-cni-compatpkg:apk/wolfi/calicoctlpkg:apk/wolfi/calico-felixpkg:apk/wolfi/calico-key-cert-provisionerpkg:apk/wolfi/calico-kube-controllerspkg:apk/wolfi/calico-nodepkg:apk/wolfi/calico-pod2daemonpkg:apk/wolfi/calico-pod2daemon-flexvol-compatpkg:apk/wolfi/calico-typha-clientpkg:apk/wolfi/calico-typhadpkg:apk/wolfi/cluster-autoscaler-1.25pkg:apk/wolfi/cluster-autoscaler-1.25-compatpkg:apk/wolfi/cluster-autoscaler-1.26pkg:apk/wolfi/cluster-autoscaler-1.26-compatpkg:apk/wolfi/kubeflow-pipelinespkg:apk/wolfi/kubeflow-pipelines-apiserverpkg:apk/wolfi/kubeflow-pipelines-cache-deployerpkg:apk/wolfi/kubeflow-pipelines-cache-deployer-compatpkg:apk/wolfi/kubeflow-pipelines-cache_serverpkg:apk/wolfi/kubeflow-pipelines-frontendpkg:apk/wolfi/kubeflow-pipelines-metadata-envoy-configpkg:apk/wolfi/kubeflow-pipelines-metadata-writerpkg:apk/wolfi/kubeflow-pipelines-metadata-writer-compatpkg:apk/wolfi/kubeflow-pipelines-persistence_agentpkg:apk/wolfi/kubeflow-pipelines-scheduledworkflowpkg:apk/wolfi/kubeflow-pipelines-viewer-crd-controllerpkg:apk/wolfi/nodetaintpkg:apk/wolfi/sparkctlpkg:apk/wolfi/spark-operatorpkg:apk/wolfi/spark-operator-oci-entrypointpkg:golang/k8s.io/kubernetespkg:rpm/opensuse/govulncheck-vulndb&distro=openSUSE%20Tumbleweed
< 2.7.14-r8+ 117 more
- (no CPE)range: < 2.7.14-r8
- (no CPE)range: < 2.7.14-r8
- (no CPE)range: < 2.7.14-r8
- (no CPE)range: < 2.8.6-r1
- (no CPE)range: < 2.8.6-r1
- (no CPE)range: < 2.8.6-r1
- (no CPE)range: < 1.18.0-r8
- (no CPE)range: < 1.19.0-r8
- (no CPE)range: < 1.7.0-r6
- (no CPE)range: < 1.7.0-r5
- (no CPE)range: < 1.6.0-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.25.2-r5
- (no CPE)range: < 0
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 0
- (no CPE)range: < 3.25.2-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 0
- (no CPE)range: < 3.25.2-r5
- (no CPE)range: < 0
- (no CPE)range: < 3.25.2-r5
- (no CPE)range: < 0
- (no CPE)range: < 3.25.2-r5
- (no CPE)range: < 0
- (no CPE)range: < 3.25.2-r5
- (no CPE)range: < 0
- (no CPE)range: < 3.25.2-r5
- (no CPE)range: < 0
- (no CPE)range: < 0
- (no CPE)range: < 3.25.2-r5
- (no CPE)range: < 0
- (no CPE)range: < 3.25.2-r5
- (no CPE)range: < 0
- (no CPE)range: < 3.25.2-r5
- (no CPE)range: < 0
- (no CPE)range: < 3.25.2-r5
- (no CPE)range: < 0
- (no CPE)range: < 3.25.2-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 1.25.3-r4
- (no CPE)range: < 1.25.3-r4
- (no CPE)range: < 1.26.4-r4
- (no CPE)range: < 1.26.4-r4
- (no CPE)range: < 1.25.3-r7
- (no CPE)range: < 1.25.3-r7
- (no CPE)range: < 1.28.0-r5
- (no CPE)range: < 1.28.0-r5
- (no CPE)range: < 2.0.5-r5
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 0
- (no CPE)range: < 0
- (no CPE)range: < 0
- (no CPE)range: < 0
- (no CPE)range: < 0
- (no CPE)range: < 2.7.14-r8
- (no CPE)range: < 2.7.14-r8
- (no CPE)range: < 2.7.14-r8
- (no CPE)range: < 2.8.6-r1
- (no CPE)range: < 2.8.6-r1
- (no CPE)range: < 2.8.6-r1
- (no CPE)range: < 1.7.0-r6
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 3.26.3-r5
- (no CPE)range: < 1.25.3-r4
- (no CPE)range: < 1.25.3-r4
- (no CPE)range: < 1.26.4-r4
- (no CPE)range: < 1.26.4-r4
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 2.14.3-r3
- (no CPE)range: < 0
- (no CPE)range: < 0
- (no CPE)range: < 0
- (no CPE)range: < 0
- (no CPE)range: >= 1.28.0, < 1.28.1
- (no CPE)range: < 0.0.20241213T205935-1.1
- Kubernetes/kubeletv5Range: v1.28.0
Patches
5c4e17abb0472Merge pull request #120134 from ritazh/cherry-pick-cve-2023-3955-1.28
3 files changed · +25 −13
pkg/volume/util/util.go+8 −4 modified@@ -709,11 +709,15 @@ func HasMountRefs(mountPath string, mountRefs []string) bool { func WriteVolumeCache(deviceMountPath string, exec utilexec.Interface) error { // If runtime os is windows, execute Write-VolumeCache powershell command on the disk if runtime.GOOS == "windows" { - cmd := fmt.Sprintf("Get-Volume -FilePath %s | Write-Volumecache", deviceMountPath) - output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() - klog.Infof("command (%q) execeuted: %v, output: %q", cmd, err, string(output)) + cmdString := "Get-Volume -FilePath $env:mountpath | Write-Volumecache" + cmd := exec.Command("powershell", "/c", cmdString) + env := append(os.Environ(), fmt.Sprintf("mountpath=%s", deviceMountPath)) + cmd.SetEnv(env) + klog.V(8).Infof("Executing command: %q", cmdString) + output, err := cmd.CombinedOutput() + klog.Infof("command (%q) execeuted: %v, output: %q", cmdString, err, string(output)) if err != nil { - return fmt.Errorf("command (%q) failed: %v, output: %q", cmd, err, string(output)) + return fmt.Errorf("command (%q) failed: %v, output: %q", cmdString, err, string(output)) } } // For linux runtime, it skips because unmount will automatically flush disk data
staging/src/k8s.io/mount-utils/mount_windows.go+16 −8 modified@@ -287,14 +287,20 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target fstype = "NTFS" } - // format disk if it is unformatted(raw) - formatOptionsUnwrapped := "" if len(formatOptions) > 0 { - formatOptionsUnwrapped = " " + strings.Join(formatOptions, " ") + return fmt.Errorf("diskMount: formatOptions are not supported on Windows") } - cmd := fmt.Sprintf("Get-Disk -Number %s | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru"+ - " | New-Partition -UseMaximumSize | Format-Volume -FileSystem %s -Confirm:$false%s", source, fstype, formatOptionsUnwrapped) - if output, err := mounter.Exec.Command("powershell", "/c", cmd).CombinedOutput(); err != nil { + + cmdString := "Get-Disk -Number $env:source | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru" + + " | New-Partition -UseMaximumSize | Format-Volume -FileSystem $env:fstype -Confirm:$false" + cmd := mounter.Exec.Command("powershell", "/c", cmdString) + env := append(os.Environ(), + fmt.Sprintf("source=%s", source), + fmt.Sprintf("fstype=%s", fstype), + ) + cmd.SetEnv(env) + klog.V(8).Infof("Executing command: %q", cmdString) + if output, err := cmd.CombinedOutput(); err != nil { return fmt.Errorf("diskMount: format disk failed, error: %v, output: %q", err, string(output)) } klog.V(4).Infof("diskMount: Disk successfully formatted, disk: %q, fstype: %q", source, fstype) @@ -310,8 +316,10 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target // ListVolumesOnDisk - returns back list of volumes(volumeIDs) in the disk (requested in diskID). func ListVolumesOnDisk(diskID string) (volumeIDs []string, err error) { // If a Disk has multiple volumes, Get-Volume may not return items in the same order. - cmd := fmt.Sprintf("(Get-Disk -DeviceId %s | Get-Partition | Get-Volume | Sort-Object -Property UniqueId).UniqueId", diskID) - output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() + cmd := exec.Command("powershell", "/c", "(Get-Disk -DeviceId $env:diskID | Get-Partition | Get-Volume | Sort-Object -Property UniqueId).UniqueId") + cmd.Env = append(os.Environ(), fmt.Sprintf("diskID=%s", diskID)) + klog.V(8).Infof("Executing command: %q", cmd.String()) + output, err := cmd.CombinedOutput() klog.V(4).Infof("ListVolumesOnDisk id from %s: %s", diskID, string(output)) if err != nil { return []string{}, fmt.Errorf("error list volumes on disk. cmd: %s, output: %s, error: %v", cmd, string(output), err)
staging/src/k8s.io/mount-utils/mount_windows_test.go+1 −1 modified@@ -275,7 +275,7 @@ func TestFormatAndMount(t *testing.T) { Exec: fakeExec, } target := filepath.Join(t.TempDir(), test.target) - err = mounter.FormatAndMount(test.device, target, test.fstype, test.mountOptions) + err := mounter.FormatAndMount(test.device, target, test.fstype, test.mountOptions) if test.expectError { assert.NotNil(t, err, "Expect error during FormatAndMount(%s, %s, %s, %v)", test.device, test.target, test.fstype, test.mountOptions) } else {
b7547e28f898Merge pull request #120137 from ritazh/cherry-pick-cve-2023-3955-1.25
2 files changed · +23 −11
pkg/volume/util/util.go+8 −4 modified@@ -672,11 +672,15 @@ func HasMountRefs(mountPath string, mountRefs []string) bool { func WriteVolumeCache(deviceMountPath string, exec utilexec.Interface) error { // If runtime os is windows, execute Write-VolumeCache powershell command on the disk if runtime.GOOS == "windows" { - cmd := fmt.Sprintf("Get-Volume -FilePath %s | Write-Volumecache", deviceMountPath) - output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() - klog.Infof("command (%q) execeuted: %v, output: %q", cmd, err, string(output)) + cmdString := "Get-Volume -FilePath $env:mountpath | Write-Volumecache" + cmd := exec.Command("powershell", "/c", cmdString) + env := append(os.Environ(), fmt.Sprintf("mountpath=%s", deviceMountPath)) + cmd.SetEnv(env) + klog.Infof("Executing command: %q", cmdString) + output, err := cmd.CombinedOutput() + klog.Infof("command (%q) execeuted: %v, output: %q", cmdString, err, string(output)) if err != nil { - return fmt.Errorf("command (%q) failed: %v, output: %q", cmd, err, string(output)) + return fmt.Errorf("command (%q) failed: %v, output: %q", cmdString, err, string(output)) } } // For linux runtime, it skips because unmount will automatically flush disk data
staging/src/k8s.io/mount-utils/mount_windows.go+15 −7 modified@@ -287,10 +287,16 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target fstype = "NTFS" } - // format disk if it is unformatted(raw) - cmd := fmt.Sprintf("Get-Disk -Number %s | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru"+ - " | New-Partition -UseMaximumSize | Format-Volume -FileSystem %s -Confirm:$false", source, fstype) - if output, err := mounter.Exec.Command("powershell", "/c", cmd).CombinedOutput(); err != nil { + cmdString := "Get-Disk -Number $env:source | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru" + + " | New-Partition -UseMaximumSize | Format-Volume -FileSystem $env:fstype -Confirm:$false" + cmd := mounter.Exec.Command("powershell", "/c", cmdString) + env := append(os.Environ(), + fmt.Sprintf("source=%s", source), + fmt.Sprintf("fstype=%s", fstype), + ) + cmd.SetEnv(env) + klog.V(8).Infof("Executing command: %q", cmdString) + if output, err := cmd.CombinedOutput(); err != nil { return fmt.Errorf("diskMount: format disk failed, error: %v, output: %q", err, string(output)) } klog.V(4).Infof("diskMount: Disk successfully formatted, disk: %q, fstype: %q", source, fstype) @@ -312,9 +318,11 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target // ListVolumesOnDisk - returns back list of volumes(volumeIDs) in the disk (requested in diskID). func listVolumesOnDisk(diskID string) (volumeIDs []string, err error) { - cmd := fmt.Sprintf("(Get-Disk -DeviceId %s | Get-Partition | Get-Volume).UniqueId", diskID) - output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() - klog.V(4).Infof("listVolumesOnDisk id from %s: %s", diskID, string(output)) + cmd := exec.Command("powershell", "/c", "(Get-Disk -DeviceId $env:diskID | Get-Partition | Get-Volume).UniqueId") + cmd.Env = append(os.Environ(), fmt.Sprintf("diskID=%s", diskID)) + klog.V(8).Infof("Executing command: %q", cmd.String()) + output, err := cmd.CombinedOutput() + klog.V(4).Infof("ListVolumesOnDisk id from %s: %s", diskID, string(output)) if err != nil { return []string{}, fmt.Errorf("error list volumes on disk. cmd: %s, output: %s, error: %v", cmd, string(output), err) }
38c97fa67ed3Merge pull request #120135 from ritazh/cherry-pick-cve-2023-3955-1.27
2 files changed · +24 −12
pkg/volume/util/util.go+8 −4 modified@@ -710,11 +710,15 @@ func HasMountRefs(mountPath string, mountRefs []string) bool { func WriteVolumeCache(deviceMountPath string, exec utilexec.Interface) error { // If runtime os is windows, execute Write-VolumeCache powershell command on the disk if runtime.GOOS == "windows" { - cmd := fmt.Sprintf("Get-Volume -FilePath %s | Write-Volumecache", deviceMountPath) - output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() - klog.Infof("command (%q) execeuted: %v, output: %q", cmd, err, string(output)) + cmdString := "Get-Volume -FilePath $env:mountpath | Write-Volumecache" + cmd := exec.Command("powershell", "/c", cmdString) + env := append(os.Environ(), fmt.Sprintf("mountpath=%s", deviceMountPath)) + cmd.SetEnv(env) + klog.V(8).Infof("Executing command: %q", cmdString) + output, err := cmd.CombinedOutput() + klog.Infof("command (%q) execeuted: %v, output: %q", cmdString, err, string(output)) if err != nil { - return fmt.Errorf("command (%q) failed: %v, output: %q", cmd, err, string(output)) + return fmt.Errorf("command (%q) failed: %v, output: %q", cmdString, err, string(output)) } } // For linux runtime, it skips because unmount will automatically flush disk data
staging/src/k8s.io/mount-utils/mount_windows.go+16 −8 modified@@ -287,14 +287,20 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target fstype = "NTFS" } - // format disk if it is unformatted(raw) - formatOptionsUnwrapped := "" if len(formatOptions) > 0 { - formatOptionsUnwrapped = " " + strings.Join(formatOptions, " ") + return fmt.Errorf("diskMount: formatOptions are not supported on Windows") } - cmd := fmt.Sprintf("Get-Disk -Number %s | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru"+ - " | New-Partition -UseMaximumSize | Format-Volume -FileSystem %s -Confirm:$false%s", source, fstype, formatOptionsUnwrapped) - if output, err := mounter.Exec.Command("powershell", "/c", cmd).CombinedOutput(); err != nil { + + cmdString := "Get-Disk -Number $env:source | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru" + + " | New-Partition -UseMaximumSize | Format-Volume -FileSystem $env:fstype -Confirm:$false" + cmd := mounter.Exec.Command("powershell", "/c", cmdString) + env := append(os.Environ(), + fmt.Sprintf("source=%s", source), + fmt.Sprintf("fstype=%s", fstype), + ) + cmd.SetEnv(env) + klog.V(8).Infof("Executing command: %q", cmdString) + if output, err := cmd.CombinedOutput(); err != nil { return fmt.Errorf("diskMount: format disk failed, error: %v, output: %q", err, string(output)) } klog.V(4).Infof("diskMount: Disk successfully formatted, disk: %q, fstype: %q", source, fstype) @@ -316,8 +322,10 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target // ListVolumesOnDisk - returns back list of volumes(volumeIDs) in the disk (requested in diskID). func listVolumesOnDisk(diskID string) (volumeIDs []string, err error) { - cmd := fmt.Sprintf("(Get-Disk -DeviceId %s | Get-Partition | Get-Volume).UniqueId", diskID) - output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() + cmd := exec.Command("powershell", "/c", "(Get-Disk -DeviceId $env:diskID | Get-Partition | Get-Volume).UniqueId") + cmd.Env = append(os.Environ(), fmt.Sprintf("diskID=%s", diskID)) + klog.V(8).Infof("Executing command: %q", cmd.String()) + output, err := cmd.CombinedOutput() klog.V(4).Infof("listVolumesOnDisk id from %s: %s", diskID, string(output)) if err != nil { return []string{}, fmt.Errorf("error list volumes on disk. cmd: %s, output: %s, error: %v", cmd, string(output), err)
50334505cd27Merge pull request #120136 from ritazh/cherry-pick-cve-2023-3955-1.26
2 files changed · +24 −12
pkg/volume/util/util.go+8 −4 modified@@ -672,11 +672,15 @@ func HasMountRefs(mountPath string, mountRefs []string) bool { func WriteVolumeCache(deviceMountPath string, exec utilexec.Interface) error { // If runtime os is windows, execute Write-VolumeCache powershell command on the disk if runtime.GOOS == "windows" { - cmd := fmt.Sprintf("Get-Volume -FilePath %s | Write-Volumecache", deviceMountPath) - output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() - klog.Infof("command (%q) execeuted: %v, output: %q", cmd, err, string(output)) + cmdString := "Get-Volume -FilePath $env:mountpath | Write-Volumecache" + cmd := exec.Command("powershell", "/c", cmdString) + env := append(os.Environ(), fmt.Sprintf("mountpath=%s", deviceMountPath)) + cmd.SetEnv(env) + klog.V(8).Infof("Executing command: %q", cmdString) + output, err := cmd.CombinedOutput() + klog.Infof("command (%q) execeuted: %v, output: %q", cmdString, err, string(output)) if err != nil { - return fmt.Errorf("command (%q) failed: %v, output: %q", cmd, err, string(output)) + return fmt.Errorf("command (%q) failed: %v, output: %q", cmdString, err, string(output)) } } // For linux runtime, it skips because unmount will automatically flush disk data
staging/src/k8s.io/mount-utils/mount_windows.go+16 −8 modified@@ -287,14 +287,20 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target fstype = "NTFS" } - // format disk if it is unformatted(raw) - formatOptionsUnwrapped := "" if len(formatOptions) > 0 { - formatOptionsUnwrapped = " " + strings.Join(formatOptions, " ") + return fmt.Errorf("diskMount: formatOptions are not supported on Windows") } - cmd := fmt.Sprintf("Get-Disk -Number %s | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru"+ - " | New-Partition -UseMaximumSize | Format-Volume -FileSystem %s -Confirm:$false%s", source, fstype, formatOptionsUnwrapped) - if output, err := mounter.Exec.Command("powershell", "/c", cmd).CombinedOutput(); err != nil { + + cmdString := "Get-Disk -Number $env:source | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru" + + " | New-Partition -UseMaximumSize | Format-Volume -FileSystem $env:fstype -Confirm:$false" + cmd := mounter.Exec.Command("powershell", "/c", cmdString) + env := append(os.Environ(), + fmt.Sprintf("source=%s", source), + fmt.Sprintf("fstype=%s", fstype), + ) + cmd.SetEnv(env) + klog.V(8).Infof("Executing command: %q", cmdString) + if output, err := cmd.CombinedOutput(); err != nil { return fmt.Errorf("diskMount: format disk failed, error: %v, output: %q", err, string(output)) } klog.V(4).Infof("diskMount: Disk successfully formatted, disk: %q, fstype: %q", source, fstype) @@ -316,8 +322,10 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target // ListVolumesOnDisk - returns back list of volumes(volumeIDs) in the disk (requested in diskID). func listVolumesOnDisk(diskID string) (volumeIDs []string, err error) { - cmd := fmt.Sprintf("(Get-Disk -DeviceId %s | Get-Partition | Get-Volume).UniqueId", diskID) - output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() + cmd := exec.Command("powershell", "/c", "(Get-Disk -DeviceId $env:diskID | Get-Partition | Get-Volume).UniqueId") + cmd.Env = append(os.Environ(), fmt.Sprintf("diskID=%s", diskID)) + klog.V(8).Infof("Executing command: %q", cmd.String()) + output, err := cmd.CombinedOutput() klog.V(4).Infof("listVolumesOnDisk id from %s: %s", diskID, string(output)) if err != nil { return []string{}, fmt.Errorf("error list volumes on disk. cmd: %s, output: %s, error: %v", cmd, string(output), err)
7da6d72c05dfMerge pull request #120138 from ritazh/cherry-pick-cve-2023-3955-1.24
2 files changed · +22 −10
pkg/volume/util/util.go+8 −4 modified@@ -656,11 +656,15 @@ func HasMountRefs(mountPath string, mountRefs []string) bool { func WriteVolumeCache(deviceMountPath string, exec utilexec.Interface) error { // If runtime os is windows, execute Write-VolumeCache powershell command on the disk if runtime.GOOS == "windows" { - cmd := fmt.Sprintf("Get-Volume -FilePath %s | Write-Volumecache", deviceMountPath) - output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() - klog.Infof("command (%q) execeuted: %v, output: %q", cmd, err, string(output)) + cmdString := "Get-Volume -FilePath $env:mountpath | Write-Volumecache" + cmd := exec.Command("powershell", "/c", cmdString) + env := append(os.Environ(), fmt.Sprintf("mountpath=%s", deviceMountPath)) + cmd.SetEnv(env) + klog.Infof("Executing command: %q", cmdString) + output, err := cmd.CombinedOutput() + klog.Infof("command (%q) execeuted: %v, output: %q", cmdString, err, string(output)) if err != nil { - return fmt.Errorf("command (%q) failed: %v, output: %q", cmd, err, string(output)) + return fmt.Errorf("command (%q) failed: %v, output: %q", cmdString, err, string(output)) } } // For linux runtime, it skips because unmount will automatically flush disk data
staging/src/k8s.io/mount-utils/mount_windows.go+14 −6 modified@@ -278,10 +278,16 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target fstype = "NTFS" } - // format disk if it is unformatted(raw) - cmd := fmt.Sprintf("Get-Disk -Number %s | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru"+ - " | New-Partition -UseMaximumSize | Format-Volume -FileSystem %s -Confirm:$false", source, fstype) - if output, err := mounter.Exec.Command("powershell", "/c", cmd).CombinedOutput(); err != nil { + cmdString := "Get-Disk -Number $env:source | Where partitionstyle -eq 'raw' | Initialize-Disk -PartitionStyle GPT -PassThru" + + " | New-Partition -UseMaximumSize | Format-Volume -FileSystem $env:fstype -Confirm:$false" + cmd := mounter.Exec.Command("powershell", "/c", cmdString) + env := append(os.Environ(), + fmt.Sprintf("source=%s", source), + fmt.Sprintf("fstype=%s", fstype), + ) + cmd.SetEnv(env) + klog.V(8).Infof("Executing command: %q", cmdString) + if output, err := cmd.CombinedOutput(); err != nil { return fmt.Errorf("diskMount: format disk failed, error: %v, output: %q", err, string(output)) } klog.V(4).Infof("diskMount: Disk successfully formatted, disk: %q, fstype: %q", source, fstype) @@ -303,8 +309,10 @@ func (mounter *SafeFormatAndMount) formatAndMountSensitive(source string, target // ListVolumesOnDisk - returns back list of volumes(volumeIDs) in the disk (requested in diskID). func listVolumesOnDisk(diskID string) (volumeIDs []string, err error) { - cmd := fmt.Sprintf("(Get-Disk -DeviceId %s | Get-Partition | Get-Volume).UniqueId", diskID) - output, err := exec.Command("powershell", "/c", cmd).CombinedOutput() + cmd := exec.Command("powershell", "/c", "(Get-Disk -DeviceId $env:diskID | Get-Partition | Get-Volume).UniqueId") + cmd.Env = append(os.Environ(), fmt.Sprintf("diskID=%s", diskID)) + klog.V(8).Infof("Executing command: %q", cmd.String()) + output, err := cmd.CombinedOutput() klog.V(4).Infof("listVolumesOnDisk id from %s: %s", diskID, string(output)) if err != nil { return []string{}, fmt.Errorf("error list volumes on disk. cmd: %s, output: %s, error: %v", cmd, string(output), err)
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
17- github.com/advisories/GHSA-q78c-gwqw-jcmcghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2023-3955ghsaADVISORY
- github.com/kubernetes/kubernetes/commit/38c97fa67ed35f36e730856728c9e3807f63546aghsaWEB
- github.com/kubernetes/kubernetes/commit/50334505cd27cbe7cf71865388f25a00e29b2596ghsaWEB
- github.com/kubernetes/kubernetes/commit/7da6d72c05dffb3b87e62e2bc8c3228ea12ba1b9ghsaWEB
- github.com/kubernetes/kubernetes/commit/b7547e28f898af37aa2f1107a49111f963250fe6ghsaWEB
- github.com/kubernetes/kubernetes/commit/c4e17abb04728e3a3f9bb26e727b0f978df20ec9ghsaWEB
- github.com/kubernetes/kubernetes/issues/119595ghsaissue-trackingWEB
- github.com/kubernetes/kubernetes/pull/120128ghsaWEB
- github.com/kubernetes/kubernetes/pull/120134ghsaWEB
- github.com/kubernetes/kubernetes/pull/120135ghsaWEB
- github.com/kubernetes/kubernetes/pull/120136ghsaWEB
- github.com/kubernetes/kubernetes/pull/120137ghsaWEB
- github.com/kubernetes/kubernetes/pull/120138ghsaWEB
- groups.google.com/g/kubernetes-security-announce/c/JrX4bb7d83Eghsamailing-listWEB
- security.netapp.com/advisory/ntap-20231221-0002ghsaWEB
- security.netapp.com/advisory/ntap-20231221-0002/mitre
News mentions
0No linked articles in our index yet.