github.com/rish1988/moby@v25.0.2+incompatible/pkg/chrootarchive/archive_unix.go (about) 1 //go:build !windows 2 3 package chrootarchive // import "github.com/docker/docker/pkg/chrootarchive" 4 5 import ( 6 "io" 7 "net" 8 "os/user" 9 "path/filepath" 10 "strings" 11 12 "github.com/docker/docker/pkg/archive" 13 "github.com/pkg/errors" 14 ) 15 16 func init() { 17 // initialize nss libraries in Glibc so that the dynamic libraries are loaded in the host 18 // environment not in the chroot from untrusted files. 19 _, _ = user.Lookup("docker") 20 _, _ = net.LookupHost("localhost") 21 } 22 23 func invokeUnpack(decompressedArchive io.Reader, dest string, options *archive.TarOptions, root string) error { 24 relDest, err := resolvePathInChroot(root, dest) 25 if err != nil { 26 return err 27 } 28 29 return doUnpack(decompressedArchive, relDest, root, options) 30 } 31 32 func invokePack(srcPath string, options *archive.TarOptions, root string) (io.ReadCloser, error) { 33 relSrc, err := resolvePathInChroot(root, srcPath) 34 if err != nil { 35 return nil, err 36 } 37 38 // make sure we didn't trim a trailing slash with the call to `resolvePathInChroot` 39 if strings.HasSuffix(srcPath, "/") && !strings.HasSuffix(relSrc, "/") { 40 relSrc += "/" 41 } 42 43 return doPack(relSrc, root, options) 44 } 45 46 // resolvePathInChroot returns the equivalent to path inside a chroot rooted at root. 47 // The returned path always begins with '/'. 48 // 49 // - resolvePathInChroot("/a/b", "/a/b/c/d") -> "/c/d" 50 // - resolvePathInChroot("/a/b", "/a/b") -> "/" 51 // 52 // The implementation is buggy, and some bugs may be load-bearing. 53 // Here be dragons. 54 func resolvePathInChroot(root, path string) (string, error) { 55 if root == "" { 56 return "", errors.New("root path must not be empty") 57 } 58 rel, err := filepath.Rel(root, path) 59 if err != nil { 60 return "", err 61 } 62 if rel == "." { 63 rel = "/" 64 } 65 if rel[0] != '/' { 66 rel = "/" + rel 67 } 68 return rel, nil 69 }