Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
47063891
Unverified
Commit
47063891
authored
Mar 06, 2019
by
Kubernetes Prow Robot
Committed by
GitHub
Mar 06, 2019
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #75037 from soltysh/cp_bug
Fix panic in kubectl cp command
parents
7fbfe701
ee7edb77
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
97 additions
and
19 deletions
+97
-19
cp.go
pkg/kubectl/cmd/cp/cp.go
+18
-4
cp_test.go
pkg/kubectl/cmd/cp/cp_test.go
+79
-15
No files found.
pkg/kubectl/cmd/cp/cp.go
View file @
47063891
...
@@ -307,7 +307,7 @@ func (o *CopyOptions) copyFromPod(src, dest fileSpec) error {
...
@@ -307,7 +307,7 @@ func (o *CopyOptions) copyFromPod(src, dest fileSpec) error {
// remove extraneous path shortcuts - these could occur if a path contained extra "../"
// remove extraneous path shortcuts - these could occur if a path contained extra "../"
// and attempted to navigate beyond "/" in a remote filesystem
// and attempted to navigate beyond "/" in a remote filesystem
prefix
=
stripPathShortcuts
(
prefix
)
prefix
=
stripPathShortcuts
(
prefix
)
return
untarAll
(
reader
,
dest
.
File
,
prefix
)
return
o
.
untarAll
(
reader
,
dest
.
File
,
prefix
)
}
}
// stripPathShortcuts removes any leading or trailing "../" from a given path
// stripPathShortcuts removes any leading or trailing "../" from a given path
...
@@ -418,7 +418,7 @@ func clean(fileName string) string {
...
@@ -418,7 +418,7 @@ func clean(fileName string) string {
return
path
.
Clean
(
string
(
os
.
PathSeparator
)
+
fileName
)
return
path
.
Clean
(
string
(
os
.
PathSeparator
)
+
fileName
)
}
}
func
untarAll
(
reader
io
.
Reader
,
destFile
,
prefix
string
)
error
{
func
(
o
*
CopyOptions
)
untarAll
(
reader
io
.
Reader
,
destFile
,
prefix
string
)
error
{
entrySeq
:=
-
1
entrySeq
:=
-
1
// TODO: use compression here?
// TODO: use compression here?
...
@@ -433,6 +433,12 @@ func untarAll(reader io.Reader, destFile, prefix string) error {
...
@@ -433,6 +433,12 @@ func untarAll(reader io.Reader, destFile, prefix string) error {
}
}
entrySeq
++
entrySeq
++
mode
:=
header
.
FileInfo
()
.
Mode
()
mode
:=
header
.
FileInfo
()
.
Mode
()
// all the files will start with the prefix, which is the directory where
// they were located on the pod, we need to strip down that prefix, but
// if the prefix is missing it means the tar was tempered with
if
!
strings
.
HasPrefix
(
header
.
Name
,
prefix
)
{
return
fmt
.
Errorf
(
"tar contents corrupted"
)
}
outFileName
:=
path
.
Join
(
destFile
,
clean
(
header
.
Name
[
len
(
prefix
)
:
]))
outFileName
:=
path
.
Join
(
destFile
,
clean
(
header
.
Name
[
len
(
prefix
)
:
]))
baseName
:=
path
.
Dir
(
outFileName
)
baseName
:=
path
.
Dir
(
outFileName
)
if
err
:=
os
.
MkdirAll
(
baseName
,
0755
);
err
!=
nil
{
if
err
:=
os
.
MkdirAll
(
baseName
,
0755
);
err
!=
nil
{
...
@@ -457,8 +463,16 @@ func untarAll(reader io.Reader, destFile, prefix string) error {
...
@@ -457,8 +463,16 @@ func untarAll(reader io.Reader, destFile, prefix string) error {
}
}
if
mode
&
os
.
ModeSymlink
!=
0
{
if
mode
&
os
.
ModeSymlink
!=
0
{
err
:=
os
.
Symlink
(
header
.
Linkname
,
outFileName
)
linkname
:=
header
.
Linkname
if
err
!=
nil
{
// error is returned if linkname can't be made relative to destFile,
// but relative can end up being ../dir that's why we also need to
// verify if relative path is the same after Clean-ing
relative
,
err
:=
filepath
.
Rel
(
destFile
,
linkname
)
if
path
.
IsAbs
(
linkname
)
&&
(
err
!=
nil
||
relative
!=
stripPathShortcuts
(
relative
))
{
fmt
.
Fprintf
(
o
.
IOStreams
.
ErrOut
,
"warning: link %q is pointing to %q which is outside target destination, skipping
\n
"
,
outFileName
,
header
.
Linkname
)
continue
}
if
err
:=
os
.
Symlink
(
linkname
,
outFileName
);
err
!=
nil
{
return
err
return
err
}
}
}
else
{
}
else
{
...
...
pkg/kubectl/cmd/cp/cp_test.go
View file @
47063891
...
@@ -191,27 +191,33 @@ func TestStripPathShortcuts(t *testing.T) {
...
@@ -191,27 +191,33 @@ func TestStripPathShortcuts(t *testing.T) {
}
}
}
}
func
TestTarUntar
(
t
*
testing
.
T
)
{
func
checkErr
(
t
*
testing
.
T
,
err
error
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"input"
)
if
err
!=
nil
{
dir2
,
err2
:=
ioutil
.
TempDir
(
""
,
"output"
)
t
.
Errorf
(
"unexpected error: %v"
,
err
)
if
err
!=
nil
||
err2
!=
nil
{
t
.
Errorf
(
"unexpected error: %v | %v"
,
err
,
err2
)
t
.
FailNow
()
t
.
FailNow
()
}
}
}
func
TestTarUntar
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"input"
)
checkErr
(
t
,
err
)
dir2
,
err
:=
ioutil
.
TempDir
(
""
,
"output"
)
checkErr
(
t
,
err
)
dir3
,
err
:=
ioutil
.
TempDir
(
""
,
"dir"
)
checkErr
(
t
,
err
)
dir
=
dir
+
"/"
dir
=
dir
+
"/"
defer
func
()
{
defer
func
()
{
if
err
:=
os
.
RemoveAll
(
dir
);
err
!=
nil
{
os
.
RemoveAll
(
dir
)
t
.
Errorf
(
"Unexpected error cleaning up: %v"
,
err
)
os
.
RemoveAll
(
dir2
)
}
os
.
RemoveAll
(
dir3
)
if
err
:=
os
.
RemoveAll
(
dir2
);
err
!=
nil
{
t
.
Errorf
(
"Unexpected error cleaning up: %v"
,
err
)
}
}()
}()
files
:=
[]
struct
{
files
:=
[]
struct
{
name
string
name
string
nameList
[]
string
nameList
[]
string
data
string
data
string
omitted
bool
fileType
FileType
fileType
FileType
}{
}{
{
{
...
@@ -236,7 +242,24 @@ func TestTarUntar(t *testing.T) {
...
@@ -236,7 +242,24 @@ func TestTarUntar(t *testing.T) {
},
},
{
{
name
:
"gakki"
,
name
:
"gakki"
,
data
:
"tmp/gakki"
,
fileType
:
SymLink
,
},
{
name
:
"relative_to_dest"
,
data
:
path
.
Join
(
dir2
,
"foo"
),
fileType
:
SymLink
,
},
{
name
:
"tricky_relative"
,
data
:
path
.
Join
(
dir3
,
"xyz"
),
omitted
:
true
,
fileType
:
SymLink
,
},
{
name
:
"absolute_path"
,
data
:
"/tmp/gakki"
,
data
:
"/tmp/gakki"
,
omitted
:
true
,
fileType
:
SymLink
,
fileType
:
SymLink
,
},
},
{
{
...
@@ -268,13 +291,15 @@ func TestTarUntar(t *testing.T) {
...
@@ -268,13 +291,15 @@ func TestTarUntar(t *testing.T) {
}
}
}
}
opts
:=
NewCopyOptions
(
genericclioptions
.
NewTestIOStreamsDiscard
())
writer
:=
&
bytes
.
Buffer
{}
writer
:=
&
bytes
.
Buffer
{}
if
err
:=
makeTar
(
dir
,
dir
,
writer
);
err
!=
nil
{
if
err
:=
makeTar
(
dir
,
dir
,
writer
);
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
}
reader
:=
bytes
.
NewBuffer
(
writer
.
Bytes
())
reader
:=
bytes
.
NewBuffer
(
writer
.
Bytes
())
if
err
:=
untarAll
(
reader
,
dir2
,
""
);
err
!=
nil
{
if
err
:=
opts
.
untarAll
(
reader
,
dir2
,
""
);
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
}
...
@@ -286,7 +311,12 @@ func TestTarUntar(t *testing.T) {
...
@@ -286,7 +311,12 @@ func TestTarUntar(t *testing.T) {
cmpFileData
(
t
,
filePath
,
file
.
data
)
cmpFileData
(
t
,
filePath
,
file
.
data
)
}
else
if
file
.
fileType
==
SymLink
{
}
else
if
file
.
fileType
==
SymLink
{
dest
,
err
:=
os
.
Readlink
(
filePath
)
dest
,
err
:=
os
.
Readlink
(
filePath
)
if
file
.
omitted
{
if
err
!=
nil
&&
strings
.
Contains
(
err
.
Error
(),
"no such file or directory"
)
{
continue
}
t
.
Fatalf
(
"expected to omit symlink for %s"
,
filePath
)
}
if
err
!=
nil
{
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
}
...
@@ -304,6 +334,38 @@ func TestTarUntar(t *testing.T) {
...
@@ -304,6 +334,38 @@ func TestTarUntar(t *testing.T) {
}
}
}
}
func
TestTarUntarWrongPrefix
(
t
*
testing
.
T
)
{
dir
,
err
:=
ioutil
.
TempDir
(
""
,
"input"
)
checkErr
(
t
,
err
)
dir2
,
err
:=
ioutil
.
TempDir
(
""
,
"output"
)
checkErr
(
t
,
err
)
dir
=
dir
+
"/"
defer
func
()
{
os
.
RemoveAll
(
dir
)
os
.
RemoveAll
(
dir2
)
}()
filepath
:=
path
.
Join
(
dir
,
"foo"
)
if
err
:=
os
.
MkdirAll
(
path
.
Dir
(
filepath
),
0755
);
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
createTmpFile
(
t
,
filepath
,
"sample data"
)
opts
:=
NewCopyOptions
(
genericclioptions
.
NewTestIOStreamsDiscard
())
writer
:=
&
bytes
.
Buffer
{}
if
err
:=
makeTar
(
dir
,
dir
,
writer
);
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
reader
:=
bytes
.
NewBuffer
(
writer
.
Bytes
())
err
=
opts
.
untarAll
(
reader
,
dir2
,
"verylongprefix-showing-the-tar-was-tempered-with"
)
if
err
==
nil
||
!
strings
.
Contains
(
err
.
Error
(),
"tar contents corrupted"
)
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
}
// TestCopyToLocalFileOrDir tests untarAll in two cases :
// TestCopyToLocalFileOrDir tests untarAll in two cases :
// 1: copy pod file to local file
// 1: copy pod file to local file
// 2: copy pod file into local directory
// 2: copy pod file into local directory
...
@@ -376,7 +438,8 @@ func TestCopyToLocalFileOrDir(t *testing.T) {
...
@@ -376,7 +438,8 @@ func TestCopyToLocalFileOrDir(t *testing.T) {
}
}
defer
srcTarFile
.
Close
()
defer
srcTarFile
.
Close
()
if
err
:=
untarAll
(
srcTarFile
,
destPath
,
getPrefix
(
srcFilePath
));
err
!=
nil
{
opts
:=
NewCopyOptions
(
genericclioptions
.
NewTestIOStreamsDiscard
())
if
err
:=
opts
.
untarAll
(
srcTarFile
,
destPath
,
getPrefix
(
srcFilePath
));
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v"
,
err
)
t
.
Errorf
(
"unexpected error: %v"
,
err
)
t
.
FailNow
()
t
.
FailNow
()
}
}
...
@@ -503,7 +566,8 @@ func TestBadTar(t *testing.T) {
...
@@ -503,7 +566,8 @@ func TestBadTar(t *testing.T) {
t
.
FailNow
()
t
.
FailNow
()
}
}
if
err
:=
untarAll
(
&
buf
,
dir
,
"/prefix"
);
err
!=
nil
{
opts
:=
NewCopyOptions
(
genericclioptions
.
NewTestIOStreamsDiscard
())
if
err
:=
opts
.
untarAll
(
&
buf
,
dir
,
"/prefix"
);
err
!=
nil
{
t
.
Errorf
(
"unexpected error: %v "
,
err
)
t
.
Errorf
(
"unexpected error: %v "
,
err
)
t
.
FailNow
()
t
.
FailNow
()
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment