ソースを参照

Merge pull request #5396 from lalyos/5370-infinite-loop-caused-by-symlink

5370 infinite loop caused by symlink
Michael Crosby 11 年 前
コミット
23062e55fd
4 ファイル変更27 行追加3 行削除
  1. 1 0
      AUTHORS
  2. 12 3
      pkg/symlink/fs.go
  3. 13 0
      pkg/symlink/fs_test.go
  4. 1 0
      pkg/symlink/testdata/fs/i

+ 1 - 0
AUTHORS

@@ -189,6 +189,7 @@ Kimbro Staken <kstaken@kstaken.com>
 Kiran Gangadharan <kiran.daredevil@gmail.com>
 Konstantin Pelykh <kpelykh@zettaset.com>
 Kyle Conroy <kyle.j.conroy@gmail.com>
+Lajos Papp <lajos.papp@sequenceiq.com>
 Laurie Voss <github@seldo.com>
 Liang-Chi Hsieh <viirya@gmail.com>
 Lokesh Mandvekar <lsm5@redhat.com>

+ 12 - 3
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) {

+ 13 - 0
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 {

+ 1 - 0
pkg/symlink/testdata/fs/i

@@ -0,0 +1 @@
+a