diff options
Diffstat (limited to 'vendor/github.com')
5 files changed, 94 insertions, 17 deletions
diff --git a/vendor/github.com/containers/buildah/add.go b/vendor/github.com/containers/buildah/add.go index 0903fc7db..cd466ccb3 100644 --- a/vendor/github.com/containers/buildah/add.go +++ b/vendor/github.com/containers/buildah/add.go @@ -324,13 +324,33 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption return errors.Wrapf(err, "error processing excludes list %v", options.Excludes) } - // Copy each source in turn. + // Make sure that, if it's a symlink, we'll chroot to the target of the link; + // knowing that target requires that we resolve it within the chroot. + evalOptions := copier.EvalOptions{} + evaluated, err := copier.Eval(mountPoint, extractDirectory, evalOptions) + if err != nil { + return errors.Wrapf(err, "error checking on destination %v", extractDirectory) + } + extractDirectory = evaluated + + // Set up ID maps. var srcUIDMap, srcGIDMap []idtools.IDMap if options.IDMappingOptions != nil { srcUIDMap, srcGIDMap = convertRuntimeIDMaps(options.IDMappingOptions.UIDMap, options.IDMappingOptions.GIDMap) } destUIDMap, destGIDMap := convertRuntimeIDMaps(b.IDMappingOptions.UIDMap, b.IDMappingOptions.GIDMap) + // Create the target directory if it doesn't exist yet. + mkdirOptions := copier.MkdirOptions{ + UIDMap: destUIDMap, + GIDMap: destGIDMap, + ChownNew: chownDirs, + } + if err := copier.Mkdir(mountPoint, extractDirectory, mkdirOptions); err != nil { + return errors.Wrapf(err, "error ensuring target directory exists") + } + + // Copy each source in turn. for _, src := range sources { var multiErr *multierror.Error var getErr, closeErr, renameErr, putErr error @@ -363,7 +383,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption ChmodFiles: nil, IgnoreDevices: rsystem.RunningInUserNS(), } - putErr = copier.Put(mountPoint, extractDirectory, putOptions, io.TeeReader(pipeReader, hasher)) + putErr = copier.Put(extractDirectory, extractDirectory, putOptions, io.TeeReader(pipeReader, hasher)) } hashCloser.Close() pipeReader.Close() @@ -498,7 +518,7 @@ func (b *Builder) Add(destination string, extract bool, options AddAndCopyOption ChmodFiles: nil, IgnoreDevices: rsystem.RunningInUserNS(), } - putErr = copier.Put(mountPoint, extractDirectory, putOptions, io.TeeReader(pipeReader, hasher)) + putErr = copier.Put(extractDirectory, extractDirectory, putOptions, io.TeeReader(pipeReader, hasher)) } hashCloser.Close() pipeReader.Close() diff --git a/vendor/github.com/containers/buildah/buildah.go b/vendor/github.com/containers/buildah/buildah.go index dd43ea99a..77d313c58 100644 --- a/vendor/github.com/containers/buildah/buildah.go +++ b/vendor/github.com/containers/buildah/buildah.go @@ -28,7 +28,7 @@ const ( Package = "buildah" // Version for the Package. Bump version in contrib/rpm/buildah.spec // too. - Version = "1.19.6" + Version = "1.19.7" // The value we use to identify what type of information, currently a // serialized Builder structure, we are using as per-container state. // This should only be changed when we make incompatible changes to diff --git a/vendor/github.com/containers/buildah/copier/copier.go b/vendor/github.com/containers/buildah/copier/copier.go index 63cdb1974..b5e107d4b 100644 --- a/vendor/github.com/containers/buildah/copier/copier.go +++ b/vendor/github.com/containers/buildah/copier/copier.go @@ -70,6 +70,7 @@ func isArchivePath(path string) bool { type requestType string const ( + requestEval requestType = "EVAL" requestStat requestType = "STAT" requestGet requestType = "GET" requestPut requestType = "PUT" @@ -95,6 +96,8 @@ type request struct { func (req *request) Excludes() []string { switch req.Request { + case requestEval: + return nil case requestStat: return req.StatOptions.Excludes case requestGet: @@ -112,6 +115,8 @@ func (req *request) Excludes() []string { func (req *request) UIDMap() []idtools.IDMap { switch req.Request { + case requestEval: + return nil case requestStat: return nil case requestGet: @@ -129,6 +134,8 @@ func (req *request) UIDMap() []idtools.IDMap { func (req *request) GIDMap() []idtools.IDMap { switch req.Request { + case requestEval: + return nil case requestStat: return nil case requestGet: @@ -148,6 +155,7 @@ func (req *request) GIDMap() []idtools.IDMap { type response struct { Error string `json:",omitempty"` Stat statResponse + Eval evalResponse Get getResponse Put putResponse Mkdir mkdirResponse @@ -158,6 +166,11 @@ type statResponse struct { Globs []*StatsForGlob } +// evalResponse encodes a response for a single Eval request. +type evalResponse struct { + Evaluated string +} + // StatsForGlob encode results for a single glob pattern passed to Stat(). type StatsForGlob struct { Error string `json:",omitempty"` // error if the Glob pattern was malformed @@ -192,6 +205,33 @@ type putResponse struct { type mkdirResponse struct { } +// EvalOptions controls parts of Eval()'s behavior. +type EvalOptions struct { +} + +// Eval evaluates the directory's path, including any intermediate symbolic +// links. +// If root is specified and the current OS supports it, and the calling process +// has the necessary privileges, evaluation is performed in a chrooted context. +// If the directory is specified as an absolute path, it should either be the +// root directory or a subdirectory of the root directory. Otherwise, the +// directory is treated as a path relative to the root directory. +func Eval(root string, directory string, options EvalOptions) (string, error) { + req := request{ + Request: requestEval, + Root: root, + Directory: directory, + } + resp, err := copier(nil, nil, req) + if err != nil { + return "", err + } + if resp.Error != "" { + return "", errors.New(resp.Error) + } + return resp.Eval.Evaluated, nil +} + // StatOptions controls parts of Stat()'s behavior. type StatOptions struct { CheckForArchives bool // check for and populate the IsArchive bit in returned values @@ -243,6 +283,7 @@ type GetOptions struct { StripXattrs bool // don't record extended attributes of items being copied. no effect on archives being extracted KeepDirectoryNames bool // don't strip the top directory's basename from the paths of items in subdirectories Rename map[string]string // rename items with the specified names, or under the specified names + NoDerefSymlinks bool // don't follow symlinks when globs match them } // Get produces an archive containing items that match the specified glob @@ -557,6 +598,9 @@ func copierWithSubprocess(bulkReader io.Reader, bulkWriter io.Writer, req reques return killAndReturn(err, "error encoding request for copier subprocess") } if err = decoder.Decode(&resp); err != nil { + if errors.Is(err, io.EOF) && errorBuffer.Len() > 0 { + return killAndReturn(errors.New(errorBuffer.String()), "error in copier subprocess") + } return killAndReturn(err, "error decoding response from copier subprocess") } if err = encoder.Encode(&request{Request: requestQuit}); err != nil { @@ -667,7 +711,7 @@ func copierMain() { var err error chrooted, err = chroot(req.Root) if err != nil { - fmt.Fprintf(os.Stderr, "error changing to intended-new-root directory %q: %v", req.Root, err) + fmt.Fprintf(os.Stderr, "%v", err) os.Exit(1) } } @@ -762,6 +806,9 @@ func copierHandler(bulkReader io.Reader, bulkWriter io.Writer, req request) (*re switch req.Request { default: return nil, nil, errors.Errorf("not an implemented request type: %q", req.Request) + case requestEval: + resp := copierHandlerEval(req) + return resp, nil, nil case requestStat: resp := copierHandlerStat(req, pm) return resp, nil, nil @@ -870,6 +917,17 @@ func resolvePath(root, path string, pm *fileutils.PatternMatcher) (string, error return workingPath, nil } +func copierHandlerEval(req request) *response { + errorResponse := func(fmtspec string, args ...interface{}) *response { + return &response{Error: fmt.Sprintf(fmtspec, args...), Eval: evalResponse{}} + } + resolvedTarget, err := resolvePath(req.Root, req.Directory, nil) + if err != nil { + return errorResponse("copier: eval: error resolving %q: %v", req.Directory, err) + } + return &response{Eval: evalResponse{Evaluated: filepath.Join(req.rootPrefix, resolvedTarget)}} +} + func copierHandlerStat(req request, pm *fileutils.PatternMatcher) *response { errorResponse := func(fmtspec string, args ...interface{}) *response { return &response{Error: fmt.Sprintf(fmtspec, args...), Stat: statResponse{}} @@ -1024,7 +1082,7 @@ func copierHandlerGet(bulkWriter io.Writer, req request, pm *fileutils.PatternMa // chase links. if we hit a dead end, we should just fail followedLinks := 0 const maxFollowedLinks = 16 - for info.Mode()&os.ModeType == os.ModeSymlink && followedLinks < maxFollowedLinks { + for !req.GetOptions.NoDerefSymlinks && info.Mode()&os.ModeType == os.ModeSymlink && followedLinks < maxFollowedLinks { path, err := os.Readlink(item) if err != nil { continue @@ -1139,7 +1197,8 @@ func handleRename(rename map[string]string, name string) string { return path.Join(mappedPrefix, remainder) } if prefix[len(prefix)-1] == '/' { - if mappedPrefix, ok := rename[prefix[:len(prefix)-1]]; ok { + prefix = prefix[:len(prefix)-1] + if mappedPrefix, ok := rename[prefix]; ok { return path.Join(mappedPrefix, remainder) } } diff --git a/vendor/github.com/containers/buildah/copier/syscall_unix.go b/vendor/github.com/containers/buildah/copier/syscall_unix.go index 2c2806d0a..aa40f327c 100644 --- a/vendor/github.com/containers/buildah/copier/syscall_unix.go +++ b/vendor/github.com/containers/buildah/copier/syscall_unix.go @@ -3,10 +3,10 @@ package copier import ( - "fmt" "os" "time" + "github.com/pkg/errors" "golang.org/x/sys/unix" ) @@ -15,13 +15,13 @@ var canChroot = os.Getuid() == 0 func chroot(root string) (bool, error) { if canChroot { if err := os.Chdir(root); err != nil { - return false, fmt.Errorf("error changing to intended-new-root directory %q: %v", root, err) + return false, errors.Wrapf(err, "error changing to intended-new-root directory %q", root) } if err := unix.Chroot(root); err != nil { - return false, fmt.Errorf("error chrooting to directory %q: %v", root, err) + return false, errors.Wrapf(err, "error chrooting to directory %q", root) } if err := os.Chdir(string(os.PathSeparator)); err != nil { - return false, fmt.Errorf("error changing to just-became-root directory %q: %v", root, err) + return false, errors.Wrapf(err, "error changing to just-became-root directory %q", root) } return true, nil } diff --git a/vendor/github.com/containers/buildah/pkg/overlay/overlay.go b/vendor/github.com/containers/buildah/pkg/overlay/overlay.go index a3e5866ee..462561983 100644 --- a/vendor/github.com/containers/buildah/pkg/overlay/overlay.go +++ b/vendor/github.com/containers/buildah/pkg/overlay/overlay.go @@ -77,13 +77,11 @@ func mountHelper(contentDir, source, dest string, _, _ int, graphOptions []strin // Read-write overlay mounts want a lower, upper and a work layer. workDir := filepath.Join(contentDir, "work") upperDir := filepath.Join(contentDir, "upper") - st, err := os.Stat(dest) - if err == nil { - if err := os.Chmod(upperDir, st.Mode()); err != nil { - return mount, err - } + st, err := os.Stat(source) + if err != nil { + return mount, err } - if !os.IsNotExist(err) { + if err := os.Chmod(upperDir, st.Mode()); err != nil { return mount, err } overlayOptions = fmt.Sprintf("lowerdir=%s,upperdir=%s,workdir=%s,private", source, upperDir, workDir) |