diff --git a/AUTHORS b/AUTHORS index 014748e187..8f75ab85b3 100644 --- a/AUTHORS +++ b/AUTHORS @@ -189,6 +189,7 @@ Kimbro Staken Kiran Gangadharan Konstantin Pelykh Kyle Conroy +Lajos Papp Laurie Voss Liang-Chi Hsieh Lokesh Mandvekar diff --git a/pkg/symlink/fs.go b/pkg/symlink/fs.go index e91d33db4b..257491f91b 100644 --- a/pkg/symlink/fs.go +++ b/pkg/symlink/fs.go @@ -3,10 +3,13 @@ package symlink import ( "fmt" "os" + "path" "path/filepath" "strings" ) +const maxLoopCounter = 100 + // FollowSymlink will follow an existing link and scope it to the root // path provided. func FollowSymlinkInScope(link, root string) (string, error) { @@ -30,7 +33,14 @@ func FollowSymlinkInScope(link, root string) (string, error) { prev = filepath.Join(prev, p) prev = filepath.Clean(prev) + loopCounter := 0 for { + loopCounter++ + + if loopCounter >= maxLoopCounter { + return "", fmt.Errorf("loopCounter reached MAX: %v", loopCounter) + } + if !strings.HasPrefix(prev, root) { // Don't resolve symlinks outside of root. For example, // we don't have to check /home in the below. @@ -53,10 +63,9 @@ func FollowSymlinkInScope(link, root string) (string, error) { return "", err } - switch dest[0] { - case '/': + if path.IsAbs(dest) { prev = filepath.Join(root, dest) - case '.': + } else { prev, _ = filepath.Abs(prev) if prev = filepath.Clean(filepath.Join(filepath.Dir(prev), dest)); len(prev) < len(root) { diff --git a/pkg/symlink/fs_test.go b/pkg/symlink/fs_test.go index 1f12aa3a60..d85fd6da74 100644 --- a/pkg/symlink/fs_test.go +++ b/pkg/symlink/fs_test.go @@ -28,6 +28,19 @@ func TestFollowSymLinkNormal(t *testing.T) { } } +func TestFollowSymLinkRelativePath(t *testing.T) { + link := "testdata/fs/i" + + rewrite, err := FollowSymlinkInScope(link, "testdata") + if err != nil { + t.Fatal(err) + } + + if expected := abs(t, "testdata/fs/a"); expected != rewrite { + t.Fatalf("Expected %s got %s", expected, rewrite) + } +} + func TestFollowSymLinkUnderLinkedDir(t *testing.T) { dir, err := ioutil.TempDir("", "docker-fs-test") if err != nil { diff --git a/pkg/symlink/testdata/fs/i b/pkg/symlink/testdata/fs/i new file mode 120000 index 0000000000..2e65efe2a1 --- /dev/null +++ b/pkg/symlink/testdata/fs/i @@ -0,0 +1 @@ +a \ No newline at end of file