mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Improve FollowLink to handle recursive link and be more strick
This commit is contained in:
parent
f396c42cad
commit
8fd9633a6b
5 changed files with 52 additions and 41 deletions
|
@ -827,7 +827,7 @@ func (container *Container) createVolumes() error {
|
||||||
|
|
||||||
// Create the mountpoint
|
// Create the mountpoint
|
||||||
volPath = path.Join(container.RootfsPath(), volPath)
|
volPath = path.Join(container.RootfsPath(), volPath)
|
||||||
rootVolPath, err := utils.FollowSymlink(volPath, container.RootfsPath())
|
rootVolPath, err := utils.FollowSymlinkInScope(volPath, container.RootfsPath())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
50
utils/fs.go
50
utils/fs.go
|
@ -1,6 +1,7 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -38,43 +39,52 @@ func TreeSize(dir string) (size int64, err error) {
|
||||||
// FollowSymlink will follow an existing link and scope it to the root
|
// FollowSymlink will follow an existing link and scope it to the root
|
||||||
// path provided.
|
// path provided.
|
||||||
func FollowSymlinkInScope(link, root string) (string, error) {
|
func FollowSymlinkInScope(link, root string) (string, error) {
|
||||||
prev := "."
|
prev := "/"
|
||||||
|
|
||||||
root, err := filepath.Abs(root)
|
root, err := filepath.Abs(root)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
root = filepath.Clean(root)
|
|
||||||
link, err := filepath.Abs(link)
|
link, err = filepath.Abs(link)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
link = filepath.Clean(link)
|
|
||||||
|
if !strings.HasPrefix(filepath.Dir(link), root) {
|
||||||
|
return "", fmt.Errorf("%s is not within %s", link, root)
|
||||||
|
}
|
||||||
|
|
||||||
for _, p := range strings.Split(link, "/") {
|
for _, p := range strings.Split(link, "/") {
|
||||||
prev = filepath.Join(prev, p)
|
prev = filepath.Join(prev, p)
|
||||||
prev = filepath.Clean(prev)
|
prev = filepath.Clean(prev)
|
||||||
|
|
||||||
stat, err := os.Lstat(prev)
|
for {
|
||||||
if err != nil {
|
stat, err := os.Lstat(prev)
|
||||||
if os.IsNotExist(err) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if stat.Mode()&os.ModeSymlink == os.ModeSymlink {
|
|
||||||
dest, err := os.Readlink(prev)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if os.IsNotExist(err) {
|
||||||
|
break
|
||||||
|
}
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
if stat.Mode()&os.ModeSymlink == os.ModeSymlink {
|
||||||
switch dest[0] {
|
dest, err := os.Readlink(prev)
|
||||||
case '/':
|
if err != nil {
|
||||||
prev = filepath.Join(root, dest)
|
return "", err
|
||||||
case '.':
|
|
||||||
if prev = filepath.Clean(filepath.Join(filepath.Dir(prev), dest)); len(prev) < len(root) {
|
|
||||||
prev = filepath.Join(root, filepath.Base(dest))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch dest[0] {
|
||||||
|
case '/':
|
||||||
|
prev = filepath.Join(root, dest)
|
||||||
|
case '.':
|
||||||
|
prev, _ = filepath.Abs(prev)
|
||||||
|
|
||||||
|
if prev = filepath.Clean(filepath.Join(filepath.Dir(prev), dest)); len(prev) < len(root) {
|
||||||
|
prev = filepath.Join(root, filepath.Base(dest))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
package utils
|
package utils
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func abs(p string) string {
|
func abs(t *testing.T, p string) string {
|
||||||
o, err := filepath.Abs(p)
|
o, err := filepath.Abs(p)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
return o
|
return o
|
||||||
}
|
}
|
||||||
|
@ -17,36 +16,31 @@ func abs(p string) string {
|
||||||
func TestFollowSymLinkNormal(t *testing.T) {
|
func TestFollowSymLinkNormal(t *testing.T) {
|
||||||
link := "testdata/fs/a/d/c/data"
|
link := "testdata/fs/a/d/c/data"
|
||||||
|
|
||||||
rewrite, err := FollowSymlink(link, "test")
|
rewrite, err := FollowSymlinkInScope(link, "testdata")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if expected := abs("test/b/c/data"); expected != rewrite {
|
if expected := abs(t, "testdata/b/c/data"); expected != rewrite {
|
||||||
t.Fatalf("Expected %s got %s", expected, rewrite)
|
t.Fatalf("Expected %s got %s", expected, rewrite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFollowSymLinkRandomString(t *testing.T) {
|
func TestFollowSymLinkRandomString(t *testing.T) {
|
||||||
rewrite, err := FollowSymlink("toto", "test")
|
if _, err := FollowSymlinkInScope("toto", "testdata"); err == nil {
|
||||||
if err != nil {
|
t.Fatal("Random string should fail but didn't")
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if rewrite != "toto" {
|
|
||||||
t.Fatalf("Expected toto got %s", rewrite)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFollowSymLinkLastLink(t *testing.T) {
|
func TestFollowSymLinkLastLink(t *testing.T) {
|
||||||
link := "testdata/fs/a/d"
|
link := "testdata/fs/a/d"
|
||||||
|
|
||||||
rewrite, err := FollowSymlink(link, "test")
|
rewrite, err := FollowSymlinkInScope(link, "testdata")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if expected := abs("test/b"); expected != rewrite {
|
if expected := abs(t, "testdata/b"); expected != rewrite {
|
||||||
t.Fatalf("Expected %s got %s", expected, rewrite)
|
t.Fatalf("Expected %s got %s", expected, rewrite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,31 +48,36 @@ func TestFollowSymLinkLastLink(t *testing.T) {
|
||||||
func TestFollowSymLinkRelativeLink(t *testing.T) {
|
func TestFollowSymLinkRelativeLink(t *testing.T) {
|
||||||
link := "testdata/fs/a/e/c/data"
|
link := "testdata/fs/a/e/c/data"
|
||||||
|
|
||||||
rewrite, err := FollowSymlink(link, "test")
|
rewrite, err := FollowSymlinkInScope(link, "testdata")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if expected := abs("testdata/fs/a/e/c/data"); expected != rewrite {
|
if expected := abs(t, "testdata/fs/b/c/data"); expected != rewrite {
|
||||||
t.Fatalf("Expected %s got %s", expected, rewrite)
|
t.Fatalf("Expected %s got %s", expected, rewrite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFollowSymLinkRelativeLinkScope(t *testing.T) {
|
func TestFollowSymLinkRelativeLinkScope(t *testing.T) {
|
||||||
link := "testdata/fs/a/f"
|
link := "testdata/fs/a/f"
|
||||||
pwd, err := os.Getwd()
|
|
||||||
|
rewrite, err := FollowSymlinkInScope(link, "testdata")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
root := filepath.Join(pwd, "testdata")
|
if expected := abs(t, "testdata/test"); expected != rewrite {
|
||||||
|
t.Fatalf("Expected %s got %s", expected, rewrite)
|
||||||
|
}
|
||||||
|
|
||||||
rewrite, err := FollowSymlink(link, root)
|
link = "testdata/fs/b/h"
|
||||||
|
|
||||||
|
rewrite, err = FollowSymlinkInScope(link, "testdata")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if expected := abs("testdata/test"); expected != rewrite {
|
if expected := abs(t, "testdata/root"); expected != rewrite {
|
||||||
t.Fatalf("Expected %s got %s", expected, rewrite)
|
t.Fatalf("Expected %s got %s", expected, rewrite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
utils/testdata/fs/b/h
vendored
Symbolic link
1
utils/testdata/fs/b/h
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../g
|
1
utils/testdata/fs/g
vendored
Symbolic link
1
utils/testdata/fs/g
vendored
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../../../../../../../../../../../../root
|
Loading…
Add table
Reference in a new issue