Skip to content

Commit 730bc96

Browse files
authored
Merge pull request kubernetes#77874 from yuchengwu/fix-CVE-2019-11244
fix CVE-2019-11244: `kubectl --http-cache=<world-accessible dir>` cre…
2 parents d823fa2 + f228ae3 commit 730bc96

File tree

4 files changed

+84
-2
lines changed

4 files changed

+84
-2
lines changed

staging/src/k8s.io/client-go/discovery/cached/disk/cached_discovery.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ func (d *CachedDiscoveryClient) getCachedFile(filename string) ([]byte, error) {
172172
}
173173

174174
func (d *CachedDiscoveryClient) writeCachedFile(filename string, obj runtime.Object) error {
175-
if err := os.MkdirAll(filepath.Dir(filename), 0755); err != nil {
175+
if err := os.MkdirAll(filepath.Dir(filename), 0750); err != nil {
176176
return err
177177
}
178178

@@ -191,7 +191,7 @@ func (d *CachedDiscoveryClient) writeCachedFile(filename string, obj runtime.Obj
191191
return err
192192
}
193193

194-
err = os.Chmod(f.Name(), 0755)
194+
err = os.Chmod(f.Name(), 0660)
195195
if err != nil {
196196
return err
197197
}

staging/src/k8s.io/client-go/discovery/cached/disk/cached_discovery_test.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package disk
1919
import (
2020
"io/ioutil"
2121
"os"
22+
"path/filepath"
2223
"testing"
2324
"time"
2425

@@ -96,6 +97,32 @@ func TestNewCachedDiscoveryClient_TTL(t *testing.T) {
9697
assert.Equal(c.groupCalls, 2)
9798
}
9899

100+
func TestNewCachedDiscoveryClient_PathPerm(t *testing.T) {
101+
assert := assert.New(t)
102+
103+
d, err := ioutil.TempDir("", "")
104+
assert.NoError(err)
105+
os.RemoveAll(d)
106+
defer os.RemoveAll(d)
107+
108+
c := fakeDiscoveryClient{}
109+
cdc := newCachedDiscoveryClient(&c, d, 1*time.Nanosecond)
110+
cdc.ServerGroups()
111+
112+
err = filepath.Walk(d, func(path string, info os.FileInfo, err error) error {
113+
if err != nil {
114+
return err
115+
}
116+
if info.IsDir() {
117+
assert.Equal(os.FileMode(0750), info.Mode().Perm())
118+
} else {
119+
assert.Equal(os.FileMode(0660), info.Mode().Perm())
120+
}
121+
return nil
122+
})
123+
assert.NoError(err)
124+
}
125+
99126
type fakeDiscoveryClient struct {
100127
groupCalls int
101128
resourceCalls int

staging/src/k8s.io/client-go/discovery/cached/disk/round_tripper.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package disk
1818

1919
import (
2020
"net/http"
21+
"os"
2122
"path/filepath"
2223

2324
"github.com/gregjones/httpcache"
@@ -35,6 +36,8 @@ type cacheRoundTripper struct {
3536
// corresponding requests.
3637
func newCacheRoundTripper(cacheDir string, rt http.RoundTripper) http.RoundTripper {
3738
d := diskv.New(diskv.Options{
39+
PathPerm: os.FileMode(0750),
40+
FilePerm: os.FileMode(0660),
3841
BasePath: cacheDir,
3942
TempDir: filepath.Join(cacheDir, ".diskv-temp"),
4043
})

staging/src/k8s.io/client-go/discovery/cached/disk/round_tripper_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ import (
2222
"net/http"
2323
"net/url"
2424
"os"
25+
"path/filepath"
2526
"testing"
27+
28+
"github.com/stretchr/testify/assert"
2629
)
2730

2831
// copied from k8s.io/client-go/transport/round_trippers_test.go
@@ -93,3 +96,52 @@ func TestCacheRoundTripper(t *testing.T) {
9396
t.Errorf("Invalid content read from cache %q", string(content))
9497
}
9598
}
99+
100+
func TestCacheRoundTripperPathPerm(t *testing.T) {
101+
assert := assert.New(t)
102+
103+
rt := &testRoundTripper{}
104+
cacheDir, err := ioutil.TempDir("", "cache-rt")
105+
os.RemoveAll(cacheDir)
106+
defer os.RemoveAll(cacheDir)
107+
108+
if err != nil {
109+
t.Fatal(err)
110+
}
111+
cache := newCacheRoundTripper(cacheDir, rt)
112+
113+
// First call, caches the response
114+
req := &http.Request{
115+
Method: http.MethodGet,
116+
URL: &url.URL{Host: "localhost"},
117+
}
118+
rt.Response = &http.Response{
119+
Header: http.Header{"ETag": []string{`"123456"`}},
120+
Body: ioutil.NopCloser(bytes.NewReader([]byte("Content"))),
121+
StatusCode: http.StatusOK,
122+
}
123+
resp, err := cache.RoundTrip(req)
124+
if err != nil {
125+
t.Fatal(err)
126+
}
127+
content, err := ioutil.ReadAll(resp.Body)
128+
if err != nil {
129+
t.Fatal(err)
130+
}
131+
if string(content) != "Content" {
132+
t.Errorf(`Expected Body to be "Content", got %q`, string(content))
133+
}
134+
135+
err = filepath.Walk(cacheDir, func(path string, info os.FileInfo, err error) error {
136+
if err != nil {
137+
return err
138+
}
139+
if info.IsDir() {
140+
assert.Equal(os.FileMode(0750), info.Mode().Perm())
141+
} else {
142+
assert.Equal(os.FileMode(0660), info.Mode().Perm())
143+
}
144+
return nil
145+
})
146+
assert.NoError(err)
147+
}

0 commit comments

Comments
 (0)