8b843732b3
For unix targets, `goInChroot()` is only implemented for `Linux`, hence FreeBSD build fails. This change - Adds FreeBSD-specific chrooted tar/untar implementation - Fixes statUnix() to accomodate to FreeBSD devminor/devmajor - quirk. See also: https://github.com/containerd/containerd/pull/5991 Signed-off-by: Artem Khramov <akhramov@pm.me> Co-authored-by: Cory Snider <corhere@gmail.com>
69 lines
1.7 KiB
Go
69 lines
1.7 KiB
Go
//go:build !windows
|
|
|
|
package chrootarchive // import "github.com/docker/docker/pkg/chrootarchive"
|
|
|
|
import (
|
|
"io"
|
|
"net"
|
|
"os/user"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/docker/docker/pkg/archive"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func init() {
|
|
// initialize nss libraries in Glibc so that the dynamic libraries are loaded in the host
|
|
// environment not in the chroot from untrusted files.
|
|
_, _ = user.Lookup("docker")
|
|
_, _ = net.LookupHost("localhost")
|
|
}
|
|
|
|
func invokeUnpack(decompressedArchive io.Reader, dest string, options *archive.TarOptions, root string) error {
|
|
relDest, err := resolvePathInChroot(root, dest)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return doUnpack(decompressedArchive, relDest, root, options)
|
|
}
|
|
|
|
func invokePack(srcPath string, options *archive.TarOptions, root string) (io.ReadCloser, error) {
|
|
relSrc, err := resolvePathInChroot(root, srcPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// make sure we didn't trim a trailing slash with the call to `resolvePathInChroot`
|
|
if strings.HasSuffix(srcPath, "/") && !strings.HasSuffix(relSrc, "/") {
|
|
relSrc += "/"
|
|
}
|
|
|
|
return doPack(relSrc, root, options)
|
|
}
|
|
|
|
// resolvePathInChroot returns the equivalent to path inside a chroot rooted at root.
|
|
// The returned path always begins with '/'.
|
|
//
|
|
// - resolvePathInChroot("/a/b", "/a/b/c/d") -> "/c/d"
|
|
// - resolvePathInChroot("/a/b", "/a/b") -> "/"
|
|
//
|
|
// The implementation is buggy, and some bugs may be load-bearing.
|
|
// Here be dragons.
|
|
func resolvePathInChroot(root, path string) (string, error) {
|
|
if root == "" {
|
|
return "", errors.New("root path must not be empty")
|
|
}
|
|
rel, err := filepath.Rel(root, path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if rel == "." {
|
|
rel = "/"
|
|
}
|
|
if rel[0] != '/' {
|
|
rel = "/" + rel
|
|
}
|
|
return rel, nil
|
|
}
|