From 84a5119d171cfef41d7869ee1ce46cc432e9cac3 Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Tue, 6 Aug 2024 17:51:12 +0200 Subject: [PATCH] vendor: update c/storage Signed-off-by: Giuseppe Scrivano --- go.mod | 2 +- go.sum | 4 +- vendor/github.com/containers/storage/VERSION | 2 +- .../storage/drivers/overlay/composefs.go | 91 +++++++++++++------ .../storage/drivers/overlay/overlay.go | 2 +- .../storage/pkg/chunked/filesystem_linux.go | 10 +- .../storage/pkg/idmap/idmapped_utils.go | 13 ++- vendor/modules.txt | 2 +- 8 files changed, 84 insertions(+), 42 deletions(-) diff --git a/go.mod b/go.mod index e42de6716d..27d1be1422 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/containers/libhvee v0.7.1 github.com/containers/ocicrypt v1.2.0 github.com/containers/psgo v1.9.0 - github.com/containers/storage v1.55.0 + github.com/containers/storage v1.55.1-0.20240806141512-6b538ae8e120 github.com/containers/winquit v1.1.0 github.com/coreos/go-systemd/v22 v22.5.1-0.20231103132048-7d375ecc2b09 github.com/coreos/stream-metadata-go v0.4.4 diff --git a/go.sum b/go.sum index 1be3f2c3f7..20473ca768 100644 --- a/go.sum +++ b/go.sum @@ -97,8 +97,8 @@ github.com/containers/ocicrypt v1.2.0 h1:X14EgRK3xNFvJEfI5O4Qn4T3E25ANudSOZz/sir github.com/containers/ocicrypt v1.2.0/go.mod h1:ZNviigQajtdlxIZGibvblVuIFBKIuUI2M0QM12SD31U= github.com/containers/psgo v1.9.0 h1:eJ74jzSaCHnWt26OlKZROSyUyRcGDf+gYBdXnxrMW4g= github.com/containers/psgo v1.9.0/go.mod h1:0YoluUm43Mz2UnBIh1P+6V6NWcbpTL5uRtXyOcH0B5A= -github.com/containers/storage v1.55.0 h1:wTWZ3YpcQf1F+dSP4KxG9iqDfpQY1otaUXjPpffuhgg= -github.com/containers/storage v1.55.0/go.mod h1:28cB81IDk+y7ok60Of6u52RbCeBRucbFOeLunhER1RQ= +github.com/containers/storage v1.55.1-0.20240806141512-6b538ae8e120 h1:mxwBgVVrXjJp4C8y3wB1LdCmbin6Dr1/Omb0EQ00dV0= +github.com/containers/storage v1.55.1-0.20240806141512-6b538ae8e120/go.mod h1:4iA5DfO4KcBPIe2Gaub12GM7nDIt1qM4zk03EV6lF/w= github.com/containers/winquit v1.1.0 h1:jArun04BNDQvt2W0Y78kh9TazN2EIEMG5Im6/JY7+pE= github.com/containers/winquit v1.1.0/go.mod h1:PsPeZlnbkmGGIToMPHF1zhWjBUkd8aHjMOr/vFcPxw8= github.com/coreos/go-oidc/v3 v3.10.0 h1:tDnXHnLyiTVyT/2zLDGj09pFPkhND8Gl8lnTRhoEaJU= diff --git a/vendor/github.com/containers/storage/VERSION b/vendor/github.com/containers/storage/VERSION index 094d6ad00c..31907770ac 100644 --- a/vendor/github.com/containers/storage/VERSION +++ b/vendor/github.com/containers/storage/VERSION @@ -1 +1 @@ -1.55.0 +1.56.0-dev diff --git a/vendor/github.com/containers/storage/drivers/overlay/composefs.go b/vendor/github.com/containers/storage/drivers/overlay/composefs.go index 973cd786c3..6f36ba3dda 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/composefs.go +++ b/vendor/github.com/containers/storage/drivers/overlay/composefs.go @@ -8,7 +8,6 @@ import ( "encoding/binary" "errors" "fmt" - "io/fs" "os" "os/exec" "path/filepath" @@ -55,29 +54,26 @@ func generateComposeFsBlob(verityDigests map[string]string, toc interface{}, com return fmt.Errorf("failed to find mkcomposefs: %w", err) } - fd, err := unix.Openat(unix.AT_FDCWD, destFile, unix.O_WRONLY|unix.O_CREAT|unix.O_TRUNC|unix.O_EXCL|unix.O_CLOEXEC, 0o644) + outFile, err := os.OpenFile(destFile, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o644) if err != nil { - return &fs.PathError{Op: "openat", Path: destFile, Err: err} + return err } - outFd := os.NewFile(uintptr(fd), "outFd") - fd, err = unix.Open(fmt.Sprintf("/proc/self/fd/%d", outFd.Fd()), unix.O_RDONLY|unix.O_CLOEXEC, 0) + roFile, err := os.Open(fmt.Sprintf("/proc/self/fd/%d", outFile.Fd())) if err != nil { - outFd.Close() - return fmt.Errorf("failed to dup output file: %w", err) + outFile.Close() + return fmt.Errorf("failed to reopen %s as read-only: %w", destFile, err) } - newFd := os.NewFile(uintptr(fd), "newFd") - defer newFd.Close() err = func() error { - // a scope to close outFd before setting fsverity on the read-only fd. - defer outFd.Close() + // a scope to close outFile before setting fsverity on the read-only fd. + defer outFile.Close() errBuf := &bytes.Buffer{} - cmd := exec.Command(writerJson, "--from-file", "-", "/proc/self/fd/3") - cmd.ExtraFiles = []*os.File{outFd} + cmd := exec.Command(writerJson, "--from-file", "-", "-") cmd.Stderr = errBuf cmd.Stdin = dumpReader + cmd.Stdout = outFile if err := cmd.Run(); err != nil { rErr := fmt.Errorf("failed to convert json to erofs: %w", err) exitErr := &exec.ExitError{} @@ -92,7 +88,7 @@ func generateComposeFsBlob(verityDigests map[string]string, toc interface{}, com return err } - if err := fsverity.EnableVerity("manifest file", int(newFd.Fd())); err != nil && !errors.Is(err, unix.ENOTSUP) && !errors.Is(err, unix.ENOTTY) { + if err := fsverity.EnableVerity("manifest file", int(roFile.Fd())); err != nil && !errors.Is(err, unix.ENOTSUP) && !errors.Is(err, unix.ENOTTY) { logrus.Warningf("%s", err) } @@ -114,23 +110,30 @@ struct lcfs_erofs_header_s { // hasACL returns true if the erofs blob has ACLs enabled func hasACL(path string) (bool, error) { - const LCFS_EROFS_FLAGS_HAS_ACL = (1 << 0) + const ( + LCFS_EROFS_FLAGS_HAS_ACL = (1 << 0) + versionNumberSize = 4 + magicNumberSize = 4 + flagsSize = 4 + ) - fd, err := unix.Openat(unix.AT_FDCWD, path, unix.O_RDONLY|unix.O_CLOEXEC, 0) + file, err := os.Open(path) if err != nil { - return false, &fs.PathError{Op: "openat", Path: path, Err: err} + return false, err } - defer unix.Close(fd) + defer file.Close() + // do not worry about checking the magic number, if the file is invalid // we will fail to mount it anyway - flags := make([]byte, 4) - nread, err := unix.Pread(fd, flags, 8) + buffer := make([]byte, versionNumberSize+magicNumberSize+flagsSize) + nread, err := file.Read(buffer) if err != nil { - return false, fmt.Errorf("pread %q: %w", path, err) + return false, err } - if nread != 4 { + if nread != len(buffer) { return false, fmt.Errorf("failed to read flags from %q", path) } + flags := buffer[versionNumberSize+magicNumberSize:] return binary.LittleEndian.Uint32(flags)&LCFS_EROFS_FLAGS_HAS_ACL != 0, nil } @@ -146,13 +149,47 @@ func mountComposefsBlob(dataDir, mountPoint string) error { if err != nil { return err } - mountOpts := "ro" - if !hasACL { - mountOpts += ",noacl" + + fsfd, err := unix.Fsopen("erofs", 0) + if err != nil { + return fmt.Errorf("failed to open erofs filesystem: %w", err) + } + defer unix.Close(fsfd) + + if err := unix.FsconfigSetString(fsfd, "source", loop.Name()); err != nil { + return fmt.Errorf("failed to set source for erofs filesystem: %w", err) } - if err := unix.Mount(loop.Name(), mountPoint, "erofs", unix.MS_RDONLY, mountOpts); err != nil { - return fmt.Errorf("failed to mount erofs image at %q: %w", mountPoint, err) + if err := unix.FsconfigSetFlag(fsfd, "ro"); err != nil { + return fmt.Errorf("failed to set erofs filesystem read-only: %w", err) + } + + if !hasACL { + if err := unix.FsconfigSetFlag(fsfd, "noacl"); err != nil { + return fmt.Errorf("failed to set noacl for erofs filesystem: %w", err) + } + } + + if err := unix.FsconfigCreate(fsfd); err != nil { + buffer := make([]byte, 4096) + if n, _ := unix.Read(fsfd, buffer); n > 0 { + return fmt.Errorf("failed to create erofs filesystem: %s: %w", string(buffer[:n]), err) + } + return fmt.Errorf("failed to create erofs filesystem: %w", err) + } + + mfd, err := unix.Fsmount(fsfd, 0, unix.MOUNT_ATTR_RDONLY) + if err != nil { + buffer := make([]byte, 4096) + if n, _ := unix.Read(fsfd, buffer); n > 0 { + return fmt.Errorf("failed to mount erofs filesystem: %s: %w", string(buffer[:n]), err) + } + return fmt.Errorf("failed to mount erofs filesystem: %w", err) + } + defer unix.Close(mfd) + + if err := unix.MoveMount(mfd, "", unix.AT_FDCWD, mountPoint, unix.MOVE_MOUNT_F_EMPTY_PATH); err != nil { + return fmt.Errorf("failed to move mount: %w", err) } return nil } diff --git a/vendor/github.com/containers/storage/drivers/overlay/overlay.go b/vendor/github.com/containers/storage/drivers/overlay/overlay.go index 8ed35745f6..b95af8a0cc 100644 --- a/vendor/github.com/containers/storage/drivers/overlay/overlay.go +++ b/vendor/github.com/containers/storage/drivers/overlay/overlay.go @@ -1934,7 +1934,7 @@ func (d *Driver) Put(id string) error { // If fusermount|fusermount3 failed to unmount the FUSE file system, make sure all // pending changes are propagated to the file system if !unmounted { - fd, err := unix.Open(mountpoint, unix.O_DIRECTORY, 0) + fd, err := unix.Open(mountpoint, unix.O_DIRECTORY|unix.O_CLOEXEC, 0) if err == nil { if err := unix.Syncfs(fd); err != nil { logrus.Debugf("Error Syncfs(%s) - %v", mountpoint, err) diff --git a/vendor/github.com/containers/storage/pkg/chunked/filesystem_linux.go b/vendor/github.com/containers/storage/pkg/chunked/filesystem_linux.go index 4fc4864a28..e26e5e5c55 100644 --- a/vendor/github.com/containers/storage/pkg/chunked/filesystem_linux.go +++ b/vendor/github.com/containers/storage/pkg/chunked/filesystem_linux.go @@ -174,7 +174,7 @@ func setFileAttrs(dirfd int, file *os.File, mode os.FileMode, metadata *fileMeta if usePath { dirName := filepath.Dir(metadata.Name) if dirName != "" { - parentFd, err := openFileUnderRoot(dirfd, dirName, unix.O_PATH|unix.O_DIRECTORY, 0) + parentFd, err := openFileUnderRoot(dirfd, dirName, unix.O_PATH|unix.O_DIRECTORY|unix.O_CLOEXEC, 0) if err != nil { return err } @@ -402,7 +402,7 @@ func openFileUnderRoot(dirfd int, name string, flags uint64, mode os.FileMode) ( // name is the path to open relative to dirfd. // mode specifies the mode to use for newly created files. func openOrCreateDirUnderRoot(dirfd int, name string, mode os.FileMode) (*os.File, error) { - fd, err := openFileUnderRootRaw(dirfd, name, unix.O_DIRECTORY|unix.O_RDONLY, 0) + fd, err := openFileUnderRootRaw(dirfd, name, unix.O_DIRECTORY|unix.O_RDONLY|unix.O_CLOEXEC, 0) if err == nil { return os.NewFile(uintptr(fd), name), nil } @@ -422,7 +422,7 @@ func openOrCreateDirUnderRoot(dirfd int, name string, mode os.FileMode) (*os.Fil return nil, &fs.PathError{Op: "mkdirat", Path: name, Err: err2} } - fd, err = openFileUnderRootRaw(int(pDir.Fd()), baseName, unix.O_DIRECTORY|unix.O_RDONLY, 0) + fd, err = openFileUnderRootRaw(int(pDir.Fd()), baseName, unix.O_DIRECTORY|unix.O_RDONLY|unix.O_CLOEXEC, 0) if err == nil { return os.NewFile(uintptr(fd), name), nil } @@ -465,7 +465,7 @@ func safeMkdir(dirfd int, mode os.FileMode, name string, metadata *fileMetadata, } } - file, err := openFileUnderRoot(parentFd, base, unix.O_DIRECTORY|unix.O_RDONLY, 0) + file, err := openFileUnderRoot(parentFd, base, unix.O_DIRECTORY|unix.O_RDONLY|unix.O_CLOEXEC, 0) if err != nil { return err } @@ -475,7 +475,7 @@ func safeMkdir(dirfd int, mode os.FileMode, name string, metadata *fileMetadata, } func safeLink(dirfd int, mode os.FileMode, metadata *fileMetadata, options *archive.TarOptions) error { - sourceFile, err := openFileUnderRoot(dirfd, metadata.Linkname, unix.O_PATH|unix.O_RDONLY|unix.O_NOFOLLOW, 0) + sourceFile, err := openFileUnderRoot(dirfd, metadata.Linkname, unix.O_PATH|unix.O_RDONLY|unix.O_NOFOLLOW|unix.O_CLOEXEC, 0) if err != nil { return err } diff --git a/vendor/github.com/containers/storage/pkg/idmap/idmapped_utils.go b/vendor/github.com/containers/storage/pkg/idmap/idmapped_utils.go index 35b93e6263..21590a4e6e 100644 --- a/vendor/github.com/containers/storage/pkg/idmap/idmapped_utils.go +++ b/vendor/github.com/containers/storage/pkg/idmap/idmapped_utils.go @@ -4,7 +4,9 @@ package idmap import ( + "errors" "fmt" + "io/fs" "os" "runtime" "syscall" @@ -26,7 +28,7 @@ func CreateIDMappedMount(source, target string, pid int) error { targetDirFd, err := unix.OpenTree(0, source, unix.OPEN_TREE_CLONE) if err != nil { - return err + return &os.PathError{Op: "open_tree", Path: source, Err: err} } defer unix.Close(targetDirFd) @@ -35,13 +37,16 @@ func CreateIDMappedMount(source, target string, pid int) error { Attr_set: unix.MOUNT_ATTR_IDMAP, Userns_fd: uint64(userNsFile.Fd()), }); err != nil { - return err + return &os.PathError{Op: "mount_setattr", Path: source, Err: err} } - if err := os.Mkdir(target, 0o700); err != nil && !os.IsExist(err) { + if err := os.Mkdir(target, 0o700); err != nil && !errors.Is(err, fs.ErrExist) { return err } - return unix.MoveMount(targetDirFd, "", 0, target, unix.MOVE_MOUNT_F_EMPTY_PATH) + if err := unix.MoveMount(targetDirFd, "", 0, target, unix.MOVE_MOUNT_F_EMPTY_PATH); err != nil { + return &os.PathError{Op: "move_mount", Path: target, Err: err} + } + return nil } // CreateUsernsProcess forks the current process and creates a user namespace using the specified diff --git a/vendor/modules.txt b/vendor/modules.txt index d20dd10a2d..2095bdc234 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -354,7 +354,7 @@ github.com/containers/psgo/internal/dev github.com/containers/psgo/internal/host github.com/containers/psgo/internal/proc github.com/containers/psgo/internal/process -# github.com/containers/storage v1.55.0 +# github.com/containers/storage v1.55.1-0.20240806141512-6b538ae8e120 ## explicit; go 1.21 github.com/containers/storage github.com/containers/storage/drivers