@@ -18,15 +18,14 @@ package util
18
18
19
19
import (
20
20
"archive/tar"
21
+ "github.com/sirupsen/logrus"
21
22
"io"
22
23
"os"
23
24
"path/filepath"
24
25
"strings"
25
-
26
- "github.com/sirupsen/logrus"
27
26
)
28
27
29
- func unpackTar (tr * tar.Reader , path string ) error {
28
+ func unpackTar (tr * tar.Reader , path string , whitelist [] string ) error {
30
29
for {
31
30
header , err := tr .Next ()
32
31
if err == io .EOF {
@@ -37,7 +36,6 @@ func unpackTar(tr *tar.Reader, path string) error {
37
36
logrus .Error ("Error getting next tar header" )
38
37
return err
39
38
}
40
-
41
39
if strings .Contains (header .Name , ".wh." ) {
42
40
rmPath := filepath .Join (path , header .Name )
43
41
// Remove the .wh file if it was extracted.
@@ -54,8 +52,11 @@ func unpackTar(tr *tar.Reader, path string) error {
54
52
}
55
53
continue
56
54
}
57
-
58
55
target := filepath .Join (path , header .Name )
56
+ // Make sure the target isn't part of the whitelist
57
+ if checkWhitelist (target , whitelist ) {
58
+ continue
59
+ }
59
60
mode := header .FileInfo ().Mode ()
60
61
switch header .Typeflag {
61
62
@@ -65,7 +66,7 @@ func unpackTar(tr *tar.Reader, path string) error {
65
66
if err := os .MkdirAll (target , mode ); err != nil {
66
67
return err
67
68
}
68
- } else {
69
+ // In some cases, MkdirAll doesn't change the permissions, so run Chmod
69
70
if err := os .Chmod (target , mode ); err != nil {
70
71
return err
71
72
}
@@ -81,7 +82,6 @@ func unpackTar(tr *tar.Reader, path string) error {
81
82
return err
82
83
}
83
84
}
84
-
85
85
// It's possible we end up creating files that can't be overwritten based on their permissions.
86
86
// Explicitly delete an existing file before continuing.
87
87
if _ , err := os .Stat (target ); ! os .IsNotExist (err ) {
@@ -106,21 +106,43 @@ func unpackTar(tr *tar.Reader, path string) error {
106
106
return err
107
107
}
108
108
currFile .Close ()
109
- }
109
+ case tar .TypeSymlink :
110
+ // It's possible we end up creating files that can't be overwritten based on their permissions.
111
+ // Explicitly delete an existing file before continuing.
112
+ if _ , err := os .Stat (target ); ! os .IsNotExist (err ) {
113
+ logrus .Debugf ("Removing %s to create symlink." , target )
114
+ if err := os .RemoveAll (target ); err != nil {
115
+ logrus .Debugf ("Unable to remove %s: %s" , target , err )
116
+ }
117
+ }
110
118
119
+ if err = os .Symlink (header .Linkname , target ); err != nil {
120
+ logrus .Errorf ("Failed to create symlink between %s and %s: %s" , header .Linkname , target , err )
121
+ }
122
+ }
111
123
}
112
124
return nil
113
125
}
114
126
127
+ func checkWhitelist (target string , whitelist []string ) bool {
128
+ for _ , w := range whitelist {
129
+ if HasFilepathPrefix (target , w ) {
130
+ logrus .Debugf ("Not extracting %s, as it has prefix %s which is whitelisted" , target , w )
131
+ return true
132
+ }
133
+ }
134
+ return false
135
+ }
136
+
115
137
// UnTar takes in a path to a tar file and writes the untarred version to the provided target.
116
138
// Only untars one level, does not untar nested tars.
117
- func UnTar (r io.Reader , target string ) error {
139
+ func UnTar (r io.Reader , target string , whitelist [] string ) error {
118
140
if _ , ok := os .Stat (target ); ok != nil {
119
141
os .MkdirAll (target , 0775 )
120
142
}
121
143
122
144
tr := tar .NewReader (r )
123
- if err := unpackTar (tr , target ); err != nil {
145
+ if err := unpackTar (tr , target , whitelist ); err != nil {
124
146
return err
125
147
}
126
148
return nil
0 commit comments