diff --git a/utils/git.go b/utils/git.go index ce8924d8af..6c039bddbe 100644 --- a/utils/git.go +++ b/utils/git.go @@ -10,6 +10,7 @@ import ( "path/filepath" "strings" + "github.com/docker/docker/pkg/symlink" "github.com/docker/docker/pkg/urlutil" ) @@ -69,7 +70,11 @@ func checkoutGit(fragment, root string) (string, error) { } if len(refAndDir) > 1 && len(refAndDir[1]) != 0 { - newCtx := filepath.Join(root, refAndDir[1]) + newCtx, err := symlink.FollowSymlinkInScope(filepath.Join(root, refAndDir[1]), root) + if err != nil { + return "", fmt.Errorf("Error setting git context, %q not within git root: %s", refAndDir[1], err) + } + fi, err := os.Stat(newCtx) if err != nil { return "", err diff --git a/utils/git_test.go b/utils/git_test.go index 10b13e9627..e9eb595630 100644 --- a/utils/git_test.go +++ b/utils/git_test.go @@ -103,6 +103,14 @@ func TestCheckoutGit(t *testing.T) { t.Fatal(err) } + if err = os.Symlink("../subdir", filepath.Join(gitDir, "parentlink")); err != nil { + t.Fatal(err) + } + + if err = os.Symlink("/subdir", filepath.Join(gitDir, "absolutelink")); err != nil { + t.Fatal(err) + } + if _, err = gitWithinDir(gitDir, "add", "-A"); err != nil { t.Fatal(err) } @@ -147,6 +155,9 @@ func TestCheckoutGit(t *testing.T) { {":Dockerfile", "", true}, // not a directory error {"master:nosubdir", "", true}, {"master:subdir", "FROM scratch\nEXPOSE 5000", false}, + {"master:parentlink", "FROM scratch\nEXPOSE 5000", false}, + {"master:absolutelink", "FROM scratch\nEXPOSE 5000", false}, + {"master:../subdir", "", true}, {"test", "FROM scratch\nEXPOSE 3000", false}, {"test:", "FROM scratch\nEXPOSE 3000", false}, {"test:subdir", "FROM busybox\nEXPOSE 5000", false},