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  }