Skip to content
This repository was archived by the owner on Mar 27, 2024. It is now read-only.

Commit 6267be2

Browse files
author
priyawadhwa
authored
Merge pull request #191 from priyawadhwa/tar
modifications to extract filesystem for kbuild
2 parents 985123b + 753dc64 commit 6267be2

File tree

9 files changed

+98
-27
lines changed

9 files changed

+98
-27
lines changed

pkg/util/cloud_prepper.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func (p CloudPrepper) GetFileSystem() (string, error) {
5959
return "", err
6060
}
6161

62-
return path, getFileSystemFromReference(ref, p.ImageSource, path)
62+
return path, GetFileSystemFromReference(ref, p.ImageSource, path, nil)
6363
}
6464

6565
func (p CloudPrepper) GetConfig() (ConfigSchema, error) {

pkg/util/daemon_prepper.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func (p DaemonPrepper) GetFileSystem() (string, error) {
6464
if err != nil {
6565
return "", err
6666
}
67-
return path, getFileSystemFromReference(ref, src, path)
67+
return path, GetFileSystemFromReference(ref, src, path, nil)
6868
}
6969

7070
func (p DaemonPrepper) GetConfig() (ConfigSchema, error) {

pkg/util/docker_utils.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ func unpackDockerSave(tarPath string, target string) error {
115115
}
116116

117117
for _, layer := range layers {
118-
if err = UnTar(bytes.NewReader(layerMap[layer]), target); err != nil {
118+
if err = UnTar(bytes.NewReader(layerMap[layer]), target, nil); err != nil {
119119
return fmt.Errorf("Could not unpack layer %s: %s", layer, err)
120120
}
121121
}

pkg/util/fs_utils.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,22 @@ func CheckSameFile(f1name, f2name string) (bool, error) {
160160
}
161161
return true, nil
162162
}
163+
164+
// HasFilepathPrefix checks if the given file path begins with prefix
165+
func HasFilepathPrefix(path, prefix string) bool {
166+
path = filepath.Clean(path)
167+
prefix = filepath.Clean(prefix)
168+
pathArray := strings.Split(path, "/")
169+
prefixArray := strings.Split(prefix, "/")
170+
171+
if len(pathArray) < len(prefixArray) {
172+
return false
173+
}
174+
for index := range prefixArray {
175+
if prefixArray[index] == pathArray[index] {
176+
continue
177+
}
178+
return false
179+
}
180+
return true
181+
}

pkg/util/image_prep_utils.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ func getImageFromTar(tarPath string) (string, error) {
127127
return tempPath, unpackDockerSave(tarPath, tempPath)
128128
}
129129

130-
func getFileSystemFromReference(ref types.ImageReference, imgSrc types.ImageSource, path string) error {
130+
func GetFileSystemFromReference(ref types.ImageReference, imgSrc types.ImageSource, path string, whitelist []string) error {
131131
img, err := ref.NewImage(nil)
132132
if err != nil {
133133
return err
@@ -151,7 +151,7 @@ func getFileSystemFromReference(ref types.ImageReference, imgSrc types.ImageSour
151151
}
152152
}
153153
tr := tar.NewReader(reader)
154-
if err := unpackTar(tr, path); err != nil {
154+
if err := unpackTar(tr, path, whitelist); err != nil {
155155
return err
156156
}
157157
}

pkg/util/tar_prepper.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,12 @@ package util
1919
import (
2020
"encoding/json"
2121
"errors"
22-
"io/ioutil"
23-
"os"
24-
"path/filepath"
25-
2622
"github.com/containers/image/docker/tarfile"
2723
"github.com/docker/docker/client"
2824
"github.com/sirupsen/logrus"
25+
"io/ioutil"
26+
"os"
27+
"path/filepath"
2928
)
3029

3130
type TarPrepper struct {
@@ -62,7 +61,7 @@ func (p TarPrepper) GetConfig() (ConfigSchema, error) {
6261
return ConfigSchema{}, err
6362
}
6463
defer f.Close()
65-
if err := UnTar(f, tempDir); err != nil {
64+
if err := UnTar(f, tempDir, nil); err != nil {
6665
return ConfigSchema{}, err
6766
}
6867

pkg/util/tar_utils.go

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@ package util
1818

1919
import (
2020
"archive/tar"
21+
"github.com/sirupsen/logrus"
2122
"io"
2223
"os"
2324
"path/filepath"
2425
"strings"
25-
26-
"github.com/sirupsen/logrus"
2726
)
2827

29-
func unpackTar(tr *tar.Reader, path string) error {
28+
func unpackTar(tr *tar.Reader, path string, whitelist []string) error {
3029
for {
3130
header, err := tr.Next()
3231
if err == io.EOF {
@@ -37,7 +36,6 @@ func unpackTar(tr *tar.Reader, path string) error {
3736
logrus.Error("Error getting next tar header")
3837
return err
3938
}
40-
4139
if strings.Contains(header.Name, ".wh.") {
4240
rmPath := filepath.Join(path, header.Name)
4341
// Remove the .wh file if it was extracted.
@@ -54,8 +52,11 @@ func unpackTar(tr *tar.Reader, path string) error {
5452
}
5553
continue
5654
}
57-
5855
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+
}
5960
mode := header.FileInfo().Mode()
6061
switch header.Typeflag {
6162

@@ -65,7 +66,7 @@ func unpackTar(tr *tar.Reader, path string) error {
6566
if err := os.MkdirAll(target, mode); err != nil {
6667
return err
6768
}
68-
} else {
69+
// In some cases, MkdirAll doesn't change the permissions, so run Chmod
6970
if err := os.Chmod(target, mode); err != nil {
7071
return err
7172
}
@@ -81,7 +82,6 @@ func unpackTar(tr *tar.Reader, path string) error {
8182
return err
8283
}
8384
}
84-
8585
// It's possible we end up creating files that can't be overwritten based on their permissions.
8686
// Explicitly delete an existing file before continuing.
8787
if _, err := os.Stat(target); !os.IsNotExist(err) {
@@ -106,21 +106,43 @@ func unpackTar(tr *tar.Reader, path string) error {
106106
return err
107107
}
108108
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+
}
110118

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+
}
111123
}
112124
return nil
113125
}
114126

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+
115137
// UnTar takes in a path to a tar file and writes the untarred version to the provided target.
116138
// 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 {
118140
if _, ok := os.Stat(target); ok != nil {
119141
os.MkdirAll(target, 0775)
120142
}
121143

122144
tr := tar.NewReader(r)
123-
if err := unpackTar(tr, target); err != nil {
145+
if err := unpackTar(tr, target, whitelist); err != nil {
124146
return err
125147
}
126148
return nil

util/fs_utils_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,26 @@ func TestCheckSameFile(t *testing.T) {
156156
}
157157
}
158158
}
159+
160+
func TestHasFilepathPrefix(t *testing.T) {
161+
type test struct {
162+
prefix string
163+
path string
164+
expectedBool bool
165+
}
166+
167+
var tests = []test{
168+
{"/foo", "/foo/bar", true},
169+
{"/foo/", "/foo/bar", true},
170+
{"/foo/bar", "/foo", false},
171+
{"/foo/bar", "/foo/", false},
172+
{"/foo", "/foobar", false},
173+
}
174+
175+
for _, test := range tests {
176+
hasPrefix := pkgutil.HasFilepathPrefix(test.path, test.prefix)
177+
if hasPrefix != test.expectedBool {
178+
t.Errorf("Got unexpected response: %v for prefix: %s and path: %s", hasPrefix, test.prefix, test.path)
179+
}
180+
}
181+
}

util/tar_utils_test.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@ import (
3030

3131
func TestUnTar(t *testing.T) {
3232
testCases := []struct {
33-
descrip string
34-
tarPath string
35-
target string
36-
expected string
37-
starter string
38-
err bool
33+
descrip string
34+
tarPath string
35+
target string
36+
expected string
37+
starter string
38+
whitelist []string
39+
err bool
3940
}{
4041
{
4142
descrip: "Tar with files",
@@ -76,6 +77,13 @@ func TestUnTar(t *testing.T) {
7677
expected: "testTars/la-croix-dir-update-actual",
7778
starter: "testTars/la-croix-starter",
7879
},
80+
{
81+
descrip: "Tar with whitelist",
82+
tarPath: "testTars/la-croix2.tar",
83+
target: "testTars/la-croix-whitelist",
84+
expected: "testTars/la-croix1-actual",
85+
whitelist: []string{"testTars/la-croix-whitelist/nest"},
86+
},
7987
}
8088
for _, test := range testCases {
8189
remove := true
@@ -86,7 +94,7 @@ func TestUnTar(t *testing.T) {
8694
if err != nil {
8795
t.Errorf("Error opening tar: %s", err)
8896
}
89-
if err := pkgutil.UnTar(r, test.target); err != nil && !test.err {
97+
if err := pkgutil.UnTar(r, test.target, test.whitelist); err != nil && !test.err {
9098
t.Errorf(test.descrip, "Got unexpected error: %s", err)
9199
remove = false
92100
}

0 commit comments

Comments
 (0)