1- From 16e3f5f89b13152057ae9a90f95c3128f3164e04 Mon Sep 17 00:00:00 2001
1+ From 8fb76d6ab555577e98e23b7500009537a471feee Mon Sep 17 00:00:00 2001
22From: George Jenkins <gvjenkins@gmail.com>
33Date: Fri, 6 Mar 2026 08:01:01 -0800
44Subject: [PATCH] fix: Chart dot-name path bug
55
66Signed-off-by: George Jenkins <gvjenkins@gmail.com>
7- Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
8- Upstream- reference: https://github.com/helm/helm/commit/8fb76d6ab555577e98e23b7500009537a471feee.patch
7+
8+ Upstream Patch reference: https://github.com/helm/helm/commit/8fb76d6ab555577e98e23b7500009537a471feee.patch
99---
10- pkg/chart/metadata.go | 3 +++
11- pkg/chartutil/expand.go | 18 ++++++++++++++++++
12- 2 files changed, 21 insertions(+)
10+ pkg/chart/metadata.go | 3 +
11+ pkg/chart/metadata_test.go | 10 +++
12+ pkg/chartutil/expand.go | 18 ++++
13+ pkg/chartutil/expand_test.go | 84 +++++++++++++++++++
14+ pkg/chartutil/testdata/dotdotname/Chart.yaml | 4 +
15+ pkg/chartutil/testdata/dotname/Chart.yaml | 4 +
16+ pkg/chartutil/testdata/slashinname/Chart.yaml | 4 +
17+ 7 files changed, 127 insertions(+)
18+ create mode 100644 pkg/chartutil/testdata/dotdotname/Chart.yaml
19+ create mode 100644 pkg/chartutil/testdata/dotname/Chart.yaml
20+ create mode 100644 pkg/chartutil/testdata/slashinname/Chart.yaml
1321
1422diff --git a/pkg/chart/metadata.go b/pkg/chart/metadata.go
1523index a08a97c..0e78fda 100644
@@ -25,6 +33,27 @@ index a08a97c..0e78fda 100644
2533 if md.Name != filepath.Base(md.Name) {
2634 return ValidationErrorf("chart.metadata.name %q is invalid", md.Name)
2735 }
36+ diff --git a/pkg/chart/metadata_test.go b/pkg/chart/metadata_test.go
37+ index 62aea72..67e0b58 100644
38+ --- a/pkg/chart/metadata_test.go
39+ +++ b/pkg/chart/metadata_test.go
40+ @@ -40,6 +40,16 @@ func TestValidate(t *testing.T) {
41+ &Metadata{APIVersion: "v2", Version: "1.0"},
42+ ValidationError("chart.metadata.name is required"),
43+ },
44+ + {
45+ + "chart with dot name",
46+ + &Metadata{Name: ".", APIVersion: "v2", Version: "1.0"},
47+ + ValidationError("chart.metadata.name \".\" is not allowed"),
48+ + },
49+ + {
50+ + "chart with dotdot name",
51+ + &Metadata{Name: "..", APIVersion: "v2", Version: "1.0"},
52+ + ValidationError("chart.metadata.name \"..\" is not allowed"),
53+ + },
54+ {
55+ "chart without name",
56+ &Metadata{Name: "../../test", APIVersion: "v2", Version: "1.0"},
2857diff --git a/pkg/chartutil/expand.go b/pkg/chartutil/expand.go
2958index 7ae1ae6..af1dfa3 100644
3059--- a/pkg/chartutil/expand.go
@@ -67,6 +96,146 @@ index 7ae1ae6..af1dfa3 100644
6796 // Copy all files verbatim. We don't parse these files because parsing can remove
6897 // comments.
6998 for _, file := range files {
99+ diff --git a/pkg/chartutil/expand_test.go b/pkg/chartutil/expand_test.go
100+ index f31a3d2..de9fd12 100644
101+ --- a/pkg/chartutil/expand_test.go
102+ +++ b/pkg/chartutil/expand_test.go
103+ @@ -17,11 +17,73 @@ limitations under the License.
104+ package chartutil
105+
106+ import (
107+ + "archive/tar"
108+ + "bytes"
109+ + "compress/gzip"
110+ + "io/fs"
111+ "os"
112+ "path/filepath"
113+ "testing"
114+ +
115+ + "github.com/stretchr/testify/assert"
116+ + "github.com/stretchr/testify/require"
117+ )
118+
119+ + // makeTestChartArchive builds a gzipped tar archive from the given sourceDir directory, file entries are prefixed with the given chartName
120+ + func makeTestChartArchive(t *testing.T, chartName, sourceDir string) *bytes.Buffer {
121+ + t.Helper()
122+ +
123+ + var result bytes.Buffer
124+ + gw := gzip.NewWriter(&result)
125+ + tw := tar.NewWriter(gw)
126+ +
127+ + dir := os.DirFS(sourceDir)
128+ +
129+ + writeFile := func(relPath string) {
130+ + t.Helper()
131+ + f, err := dir.Open(relPath)
132+ + require.NoError(t, err)
133+ +
134+ + fStat, err := f.Stat()
135+ + require.NoError(t, err)
136+ +
137+ + err = tw.WriteHeader(&tar.Header{
138+ + Name: filepath.Join(chartName, relPath),
139+ + Mode: int64(fStat.Mode()),
140+ + Size: fStat.Size(),
141+ + })
142+ + require.NoError(t, err)
143+ +
144+ + data, err := fs.ReadFile(dir, relPath)
145+ + require.NoError(t, err)
146+ + tw.Write(data)
147+ + }
148+ +
149+ + err := fs.WalkDir(dir, ".", func(path string, d os.DirEntry, walkErr error) error {
150+ + if walkErr != nil {
151+ + return walkErr
152+ + }
153+ +
154+ + if d.IsDir() {
155+ + return nil
156+ + }
157+ +
158+ + writeFile(path)
159+ +
160+ + return nil
161+ + })
162+ + if err != nil {
163+ + t.Fatal(err)
164+ + }
165+ +
166+ + err = tw.Close()
167+ + require.NoError(t, err)
168+ + err = gw.Close()
169+ + require.NoError(t, err)
170+ +
171+ + return &result
172+ + }
173+ +
174+ func TestExpand(t *testing.T) {
175+ dest := t.TempDir()
176+
177+ @@ -75,6 +137,28 @@ func TestExpand(t *testing.T) {
178+ }
179+ }
180+
181+ + func TestExpandError(t *testing.T) {
182+ + tests := map[string]struct {
183+ + chartName string
184+ + chartDir string
185+ + wantErr string
186+ + }{
187+ + "dot name": {"dotname", "testdata/dotname", "not allowed"},
188+ + "dotdot name": {"dotdotname", "testdata/dotdotname", "not allowed"},
189+ + "slash in name": {"slashinname", "testdata/slashinname", "must not contain path separators"},
190+ + }
191+ +
192+ + for name, tt := range tests {
193+ + t.Run(name, func(t *testing.T) {
194+ + archive := makeTestChartArchive(t, tt.chartName, tt.chartDir)
195+ +
196+ + dest := t.TempDir()
197+ + err := Expand(dest, archive)
198+ + assert.ErrorContains(t, err, tt.wantErr)
199+ + })
200+ + }
201+ + }
202+ +
203+ func TestExpandFile(t *testing.T) {
204+ dest := t.TempDir()
205+
206+ diff --git a/pkg/chartutil/testdata/dotdotname/Chart.yaml b/pkg/chartutil/testdata/dotdotname/Chart.yaml
207+ new file mode 100644
208+ index 0000000..9b081f2
209+ --- /dev/null
210+ +++ b/pkg/chartutil/testdata/dotdotname/Chart.yaml
211+ @@ -0,0 +1,4 @@
212+ + apiVersion: v3
213+ + name: ..
214+ + description: A Helm chart for Kubernetes
215+ + version: 0.1.0
216+ \ No newline at end of file
217+ diff --git a/pkg/chartutil/testdata/dotname/Chart.yaml b/pkg/chartutil/testdata/dotname/Chart.yaml
218+ new file mode 100644
219+ index 0000000..597c162
220+ --- /dev/null
221+ +++ b/pkg/chartutil/testdata/dotname/Chart.yaml
222+ @@ -0,0 +1,4 @@
223+ + apiVersion: v3
224+ + name: .
225+ + description: A Helm chart for Kubernetes
226+ + version: 0.1.0
227+ \ No newline at end of file
228+ diff --git a/pkg/chartutil/testdata/slashinname/Chart.yaml b/pkg/chartutil/testdata/slashinname/Chart.yaml
229+ new file mode 100644
230+ index 0000000..0c522a4
231+ --- /dev/null
232+ +++ b/pkg/chartutil/testdata/slashinname/Chart.yaml
233+ @@ -0,0 +1,4 @@
234+ + apiVersion: v3
235+ + name: a/../b
236+ + description: A Helm chart for Kubernetes
237+ + version: 0.1.0
238+ \ No newline at end of file
70239- -
71- 2.45.4
240+ 2.43.0
72241
0 commit comments