mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Test kubectl cp escape
This commit is contained in:
parent
1c5eed4233
commit
a867b399af
@ -30,6 +30,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
"k8s.io/apimachinery/pkg/api/errors"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@ -578,7 +579,6 @@ func TestBadTar(t *testing.T) {
|
|||||||
t.Errorf("Error finding file: %v", err)
|
t.Errorf("Error finding file: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClean(t *testing.T) {
|
func TestClean(t *testing.T) {
|
||||||
@ -768,6 +768,163 @@ func TestValidate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUntar(t *testing.T) {
|
||||||
|
testdir, err := ioutil.TempDir("", "test-untar")
|
||||||
|
require.NoError(t, err)
|
||||||
|
defer os.RemoveAll(testdir)
|
||||||
|
t.Logf("Test base: %s", testdir)
|
||||||
|
|
||||||
|
const (
|
||||||
|
dest = "base"
|
||||||
|
)
|
||||||
|
|
||||||
|
type file struct {
|
||||||
|
path string
|
||||||
|
linkTarget string // For link types
|
||||||
|
expected string // Expect to find the file here (or not, if empty)
|
||||||
|
}
|
||||||
|
files := []file{{
|
||||||
|
// Absolute file within dest
|
||||||
|
path: filepath.Join(testdir, dest, "abs"),
|
||||||
|
expected: filepath.Join(testdir, dest, testdir, dest, "abs"),
|
||||||
|
}, { // Absolute file outside dest
|
||||||
|
path: filepath.Join(testdir, "abs-out"),
|
||||||
|
expected: filepath.Join(testdir, dest, testdir, "abs-out"),
|
||||||
|
}, { // Absolute nested file within dest
|
||||||
|
path: filepath.Join(testdir, dest, "nested/nest-abs"),
|
||||||
|
expected: filepath.Join(testdir, dest, testdir, dest, "nested/nest-abs"),
|
||||||
|
}, { // Absolute nested file outside dest
|
||||||
|
path: filepath.Join(testdir, dest, "nested/../../nest-abs-out"),
|
||||||
|
expected: filepath.Join(testdir, dest, testdir, "nest-abs-out"),
|
||||||
|
}, { // Relative file inside dest
|
||||||
|
path: "relative",
|
||||||
|
expected: filepath.Join(testdir, dest, "relative"),
|
||||||
|
}, { // Relative file outside dest
|
||||||
|
path: "../unrelative",
|
||||||
|
expected: filepath.Join(testdir, dest, "unrelative"),
|
||||||
|
}, { // Nested relative file inside dest
|
||||||
|
path: "nested/nest-rel",
|
||||||
|
expected: filepath.Join(testdir, dest, "nested/nest-rel"),
|
||||||
|
}, { // Nested relative file outside dest
|
||||||
|
path: "nested/../../nest-unrelative",
|
||||||
|
expected: filepath.Join(testdir, dest, "nest-unrelative"),
|
||||||
|
}}
|
||||||
|
|
||||||
|
mkExpectation := func(expected, suffix string) string {
|
||||||
|
if expected == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return expected + suffix
|
||||||
|
}
|
||||||
|
links := []file{}
|
||||||
|
for _, f := range files {
|
||||||
|
links = append(links, file{
|
||||||
|
path: f.path + "-innerlink",
|
||||||
|
linkTarget: "link-target",
|
||||||
|
expected: mkExpectation(f.expected, "-innerlink"),
|
||||||
|
}, file{
|
||||||
|
path: f.path + "-innerlink-abs",
|
||||||
|
linkTarget: filepath.Join(testdir, dest, "link-target"),
|
||||||
|
expected: "",
|
||||||
|
}, file{
|
||||||
|
path: f.path + "-outerlink",
|
||||||
|
linkTarget: filepath.Join(backtick(f.path), "link-target"),
|
||||||
|
expected: "",
|
||||||
|
}, file{
|
||||||
|
path: f.path + "-outerlink-abs",
|
||||||
|
linkTarget: filepath.Join(testdir, "link-target"),
|
||||||
|
expected: "",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
files = append(files, links...)
|
||||||
|
|
||||||
|
// Test back-tick escaping through a symlink.
|
||||||
|
files = append(files,
|
||||||
|
file{
|
||||||
|
path: "nested/again/back-link",
|
||||||
|
linkTarget: "../../nested",
|
||||||
|
expected: filepath.Join(testdir, dest, "nested/again/back-link"),
|
||||||
|
},
|
||||||
|
file{
|
||||||
|
path: "nested/again/back-link/../../../back-link-file",
|
||||||
|
expected: filepath.Join(testdir, dest, "back-link-file"),
|
||||||
|
})
|
||||||
|
|
||||||
|
// Test chaining back-tick symlinks.
|
||||||
|
files = append(files,
|
||||||
|
file{
|
||||||
|
path: "nested/back-link-first",
|
||||||
|
linkTarget: "../",
|
||||||
|
expected: filepath.Join(testdir, dest, "nested/back-link-first"),
|
||||||
|
},
|
||||||
|
file{
|
||||||
|
path: "nested/back-link-first/back-link-second",
|
||||||
|
linkTarget: "../",
|
||||||
|
expected: filepath.Join(testdir, dest, "back-link-second"),
|
||||||
|
},
|
||||||
|
file{
|
||||||
|
path: "nested/back-link-first/back-link-second/back-link-term",
|
||||||
|
})
|
||||||
|
|
||||||
|
buf := &bytes.Buffer{}
|
||||||
|
tw := tar.NewWriter(buf)
|
||||||
|
expectations := map[string]bool{}
|
||||||
|
for _, f := range files {
|
||||||
|
if f.expected != "" {
|
||||||
|
expectations[f.expected] = false
|
||||||
|
}
|
||||||
|
if f.linkTarget == "" {
|
||||||
|
hdr := &tar.Header{
|
||||||
|
Name: f.path,
|
||||||
|
Mode: 0666,
|
||||||
|
Size: int64(len(f.path)),
|
||||||
|
}
|
||||||
|
require.NoError(t, tw.WriteHeader(hdr), f.path)
|
||||||
|
_, err := tw.Write([]byte(f.path))
|
||||||
|
require.NoError(t, err, f.path)
|
||||||
|
} else {
|
||||||
|
hdr := &tar.Header{
|
||||||
|
Name: f.path,
|
||||||
|
Mode: int64(0777 | os.ModeSymlink),
|
||||||
|
Typeflag: tar.TypeSymlink,
|
||||||
|
Linkname: f.linkTarget,
|
||||||
|
}
|
||||||
|
require.NoError(t, tw.WriteHeader(hdr), f.path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tw.Close()
|
||||||
|
|
||||||
|
opts := NewCopyOptions(genericclioptions.NewTestIOStreamsDiscard())
|
||||||
|
|
||||||
|
require.NoError(t, opts.untarAll(buf, filepath.Join(testdir, dest), ""))
|
||||||
|
|
||||||
|
filepath.Walk(testdir, func(path string, info os.FileInfo, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if info.IsDir() {
|
||||||
|
return nil // Ignore directories.
|
||||||
|
}
|
||||||
|
if _, ok := expectations[path]; !ok {
|
||||||
|
t.Errorf("Unexpected file at %s", path)
|
||||||
|
} else {
|
||||||
|
expectations[path] = true
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
for path, found := range expectations {
|
||||||
|
if !found {
|
||||||
|
t.Errorf("Missing expected file %s", path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// backtick returns a path to one directory up from the target
|
||||||
|
func backtick(target string) string {
|
||||||
|
rel, _ := filepath.Rel(filepath.Dir(target), "../")
|
||||||
|
return rel
|
||||||
|
}
|
||||||
|
|
||||||
func createTmpFile(t *testing.T, filepath, data string) {
|
func createTmpFile(t *testing.T, filepath, data string) {
|
||||||
f, err := os.Create(filepath)
|
f, err := os.Create(filepath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user