Update archive to use its own xattr funcs

Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
Derek McGowan
2024-12-11 16:26:55 -08:00
parent 1b4cbea3a8
commit 35b9525f9a
9 changed files with 84 additions and 15 deletions

View File

@@ -26,7 +26,6 @@ import (
"github.com/containerd/log"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/pools"
"github.com/docker/docker/pkg/system"
"github.com/klauspost/compress/zstd"
"github.com/moby/patternmatcher"
"github.com/moby/sys/sequential"
@@ -507,7 +506,7 @@ func ReadSecurityXattrToTarHeader(path string, hdr *tar.Header) error {
vfsCapRevision2 = 2
vfsCapRevision3 = 3
)
capability, _ := system.Lgetxattr(path, "security.capability")
capability, _ := lgetxattr(path, "security.capability")
if capability != nil {
if capability[versionOffset] == vfsCapRevision3 {
// Convert VFS_CAP_REVISION_3 to VFS_CAP_REVISION_2 as root UID makes no
@@ -799,7 +798,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, o
if !ok {
continue
}
if err := system.Lsetxattr(path, xattr, []byte(value), 0); err != nil {
if err := lsetxattr(path, xattr, []byte(value), 0); err != nil {
if bestEffortXattrs && errors.Is(err, syscall.ENOTSUP) || errors.Is(err, syscall.EPERM) {
// EPERM occurs if modifying xattrs is not allowed. This can
// happen when running in userns with restrictions (ChromeOS).
@@ -1346,7 +1345,7 @@ func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
dst = filepath.Join(dst, filepath.Base(src))
}
// Create the holding directory if necessary
if err := system.MkdirAll(filepath.Dir(dst), 0o700); err != nil {
if err := os.MkdirAll(filepath.Dir(dst), 0o700); err != nil {
return err
}

View File

@@ -7,7 +7,6 @@ import (
"path/filepath"
"strings"
"github.com/docker/docker/pkg/system"
"github.com/moby/sys/userns"
"golang.org/x/sys/unix"
)
@@ -39,7 +38,7 @@ func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os
}
// convert opaque dirs to AUFS format by writing an empty file with the prefix
opaque, err := system.Lgetxattr(path, opaqueXattrName)
opaque, err := lgetxattr(path, opaqueXattrName)
if err != nil {
return nil, err
}

View File

@@ -35,7 +35,7 @@ func setupOverlayTestDir(t *testing.T, src string) {
err := os.Mkdir(filepath.Join(src, "d1"), 0o700)
assert.NilError(t, err)
err = system.Lsetxattr(filepath.Join(src, "d1"), "trusted.overlay.opaque", []byte("y"), 0)
err = unix.Lsetxattr(filepath.Join(src, "d1"), "trusted.overlay.opaque", []byte("y"), 0)
assert.NilError(t, err)
err = os.WriteFile(filepath.Join(src, "d1", "f1"), []byte{}, 0o600)
@@ -45,7 +45,7 @@ func setupOverlayTestDir(t *testing.T, src string) {
err = os.Mkdir(filepath.Join(src, "d2"), 0o750)
assert.NilError(t, err)
err = system.Lsetxattr(filepath.Join(src, "d2"), "trusted.overlay.opaque", []byte("y"), 0)
err = unix.Lsetxattr(filepath.Join(src, "d2"), "trusted.overlay.opaque", []byte("y"), 0)
assert.NilError(t, err)
err = os.WriteFile(filepath.Join(src, "d2", "f1"), []byte{}, 0o660)
@@ -60,7 +60,7 @@ func setupOverlayTestDir(t *testing.T, src string) {
}
func checkOpaqueness(t *testing.T, path string, opaque string) {
xattrOpaque, err := system.Lgetxattr(path, "trusted.overlay.opaque")
xattrOpaque, err := lgetxattr(path, "trusted.overlay.opaque")
assert.NilError(t, err)
if string(xattrOpaque) != opaque {

View File

@@ -79,7 +79,7 @@ func walkchunk(path string, fi os.FileInfo, dir string, root *FileInfo) error {
return err
}
info.stat = stat
info.capability, _ = system.Lgetxattr(cpath, "security.capability") // lgetxattr(2): fs access
info.capability, _ = lgetxattr(cpath, "security.capability") // lgetxattr(2): fs access
parent.children[info.name] = info
return nil
}

View File

@@ -84,11 +84,7 @@ func collectFileInfo(sourceDir string) (*FileInfo, error) {
stat: s,
}
// system.Lgetxattr is only implemented on Linux and produces an error
// on other platforms. This code is intentionally left commented-out
// as a reminder to include this code if this would ever be implemented
// on other platforms.
// info.capability, _ = system.Lgetxattr(path, "security.capability")
info.capability, _ = lgetxattr(path, "security.capability")
parent.children[info.name] = info

View File

@@ -0,0 +1,52 @@
//go:build linux || darwin || freebsd || netbsd
package archive // import "github.com/docker/docker/pkg/archive"
import (
"errors"
"fmt"
"io/fs"
"golang.org/x/sys/unix"
)
// lgetxattr retrieves the value of the extended attribute identified by attr
// and associated with the given path in the file system.
// It returns a nil slice and nil error if the xattr is not set.
func lgetxattr(path string, attr string) ([]byte, error) {
// Start with a 128 length byte array
dest := make([]byte, 128)
sz, err := unix.Lgetxattr(path, attr, dest)
for errors.Is(err, unix.ERANGE) {
// Buffer too small, use zero-sized buffer to get the actual size
sz, err = unix.Lgetxattr(path, attr, []byte{})
if err != nil {
return nil, wrapPathError("lgetxattr", path, attr, err)
}
dest = make([]byte, sz)
sz, err = unix.Lgetxattr(path, attr, dest)
}
if err != nil {
if errors.Is(err, noattr) {
return nil, nil
}
return nil, wrapPathError("lgetxattr", path, attr, err)
}
return dest[:sz], nil
}
// lsetxattr sets the value of the extended attribute identified by attr
// and associated with the given path in the file system.
func lsetxattr(path string, attr string, data []byte, flags int) error {
return wrapPathError("lsetxattr", path, attr, unix.Lsetxattr(path, attr, data, flags))
}
func wrapPathError(op, path, attr string, err error) error {
if err == nil {
return nil
}
return &fs.PathError{Op: op, Path: path, Err: fmt.Errorf("xattr %q: %w", attr, err)}
}

View File

@@ -0,0 +1,5 @@
package archive // import "github.com/docker/docker/pkg/archive"
import "golang.org/x/sys/unix"
var noattr = unix.ENODATA

View File

@@ -0,0 +1,7 @@
//go:build !linux && !windows
package archive // import "github.com/docker/docker/pkg/archive"
import "golang.org/x/sys/unix"
var noattr = unix.ENOATTR

View File

@@ -0,0 +1,11 @@
//go:build !linux && !darwin && !freebsd && !netbsd
package archive // import "github.com/docker/docker/pkg/archive"
func lgetxattr(path string, attr string) ([]byte, error) {
return nil, nil
}
func lsetxattr(path string, attr string, data []byte, flags int) error {
return nil
}