[ARVADOS] updated: 1.1.0-38-gca3d900

Git user git at public.curoverse.com
Mon Oct 16 16:40:10 EDT 2017


Summary of changes:
 services/crunch-run/crunchrun.go      | 30 +++++++++++++++++++++---------
 services/crunch-run/crunchrun_test.go | 18 ++++++++++++++++++
 2 files changed, 39 insertions(+), 9 deletions(-)

       via  ca3d9008da4a57e71cb7e6dfd1e25b5eb0c0de0b (commit)
      from  e5f33b99e1c363e4d14f429075fdce15b9643000 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit ca3d9008da4a57e71cb7e6dfd1e25b5eb0c0de0b
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Mon Oct 16 16:39:36 2017 -0400

    12183: Handle circular directory symlinks
    
    Arvados-DCO-1.1-Signed-off-by: Peter Amstutz <pamstutz at veritasgenetics.com>

diff --git a/services/crunch-run/crunchrun.go b/services/crunch-run/crunchrun.go
index f900d19..cb80436 100644
--- a/services/crunch-run/crunchrun.go
+++ b/services/crunch-run/crunchrun.go
@@ -914,6 +914,8 @@ func (runner *ContainerRunner) WaitFinish() (err error) {
 	return nil
 }
 
+var NotInOutputDirError = fmt.Errorf("Must point to path within the output directory")
+
 func (runner *ContainerRunner) derefOutputSymlink(path string, startinfo os.FileInfo) (tgt string, readlinktgt string, info os.FileInfo, err error) {
 	// Follow symlinks if necessary
 	info = startinfo
@@ -921,7 +923,7 @@ func (runner *ContainerRunner) derefOutputSymlink(path string, startinfo os.File
 	readlinktgt = ""
 	nextlink := path
 	for followed := 0; info.Mode()&os.ModeSymlink != 0; followed++ {
-		if followed >= 32 {
+		if followed >= 16 {
 			// Got stuck in a loop or just a pathological number of links, give up.
 			err = fmt.Errorf("Followed too many symlinks from path %q", path)
 			return
@@ -945,14 +947,15 @@ func (runner *ContainerRunner) derefOutputSymlink(path string, startinfo os.File
 			// After dereferencing, symlink target must either be
 			// within output directory, or must point to a
 			// collection mount.
-			break
+			err = NotInOutputDirError
+			return
 		}
 
 		info, err = os.Lstat(tgt)
 		if err != nil {
 			// tgt
-			err = fmt.Errorf("Symlink in output %q points to invalid location %q, must exist, be readable, and point to path within the output directory.",
-				path[len(runner.HostOutputDir):], readlinktgt)
+			err = fmt.Errorf("Symlink in output %q points to invalid location %q: %v",
+				path[len(runner.HostOutputDir):], readlinktgt, err)
 			return
 		}
 
@@ -976,7 +979,8 @@ func (runner *ContainerRunner) UploadOutputFile(
 	binds []string,
 	walkUpload *WalkUpload,
 	relocateFrom string,
-	relocateTo string) (manifestText string, err error) {
+	relocateTo string,
+	followed int) (manifestText string, err error) {
 
 	if info.Mode().IsDir() {
 		return
@@ -986,13 +990,20 @@ func (runner *ContainerRunner) UploadOutputFile(
 		return "", infoerr
 	}
 
+	if followed >= 8 {
+		// Got stuck in a loop or just a pathological number of
+		// directory links, give up.
+		err = fmt.Errorf("Followed too many symlinks from path %q", path)
+		return
+	}
+
 	// When following symlinks, the source path may need to be logically
 	// relocated to some other path within the output collection.  Remove
 	// the relocateFrom prefix and replace it with relocateTo.
 	relocated := relocateTo + path[len(relocateFrom):]
 
 	tgt, readlinktgt, info, derefErr := runner.derefOutputSymlink(path, info)
-	if derefErr != nil {
+	if derefErr != nil && derefErr != NotInOutputDirError {
 		return "", derefErr
 	}
 
@@ -1017,7 +1028,7 @@ func (runner *ContainerRunner) UploadOutputFile(
 
 	// If target is not a collection mount, it must be located within the
 	// output directory, otherwise it is an error.
-	if !strings.HasPrefix(tgt, runner.HostOutputDir+"/") {
+	if derefErr == NotInOutputDirError {
 		err = fmt.Errorf("Symlink in output %q points to invalid location %q, must point to path within the output directory.",
 			path[len(runner.HostOutputDir):], readlinktgt)
 		return
@@ -1034,7 +1045,8 @@ func (runner *ContainerRunner) UploadOutputFile(
 		// so they appear under the original symlink path.
 		err = filepath.Walk(tgt, func(walkpath string, walkinfo os.FileInfo, walkerr error) error {
 			var m string
-			m, walkerr = runner.UploadOutputFile(walkpath, walkinfo, walkerr, binds, walkUpload, tgt, relocated)
+			m, walkerr = runner.UploadOutputFile(walkpath, walkinfo, walkerr,
+				binds, walkUpload, tgt, relocated, followed+1)
 			if walkerr == nil {
 				manifestText = manifestText + m
 			}
@@ -1097,7 +1109,7 @@ func (runner *ContainerRunner) CaptureOutput() error {
 
 		var m string
 		err = filepath.Walk(runner.HostOutputDir, func(path string, info os.FileInfo, err error) error {
-			m, err = runner.UploadOutputFile(path, info, err, binds, walkUpload, "", "")
+			m, err = runner.UploadOutputFile(path, info, err, binds, walkUpload, "", "", 0)
 			if err == nil {
 				manifestText = manifestText + m
 			}
diff --git a/services/crunch-run/crunchrun_test.go b/services/crunch-run/crunchrun_test.go
index 098a642..d3c9990 100644
--- a/services/crunch-run/crunchrun_test.go
+++ b/services/crunch-run/crunchrun_test.go
@@ -1715,3 +1715,21 @@ func (s *TestSuite) TestEvalSymlinks(c *C) {
 		c.Assert(err, NotNil)
 	}
 }
+
+func (s *TestSuite) TestEvalSymlinkDir(c *C) {
+	cr := NewContainerRunner(&ArvTestClient{callraw: true}, &KeepTestClient{}, nil, "zzzzz-zzzzz-zzzzzzzzzzzzzzz")
+
+	realTemp, err := ioutil.TempDir("", "crunchrun_test-")
+	c.Assert(err, IsNil)
+	defer os.RemoveAll(realTemp)
+
+	cr.HostOutputDir = realTemp
+
+	// Absolute path outside output dir
+	os.Symlink(".", realTemp+"/loop")
+
+	v := "loop"
+	info, err := os.Lstat(realTemp + "/" + v)
+	_, err = cr.UploadOutputFile(realTemp+"/"+v, info, err, []string{}, nil, "", "", 0)
+	c.Assert(err, NotNil)
+}

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list