File helm-mirror-CVE-2025-32386,32387.patch of Package helm-mirror.38328
Index: helm-mirror-0.3.1/vendor/k8s.io/helm/pkg/chartutil/load.go
===================================================================
--- helm-mirror-0.3.1.orig/vendor/k8s.io/helm/pkg/chartutil/load.go
+++ helm-mirror-0.3.1/vendor/k8s.io/helm/pkg/chartutil/load.go
@@ -66,6 +66,15 @@ type BufferedFile struct {
Data []byte
}
+// MaxDecompressedChartSize is the maximum size of a chart archive that will be
+// decompressed. This is the decompressed size of all the files.
+// The default value is 100 MiB.
+var MaxDecompressedChartSize int64 = 100 * 1024 * 1024 // Default 100 MiB
+
+// MaxDecompressedFileSize is the size of the largest file that Helm will attempt to load.
+// The size of the file is the decompressed version of it when it is stored in an archive.
+var MaxDecompressedFileSize int64 = 5 * 1024 * 1024 // Default 5 MiB
+
var drivePathPattern = regexp.MustCompile(`^[a-zA-Z]:/`)
// loadArchiveFiles loads files out of an archive
@@ -78,6 +87,7 @@ func loadArchiveFiles(in io.Reader) ([]*
files := []*BufferedFile{}
tr := tar.NewReader(unzipped)
+ remainingSize := MaxDecompressedChartSize
for {
b := bytes.NewBuffer(nil)
hd, err := tr.Next()
@@ -137,10 +147,30 @@ func loadArchiveFiles(in io.Reader) ([]*
return nil, errors.New("chart yaml not in base directory")
}
- if _, err := io.Copy(b, tr); err != nil {
+ if hd.Size > remainingSize {
+ return nil, fmt.Errorf("decompressed chart is larger than the maximum size %d", MaxDecompressedChartSize)
+ }
+
+ if hd.Size > MaxDecompressedFileSize {
+ return nil, fmt.Errorf("decompressed chart file %q is larger than the maximum file size %d", hd.Name, MaxDecompressedFileSize)
+ }
+
+ limitedReader := io.LimitReader(tr, remainingSize)
+
+ bytesWritten, err := io.Copy(b, limitedReader)
+ if err != nil {
return files, err
}
+ remainingSize -= bytesWritten
+ // When the bytesWritten are less than the file size it means the limit reader ended
+ // copying early. Here we report that error. This is important if the last file extracted
+ // is the one that goes over the limit. It assumes the Size stored in the tar header
+ // is correct, something many applications do.
+ if bytesWritten < hd.Size || remainingSize <= 0 {
+ return nil, fmt.Errorf("decompressed chart is larger than the maximum size %d", MaxDecompressedChartSize)
+ }
+
files = append(files, &BufferedFile{Name: n, Data: b.Bytes()})
b.Reset()
}
@@ -362,6 +392,10 @@ func LoadDir(dir string) (*chart.Chart,
return fmt.Errorf("cannot load irregular file %s as it has file mode type bits set", name)
}
+ if fi.Size() > MaxDecompressedFileSize {
+ return fmt.Errorf("chart file %q is larger than the maximum file size %d", fi.Name(), MaxDecompressedFileSize)
+ }
+
data, err := ioutil.ReadFile(name)
if err != nil {
return fmt.Errorf("error reading %s: %s", n, err)