From e3e078ca2fc4ce76461a40533add9f33afcd1abe Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Sat, 12 Apr 2014 06:42:53 +0900 Subject: [PATCH 1/2] Add the test to reproduce the issue even in "make test" Docker-DCO-1.1-Signed-off-by: Kato Kazuyoshi (github: kzys) --- utils/fs_test.go | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/utils/fs_test.go b/utils/fs_test.go index dd5d97be40..9affc00e91 100644 --- a/utils/fs_test.go +++ b/utils/fs_test.go @@ -1,6 +1,8 @@ package utils import ( + "io/ioutil" + "os" "path/filepath" "testing" ) @@ -26,6 +28,29 @@ func TestFollowSymLinkNormal(t *testing.T) { } } +func TestFollowSymLinkUnderLinkedDir(t *testing.T) { + dir, err := ioutil.TempDir("", "docker-fs-test") + if err != nil { + t.Fatal(err) + } + + os.Mkdir(filepath.Join(dir, "realdir"), 0700) + os.Symlink("realdir", filepath.Join(dir, "linkdir")) + + linkDir := filepath.Join(dir, "linkdir", "foo") + dirUnderLinkDir := filepath.Join(dir, "linkdir", "foo", "bar") + os.MkdirAll(dirUnderLinkDir, 0700) + + rewrite, err := FollowSymlinkInScope(dirUnderLinkDir, linkDir) + if err != nil { + t.Fatal(err) + } + + if rewrite != dirUnderLinkDir { + t.Fatalf("Expected %s got %s", dirUnderLinkDir, rewrite) + } +} + func TestFollowSymLinkRandomString(t *testing.T) { if _, err := FollowSymlinkInScope("toto", "testdata"); err == nil { t.Fatal("Random string should fail but didn't") From 0f724863468733847306f47835739f480a7fac63 Mon Sep 17 00:00:00 2001 From: Kato Kazuyoshi Date: Fri, 11 Apr 2014 07:47:53 +0900 Subject: [PATCH 2/2] Fix utils.FollowSymlinkInScope's infinite loop bug fs_test.go doesn't finish if Docker's code is placed under a directory which has symlinks between / and the directory. For example, the below doesn't finish before the change. /home -> usr/home FollowSymlinkInScope("/home/bob/foo/bar", "/home/bob/foo") Docker-DCO-1.1-Signed-off-by: Kato Kazuyoshi (github: kzys) --- utils/fs.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/utils/fs.go b/utils/fs.go index 92864e5e16..46f64903b3 100644 --- a/utils/fs.go +++ b/utils/fs.go @@ -62,6 +62,15 @@ func FollowSymlinkInScope(link, root string) (string, error) { prev = filepath.Clean(prev) for { + if !strings.HasPrefix(prev, root) { + // Don't resolve symlinks outside of root. For example, + // we don't have to check /home in the below. + // + // /home -> usr/home + // FollowSymlinkInScope("/home/bob/foo/bar", "/home/bob/foo") + break + } + stat, err := os.Lstat(prev) if err != nil { if os.IsNotExist(err) {