diff --git a/vendor.mod b/vendor.mod index 60fd9bc4ab91..bdf576c62718 100644 --- a/vendor.mod +++ b/vendor.mod @@ -31,7 +31,7 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 github.com/google/uuid v1.6.0 github.com/mattn/go-runewidth v0.0.24 - github.com/moby/go-archive v0.3.2 + github.com/moby/go-archive v0.3.3 github.com/moby/moby/api v1.55.0 github.com/moby/moby/client v0.5.1 github.com/moby/patternmatcher v0.6.1 diff --git a/vendor.sum b/vendor.sum index ba117d3db110..5909c8727b74 100644 --- a/vendor.sum +++ b/vendor.sum @@ -107,8 +107,8 @@ github.com/mattn/go-runewidth v0.0.24/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhg github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/go-archive v0.3.2 h1:x893kC3zRygv2C+k4Y9kMxYRPLCj4XEJB0srbAP06Hw= -github.com/moby/go-archive v0.3.2/go.mod h1:Npdv43fFqlhZW7Xo8fbm3ZMYFvAGNviUPqX21VERbcE= +github.com/moby/go-archive v0.3.3 h1:OxxR9paxsluYi+zDUEXTTaIxtkK3viymW+Ka7vRhhME= +github.com/moby/go-archive v0.3.3/go.mod h1:Npdv43fFqlhZW7Xo8fbm3ZMYFvAGNviUPqX21VERbcE= github.com/moby/moby/api v1.55.0 h1:2/sexvQyqIWS8pRSCFddBfpW2qE7vR7FCL+vN8pxwMc= github.com/moby/moby/api v1.55.0/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs= github.com/moby/moby/client v0.5.1 h1:tYNaJno4c0HXz12y5BiqEDy0rVTYkWzI26lGvnTMiJw= @@ -121,6 +121,10 @@ github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= github.com/moby/sys/capability v0.4.0 h1:4D4mI6KlNtWMCM1Z/K0i7RV1FkX+DBDHKVJpCndZoHk= github.com/moby/sys/capability v0.4.0/go.mod h1:4g9IK291rVkms3LKCDOoYlnV8xKwoDTpIrNEE35Wq0I= +github.com/moby/sys/mount v0.3.5 h1:eS3fsZTjHaBihwjp4/+5Z3jxqLXYsbwxqpVSfFv3M00= +github.com/moby/sys/mount v0.3.5/go.mod h1:WUQDO+/uCiCIkIztx8SrwIDVn2dtMFRBebRhpDFT71M= +github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= +github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= github.com/moby/sys/sequential v0.7.0 h1:ASQNGNROJSuOO6LL6bPHbKvuZu6NU8P4ldPWk31zj/8= github.com/moby/sys/sequential v0.7.0/go.mod h1:NfSTAp6V3fw4tmkD62PEcOKeZKquXT8VKCkf7aVR79o= github.com/moby/sys/signal v0.7.1 h1:PrQxdvxcGijdo6UXXo/lU/TvHUWyPhj7UOpSo8tuvk0= diff --git a/vendor/github.com/moby/go-archive/archive.go b/vendor/github.com/moby/go-archive/archive.go index f428fd3668f6..689720afaaf2 100644 --- a/vendor/github.com/moby/go-archive/archive.go +++ b/vendor/github.com/moby/go-archive/archive.go @@ -17,6 +17,7 @@ import ( "time" "github.com/containerd/log" + "github.com/moby/go-archive/internal/archiveoptions" "github.com/moby/patternmatcher" "github.com/moby/sys/sequential" "github.com/moby/sys/user" @@ -81,9 +82,22 @@ type ( // were probably in the archive for a reason, so set this option at // your own peril. BestEffortXattrs bool + + // internalOptions contains options for use by packages within this module. + internalOptions *archiveoptions.Options } ) +// WithProcSelfFD returns a copy of opts prepared for extraction in a +// filesystem context where /proc/self/fd may not be accessible by path. +// +// The caller must invoke the returned cleanup function after extraction +// completes. On platforms that do not use /proc/self/fd for extraction, +// the returned cleanup function is a no-op. +func WithProcSelfFD(opts *TarOptions) (*TarOptions, func(), error) { + return withProcSelfFD(opts) +} + // Archiver implements the Archiver interface and allows the reuse of most utility functions of // this package with a pluggable Untar function. Also, to facilitate the passing of specific id // mappings for untar, an Archiver can be created with maps which will then be passed to Untar operations. @@ -509,6 +523,14 @@ func resolveArchivePath(root *os.Root, name string) (string, error) { // the native, root-relative filesystem path used for extraction. func resolveHardlinkTarget(root *os.Root, linkname string) (string, error) { cleaned := path.Clean(linkname) + if strings.HasPrefix(cleaned, "/") { + // Some image builders (e.g. kaniko) write hardlink targets as absolute + // paths. Resolve those relative to the extraction root, with chroot-like + // semantics matching absolute symlink targets. Strip the root from the + // original linkname rather than the cleaned one so that ".." components + // are not collapsed against "/" but instead rejected below. + cleaned = path.Clean(strings.TrimLeft(linkname, "/")) + } if cleaned == "." || !filepath.IsLocal(cleaned) { return "", breakoutError(fmt.Errorf("invalid hardlink target %q", linkname)) } @@ -523,6 +545,7 @@ func createTarFile(root *os.Root, dstPath string, hdr *tar.Header, reader io.Rea Lchown = true inUserns, bestEffortXattrs bool chownOpts *ChownOpts + internalOpts *archiveoptions.Options ) // TODO(thaJeztah): make opts a required argument. @@ -531,6 +554,7 @@ func createTarFile(root *os.Root, dstPath string, hdr *tar.Header, reader io.Rea inUserns = opts.InUserNS // TODO(thaJeztah): consider deprecating opts.InUserNS and detect locally. chownOpts = opts.ChownOpts bestEffortXattrs = opts.BestEffortXattrs + internalOpts = opts.internalOptions } // hdr.Mode is in linux format, which we can use for sycalls, @@ -672,7 +696,7 @@ func createTarFile(root *os.Root, dstPath string, hdr *tar.Header, reader io.Rea // There is no LChmod, so ignore mode for symlink. Also, this // must happen after chown, as that can modify the file mode - if err := handleLChmod(root, dstPath, hardlinkTarget, hdr, hdrInfo); err != nil { + if err := handleLChmod(root, dstPath, hardlinkTarget, hdr, hdrInfo, internalOpts); err != nil { return err } diff --git a/vendor/github.com/moby/go-archive/archive_linux.go b/vendor/github.com/moby/go-archive/archive_linux.go index 9341bc59978a..c813cf9a7d50 100644 --- a/vendor/github.com/moby/go-archive/archive_linux.go +++ b/vendor/github.com/moby/go-archive/archive_linux.go @@ -8,10 +8,28 @@ import ( "path/filepath" "strings" + "github.com/moby/go-archive/internal/archiveoptions" "github.com/moby/sys/userns" "golang.org/x/sys/unix" ) +func withProcSelfFD(opts *TarOptions) (*TarOptions, func(), error) { + procSelfFD, err := os.Open("/proc/self/fd") + if err != nil { + return nil, nil, err + } + + var prepared TarOptions + if opts != nil { + prepared = *opts + } + prepared.internalOptions = &archiveoptions.Options{ + ProcSelfFD: procSelfFD, + } + + return &prepared, func() { _ = procSelfFD.Close() }, nil +} + func getWhiteoutConverter(format WhiteoutFormat) tarWhiteoutConverter { if format == OverlayWhiteoutFormat { return newOverlayWhiteoutConverter() diff --git a/vendor/github.com/moby/go-archive/archive_other.go b/vendor/github.com/moby/go-archive/archive_other.go index 6495549f60e8..c8fe043455f1 100644 --- a/vendor/github.com/moby/go-archive/archive_other.go +++ b/vendor/github.com/moby/go-archive/archive_other.go @@ -2,6 +2,14 @@ package archive +func withProcSelfFD(opts *TarOptions) (*TarOptions, func(), error) { + var prepared TarOptions + if opts != nil { + prepared = *opts + } + return &prepared, func() {}, nil +} + func getWhiteoutConverter(format WhiteoutFormat) tarWhiteoutConverter { return nil } diff --git a/vendor/github.com/moby/go-archive/archive_unix.go b/vendor/github.com/moby/go-archive/archive_unix.go index 482ab69222a8..6b333e5b2ce0 100644 --- a/vendor/github.com/moby/go-archive/archive_unix.go +++ b/vendor/github.com/moby/go-archive/archive_unix.go @@ -12,6 +12,7 @@ import ( "strings" "syscall" + "github.com/moby/go-archive/internal/archiveoptions" "golang.org/x/sys/unix" ) @@ -87,7 +88,7 @@ func handleTarTypeBlockCharFifo(root *os.Root, hdr *tar.Header, dstPath string) // handleLChmod applies the mode from hdrInfo to dstPath within root, skipping // symlinks (there is no lchmod). For hardlinks, the mode is applied only when // the link target is itself not a symlink. -func handleLChmod(root *os.Root, dstPath string, hardlinkTarget string, hdr *tar.Header, hdrInfo os.FileInfo) error { +func handleLChmod(root *os.Root, dstPath string, hardlinkTarget string, hdr *tar.Header, hdrInfo os.FileInfo, opts *archiveoptions.Options) error { switch hdr.Typeflag { case tar.TypeSymlink: return nil @@ -99,17 +100,17 @@ func handleLChmod(root *os.Root, dstPath string, hardlinkTarget string, hdr *tar if err != nil || fi.Mode()&os.ModeSymlink != 0 { return nil } - return chmodNoSymlink(root, dstPath, hdrInfo.Mode()) + return chmodNoSymlink(root, dstPath, hdrInfo.Mode(), opts) default: - return chmodNoSymlink(root, dstPath, hdrInfo.Mode()) + return chmodNoSymlink(root, dstPath, hdrInfo.Mode(), opts) } } // chmodNoSymlink applies mode to a non-symlink entry. // // Callers must have already excluded symlink entries. -func chmodNoSymlink(root *os.Root, name string, mode os.FileMode) error { +func chmodNoSymlink(root *os.Root, name string, mode os.FileMode, opts *archiveoptions.Options) error { parent, err := root.OpenFile(filepath.Dir(name), os.O_RDONLY, 0) if err != nil { return err @@ -126,19 +127,7 @@ func chmodNoSymlink(root *os.Root, name string, mode os.FileMode) error { } // Fallback for systems that cannot perform fchmodat with AT_SYMLINK_NOFOLLOW. - // Open the entry without following symlinks and apply the mode through the - // resulting file descriptor. - // #nosec G115 -- ignore integer overflow conversion for parent.Fd - fd, err := unix.Openat(int(parent.Fd()), base, unix.O_RDONLY|unix.O_NOFOLLOW|unix.O_NONBLOCK, 0) - if err != nil { - return &os.PathError{Op: "openat", Path: name, Err: err} - } - defer unix.Close(fd) - - if err := unix.Fchmod(fd, perm); err != nil { - return &os.PathError{Op: "fchmod", Path: name, Err: err} - } - return nil + return chmodNoSymlinkFallback(int(parent.Fd()), base, name, perm, opts) // #nosec G115 -- ignore integer overflow conversion for parent.Fd } // fileModeToPerm returns the subset of an os.FileMode that can be applied diff --git a/vendor/github.com/moby/go-archive/archive_windows.go b/vendor/github.com/moby/go-archive/archive_windows.go index aa9e523abc95..a0e433633923 100644 --- a/vendor/github.com/moby/go-archive/archive_windows.go +++ b/vendor/github.com/moby/go-archive/archive_windows.go @@ -53,7 +53,7 @@ func handleTarTypeBlockCharFifo(root *os.Root, hdr *tar.Header, path string) err } // handleLChmod is a no-op on Windows because chmod is not supported. -func handleLChmod(root *os.Root, dstPath string, hardlinkTarget string, hdr *tar.Header, hdrInfo os.FileInfo) error { +func handleLChmod(root *os.Root, dstPath string, hardlinkTarget string, hdr *tar.Header, hdrInfo os.FileInfo, opts any) error { return nil } diff --git a/vendor/github.com/moby/go-archive/chmod_linux.go b/vendor/github.com/moby/go-archive/chmod_linux.go new file mode 100644 index 000000000000..8d92f594ad3f --- /dev/null +++ b/vendor/github.com/moby/go-archive/chmod_linux.go @@ -0,0 +1,46 @@ +package archive + +import ( + "fmt" + "os" + "runtime" + "strconv" + + "github.com/moby/go-archive/internal/archiveoptions" + "golang.org/x/sys/unix" +) + +// chmodNoSymlinkFallback applies mode without following the final path +// component on systems without fchmodat2 support. +// +// Callers must have already excluded symlink entries. +func chmodNoSymlinkFallback(parentFD int, base, name string, perm uint32, opts *archiveoptions.Options) error { + fd, err := unix.Openat(parentFD, base, unix.O_PATH|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) + if err != nil { + return &os.PathError{Op: "openat", Path: name, Err: err} + } + defer unix.Close(fd) + + if opts != nil && opts.ProcSelfFD != nil { + err := unix.Fchmodat(int(opts.ProcSelfFD.Fd()), strconv.Itoa(fd), perm, 0) + // Keep the os.File alive until fchmodat has finished using its descriptor. + runtime.KeepAlive(opts.ProcSelfFD) + if err != nil { + return &os.PathError{ + Op: "fchmodat", + Path: name, + Err: fmt.Errorf("via pre-opened /proc/self/fd/%d: %w", fd, err), + } + } + } else { + procPath := "/proc/self/fd/" + strconv.Itoa(fd) + if err := unix.Chmod(procPath, perm); err != nil { + return &os.PathError{ + Op: "chmod", + Path: name, + Err: fmt.Errorf("via %s: %w", procPath, err), + } + } + } + return nil +} diff --git a/vendor/github.com/moby/go-archive/chmod_unix_nolinux.go b/vendor/github.com/moby/go-archive/chmod_unix_nolinux.go new file mode 100644 index 000000000000..0acddb1b98f7 --- /dev/null +++ b/vendor/github.com/moby/go-archive/chmod_unix_nolinux.go @@ -0,0 +1,27 @@ +//go:build !linux && !windows + +package archive + +import ( + "os" + + "github.com/moby/go-archive/internal/archiveoptions" + "golang.org/x/sys/unix" +) + +// chmodNoSymlinkFallback applies mode without following the final path +// component on systems without fchmodat2 support. +// +// Callers must have already excluded symlink entries. +func chmodNoSymlinkFallback(parentFD int, base, name string, perm uint32, _ *archiveoptions.Options) error { + fd, err := unix.Openat(parentFD, base, unix.O_RDONLY|unix.O_NOFOLLOW|unix.O_NONBLOCK|unix.O_CLOEXEC, 0) + if err != nil { + return &os.PathError{Op: "openat", Path: name, Err: err} + } + defer unix.Close(fd) + + if err := unix.Fchmod(fd, perm); err != nil { + return &os.PathError{Op: "fchmod", Path: name, Err: err} + } + return nil +} diff --git a/vendor/github.com/moby/go-archive/internal/archiveoptions/options.go b/vendor/github.com/moby/go-archive/internal/archiveoptions/options.go new file mode 100644 index 000000000000..201eb91b6d0d --- /dev/null +++ b/vendor/github.com/moby/go-archive/internal/archiveoptions/options.go @@ -0,0 +1,12 @@ +// Package archiveoptions defines internal options shared between archive and +// chrootarchive. +package archiveoptions + +import "os" + +// Options contains extraction resources supplied by internal callers. +type Options struct { + // ProcSelfFD references /proc/self/fd as opened before entering a chroot. + // The caller retains ownership of the file. + ProcSelfFD *os.File +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 5ed81bbede08..82bd1c3b65ea 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -162,10 +162,11 @@ github.com/mattn/go-runewidth # github.com/moby/docker-image-spec v1.3.1 ## explicit; go 1.18 github.com/moby/docker-image-spec/specs-go/v1 -# github.com/moby/go-archive v0.3.2 +# github.com/moby/go-archive v0.3.3 ## explicit; go 1.25 github.com/moby/go-archive github.com/moby/go-archive/compression +github.com/moby/go-archive/internal/archiveoptions github.com/moby/go-archive/tarheader # github.com/moby/moby/api v1.55.0 ## explicit; go 1.24