summaryrefslogtreecommitdiff
path: root/vendor/github.com/opencontainers/selinux
diff options
context:
space:
mode:
authordependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com>2020-03-12 09:17:29 +0000
committerDaniel J Walsh <dwalsh@redhat.com>2020-03-12 10:37:32 -0400
commit925da74118697702092b24ff115b64258643f81c (patch)
tree2dbd785a38e57f3212734f9e5cf303b6edd1d11d /vendor/github.com/opencontainers/selinux
parent78e090092b38ab52993a3eec6d9bab0eabeaa1fc (diff)
downloadpodman-925da74118697702092b24ff115b64258643f81c.tar.gz
podman-925da74118697702092b24ff115b64258643f81c.tar.bz2
podman-925da74118697702092b24ff115b64258643f81c.zip
Bump github.com/containers/storage from 1.16.2 to 1.16.3
Bumps [github.com/containers/storage](https://github.com/containers/storage) from 1.16.2 to 1.16.3. - [Release notes](https://github.com/containers/storage/releases) - [Changelog](https://github.com/containers/storage/blob/master/docs/containers-storage-changes.md) - [Commits](https://github.com/containers/storage/compare/v1.16.2...v1.16.3) Signed-off-by: dependabot-preview[bot] <support@dependabot.com> Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Diffstat (limited to 'vendor/github.com/opencontainers/selinux')
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label.go134
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go122
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go54
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go78
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go14
-rw-r--r--vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go8
-rw-r--r--vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md42
-rw-r--r--vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go99
8 files changed, 333 insertions, 218 deletions
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
index e178568fd..6e38d3d32 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
@@ -1,109 +1,77 @@
-// +build !selinux !linux
-
package label
-// InitLabels returns the process label and file labels to be used within
-// the container. A list of options can be passed into this function to alter
-// the labels.
-func InitLabels(options []string) (string, string, error) {
- return "", "", nil
-}
-
-func ROMountLabel() string {
- return ""
-}
-
-func GenLabels(options string) (string, string, error) {
- return "", "", nil
-}
+import (
+ "github.com/opencontainers/selinux/go-selinux"
+)
-func FormatMountLabel(src string, mountLabel string) string {
- return src
-}
+// Deprecated: use selinux.ROFileLabel
+var ROMountLabel = selinux.ROFileLabel
-func SetProcessLabel(processLabel string) error {
- return nil
-}
+// SetProcessLabel takes a process label and tells the kernel to assign the
+// label to the next program executed by the current process.
+// Deprecated: use selinux.SetExecLabel
+var SetProcessLabel = selinux.SetExecLabel
-func ProcessLabel() (string, error) {
- return "", nil
-}
+// ProcessLabel returns the process label that the kernel will assign
+// to the next program executed by the current process. If "" is returned
+// this indicates that the default labeling will happen for the process.
+// Deprecated: use selinux.ExecLabel
+var ProcessLabel = selinux.ExecLabel
-func SetSocketLabel(processLabel string) error {
- return nil
-}
+// SetSocketLabel takes a process label and tells the kernel to assign the
+// label to the next socket that gets created
+// Deprecated: use selinux.SetSocketLabel
+var SetSocketLabel = selinux.SetSocketLabel
-func SocketLabel() (string, error) {
- return "", nil
-}
+// SocketLabel retrieves the current default socket label setting
+// Deprecated: use selinux.SocketLabel
+var SocketLabel = selinux.SocketLabel
-func SetKeyLabel(processLabel string) error {
- return nil
-}
+// SetKeyLabel takes a process label and tells the kernel to assign the
+// label to the next kernel keyring that gets created
+// Deprecated: use selinux.SetKeyLabel
+var SetKeyLabel = selinux.SetKeyLabel
-func KeyLabel() (string, error) {
- return "", nil
-}
+// KeyLabel retrieves the current default kernel keyring label setting
+// Deprecated: use selinux.KeyLabel
+var KeyLabel = selinux.KeyLabel
-func FileLabel(path string) (string, error) {
- return "", nil
-}
+// FileLabel returns the label for specified path
+// Deprecated: use selinux.FileLabel
+var FileLabel = selinux.FileLabel
-func SetFileLabel(path string, fileLabel string) error {
- return nil
-}
-
-func SetFileCreateLabel(fileLabel string) error {
- return nil
-}
-
-func Relabel(path string, fileLabel string, shared bool) error {
- return nil
-}
-
-func PidLabel(pid int) (string, error) {
- return "", nil
-}
+// PidLabel will return the label of the process running with the specified pid
+// Deprecated: use selinux.PidLabel
+var PidLabel = selinux.PidLabel
+// Init initialises the labeling system
func Init() {
+ selinux.GetEnabled()
}
-// ClearLabels clears all reserved labels
-func ClearLabels() {
- return
-}
+// ClearLabels will clear all reserved labels
+// Deprecated: use selinux.ClearLabels
+var ClearLabels = selinux.ClearLabels
+// ReserveLabel will record the fact that the MCS label has already been used.
+// This will prevent InitLabels from using the MCS label in a newly created
+// container
+// Deprecated: use selinux.ReserveLabel
func ReserveLabel(label string) error {
+ selinux.ReserveLabel(label)
return nil
}
+// ReleaseLabel will remove the reservation of the MCS label.
+// This will allow InitLabels to use the MCS label in a newly created
+// containers
+// Deprecated: use selinux.ReleaseLabel
func ReleaseLabel(label string) error {
+ selinux.ReleaseLabel(label)
return nil
}
// DupSecOpt takes a process label and returns security options that
// can be used to set duplicate labels on future container processes
-func DupSecOpt(src string) ([]string, error) {
- return nil, nil
-}
-
-// DisableSecOpt returns a security opt that can disable labeling
-// support for future container processes
-func DisableSecOpt() []string {
- return nil
-}
-
-// Validate checks that the label does not include unexpected options
-func Validate(label string) error {
- return nil
-}
-
-// RelabelNeeded checks whether the user requested a relabel
-func RelabelNeeded(label string) bool {
- return false
-}
-
-// IsShared checks that the label includes a "shared" mark
-func IsShared(label string) bool {
- return false
-}
+// Deprecated: use selinux.DupSecOpt
+var DupSecOpt = selinux.DupSecOpt
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
index 2730fcf4a..903829958 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go
@@ -9,6 +9,7 @@ import (
"strings"
"github.com/opencontainers/selinux/go-selinux"
+ "github.com/pkg/errors"
)
// Valid Label Options
@@ -21,7 +22,7 @@ var validOptions = map[string]bool{
"level": true,
}
-var ErrIncompatibleLabel = fmt.Errorf("Bad SELinux option z and Z can not be used together")
+var ErrIncompatibleLabel = errors.New("Bad SELinux option z and Z can not be used together")
// InitLabels returns the process label and file labels to be used within
// the container. A list of options can be passed into this function to alter
@@ -35,7 +36,7 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
if processLabel != "" {
defer func() {
if Err != nil {
- ReleaseLabel(mountLabel)
+ selinux.ReleaseLabel(mountLabel)
}
}()
pcon, err := selinux.NewContext(processLabel)
@@ -52,11 +53,11 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
return "", mountLabel, nil
}
if i := strings.Index(opt, ":"); i == -1 {
- return "", "", fmt.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt)
+ return "", "", errors.Errorf("Bad label option %q, valid options 'disable' or \n'user, role, level, type, filetype' followed by ':' and a value", opt)
}
con := strings.SplitN(opt, ":", 2)
if !validOptions[con[0]] {
- return "", "", fmt.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0])
+ return "", "", errors.Errorf("Bad label option %q, valid options 'disable, user, role, level, type, filetype'", con[0])
}
if con[0] == "filetype" {
@@ -67,19 +68,16 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
mcon[con[0]] = con[1]
}
}
- _ = ReleaseLabel(processLabel)
+ selinux.ReleaseLabel(processLabel)
processLabel = pcon.Get()
mountLabel = mcon.Get()
- _ = ReserveLabel(processLabel)
+ selinux.ReserveLabel(processLabel)
}
return processLabel, mountLabel, nil
}
-func ROMountLabel() string {
- return selinux.ROFileLabel()
-}
-
-// DEPRECATED: The GenLabels function is only to be used during the transition to the official API.
+// Deprecated: The GenLabels function is only to be used during the transition
+// to the official API. Use InitLabels(strings.Fields(options)) instead.
func GenLabels(options string) (string, string, error) {
return InitLabels(strings.Fields(options))
}
@@ -102,71 +100,27 @@ func FormatMountLabel(src, mountLabel string) string {
return src
}
-// SetProcessLabel takes a process label and tells the kernel to assign the
-// label to the next program executed by the current process.
-func SetProcessLabel(processLabel string) error {
- return selinux.SetExecLabel(processLabel)
-}
-
-// SetSocketLabel takes a process label and tells the kernel to assign the
-// label to the next socket that gets created
-func SetSocketLabel(processLabel string) error {
- return selinux.SetSocketLabel(processLabel)
-}
-
-// SocketLabel retrieves the current default socket label setting
-func SocketLabel() (string, error) {
- return selinux.SocketLabel()
-}
-
-// SetKeyLabel takes a process label and tells the kernel to assign the
-// label to the next kernel keyring that gets created
-func SetKeyLabel(processLabel string) error {
- return selinux.SetKeyLabel(processLabel)
-}
-
-// KeyLabel retrieves the current default kernel keyring label setting
-func KeyLabel() (string, error) {
- return selinux.KeyLabel()
-}
-
-// ProcessLabel returns the process label that the kernel will assign
-// to the next program executed by the current process. If "" is returned
-// this indicates that the default labeling will happen for the process.
-func ProcessLabel() (string, error) {
- return selinux.ExecLabel()
-}
-
-// FileLabel returns the label for specified path
-func FileLabel(path string) (string, error) {
- return selinux.FileLabel(path)
-}
-
// SetFileLabel modifies the "path" label to the specified file label
func SetFileLabel(path string, fileLabel string) error {
- if selinux.GetEnabled() && fileLabel != "" {
- return selinux.SetFileLabel(path, fileLabel)
+ if !selinux.GetEnabled() || fileLabel == "" {
+ return nil
}
- return nil
+ return selinux.SetFileLabel(path, fileLabel)
}
// SetFileCreateLabel tells the kernel the label for all files to be created
func SetFileCreateLabel(fileLabel string) error {
- if selinux.GetEnabled() {
- return selinux.SetFSCreateLabel(fileLabel)
+ if !selinux.GetEnabled() {
+ return nil
}
- return nil
+ return selinux.SetFSCreateLabel(fileLabel)
}
// Relabel changes the label of path to the filelabel string.
// It changes the MCS label to s0 if shared is true.
// This will allow all containers to share the content.
func Relabel(path string, fileLabel string, shared bool) error {
- if !selinux.GetEnabled() {
- return nil
- }
-
- if fileLabel == "" {
+ if !selinux.GetEnabled() || fileLabel == "" {
return nil
}
@@ -211,7 +165,7 @@ func Relabel(path string, fileLabel string, shared bool) error {
path = strings.TrimSuffix(path, "/")
}
if exclude_paths[path] {
- return fmt.Errorf("SELinux relabeling of %s is not allowed", path)
+ return errors.Errorf("SELinux relabeling of %s is not allowed", path)
}
if shared {
@@ -229,48 +183,10 @@ func Relabel(path string, fileLabel string, shared bool) error {
return nil
}
-// PidLabel will return the label of the process running with the specified pid
-func PidLabel(pid int) (string, error) {
- return selinux.PidLabel(pid)
-}
-
-// Init initialises the labeling system
-func Init() {
- selinux.GetEnabled()
-}
-
-// ClearLabels will clear all reserved labels
-func ClearLabels() {
- selinux.ClearLabels()
-}
-
-// ReserveLabel will record the fact that the MCS label has already been used.
-// This will prevent InitLabels from using the MCS label in a newly created
-// container
-func ReserveLabel(label string) error {
- selinux.ReserveLabel(label)
- return nil
-}
-
-// ReleaseLabel will remove the reservation of the MCS label.
-// This will allow InitLabels to use the MCS label in a newly created
-// containers
-func ReleaseLabel(label string) error {
- selinux.ReleaseLabel(label)
- return nil
-}
-
-// DupSecOpt takes a process label and returns security options that
-// can be used to set duplicate labels on future container processes
-func DupSecOpt(src string) ([]string, error) {
- return selinux.DupSecOpt(src)
-}
-
// DisableSecOpt returns a security opt that can disable labeling
// support for future container processes
-func DisableSecOpt() []string {
- return selinux.DisableSecOpt()
-}
+// Deprecated: use selinux.DisableSecOpt
+var DisableSecOpt = selinux.DisableSecOpt
// Validate checks that the label does not include unexpected options
func Validate(label string) error {
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go
new file mode 100644
index 000000000..cda59d671
--- /dev/null
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_stub.go
@@ -0,0 +1,54 @@
+// +build !selinux !linux
+
+package label
+
+// InitLabels returns the process label and file labels to be used within
+// the container. A list of options can be passed into this function to alter
+// the labels.
+func InitLabels(options []string) (string, string, error) {
+ return "", "", nil
+}
+
+// Deprecated: The GenLabels function is only to be used during the transition
+// to the official API. Use InitLabels(strings.Fields(options)) instead.
+func GenLabels(options string) (string, string, error) {
+ return "", "", nil
+}
+
+func FormatMountLabel(src string, mountLabel string) string {
+ return src
+}
+
+func SetFileLabel(path string, fileLabel string) error {
+ return nil
+}
+
+func SetFileCreateLabel(fileLabel string) error {
+ return nil
+}
+
+func Relabel(path string, fileLabel string, shared bool) error {
+ return nil
+}
+
+// DisableSecOpt returns a security opt that can disable labeling
+// support for future container processes
+func DisableSecOpt() []string {
+ // TODO the selinux.DisableSecOpt stub returns []string{"disable"} instead of "nil"
+ return nil
+}
+
+// Validate checks that the label does not include unexpected options
+func Validate(label string) error {
+ return nil
+}
+
+// RelabelNeeded checks whether the user requested a relabel
+func RelabelNeeded(label string) bool {
+ return false
+}
+
+// IsShared checks that the label includes a "shared" mark
+func IsShared(label string) bool {
+ return false
+}
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
index c51ddfda2..599bdb6e2 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_linux.go
@@ -17,8 +17,8 @@ import (
"strconv"
"strings"
"sync"
- "syscall"
+ "github.com/opencontainers/selinux/pkg/pwalk"
"github.com/pkg/errors"
"golang.org/x/sys/unix"
)
@@ -37,7 +37,6 @@ const (
selinuxTypeTag = "SELINUXTYPE"
selinuxTag = "SELINUX"
xattrNameSelinux = "security.selinux"
- stRdOnly = 0x01
)
type selinuxState struct {
@@ -103,13 +102,13 @@ func SetDisabled() {
}
func verifySELinuxfsMount(mnt string) bool {
- var buf syscall.Statfs_t
+ var buf unix.Statfs_t
for {
- err := syscall.Statfs(mnt, &buf)
+ err := unix.Statfs(mnt, &buf)
if err == nil {
break
}
- if err == syscall.EAGAIN {
+ if err == unix.EAGAIN {
continue
}
return false
@@ -118,7 +117,7 @@ func verifySELinuxfsMount(mnt string) bool {
if uint32(buf.Type) != uint32(unix.SELINUX_MAGIC) {
return false
}
- if (buf.Flags & stRdOnly) != 0 {
+ if (buf.Flags & unix.ST_RDONLY) != 0 {
return false
}
@@ -251,10 +250,10 @@ func isProcHandle(fh *os.File) error {
var buf unix.Statfs_t
err := unix.Fstatfs(int(fh.Fd()), &buf)
if err != nil {
- return fmt.Errorf("statfs(%q) failed: %v", fh.Name(), err)
+ return errors.Wrapf(err, "statfs(%q) failed", fh.Name())
}
if buf.Type != unix.PROC_SUPER_MAGIC {
- return fmt.Errorf("file %q is not on procfs", fh.Name())
+ return errors.Errorf("file %q is not on procfs", fh.Name())
}
return nil
@@ -282,12 +281,29 @@ func readCon(fpath string) (string, error) {
return strings.Trim(retval, "\x00"), nil
}
+// ClassIndex returns the int index for an object class in the loaded policy, or -1 and an error
+func ClassIndex(class string) (int, error) {
+ permpath := fmt.Sprintf("class/%s/index", class)
+ indexpath := filepath.Join(getSelinuxMountPoint(), permpath)
+
+ indexB, err := ioutil.ReadFile(indexpath)
+ if err != nil {
+ return -1, err
+ }
+ index, err := strconv.Atoi(string(indexB))
+ if err != nil {
+ return -1, err
+ }
+
+ return index, nil
+}
+
// SetFileLabel sets the SELinux label for this path or returns an error.
func SetFileLabel(fpath string, label string) error {
if fpath == "" {
return ErrEmptyPath
}
- if err := lsetxattr(fpath, xattrNameSelinux, []byte(label), 0); err != nil {
+ if err := unix.Lsetxattr(fpath, xattrNameSelinux, []byte(label), 0); err != nil {
return errors.Wrapf(err, "failed to set file label on %s", fpath)
}
return nil
@@ -390,7 +406,7 @@ func attrPath(attr string) string {
return path.Join(threadSelfPrefix, attr)
}
- return path.Join("/proc/self/task/", strconv.Itoa(syscall.Gettid()), "/attr/", attr)
+ return path.Join("/proc/self/task/", strconv.Itoa(unix.Gettid()), "/attr/", attr)
}
func readAttr(attr string) (string, error) {
@@ -410,6 +426,18 @@ func CanonicalizeContext(val string) (string, error) {
return readWriteCon(filepath.Join(getSelinuxMountPoint(), "context"), val)
}
+/*
+ComputeCreateContext requests the type transition from source to target for class from the kernel.
+*/
+func ComputeCreateContext(source string, target string, class string) (string, error) {
+ classidx, err := ClassIndex(class)
+ if err != nil {
+ return "", err
+ }
+
+ return readWriteCon(filepath.Join(getSelinuxMountPoint(), "create"), fmt.Sprintf("%s %s %d", source, target, classidx))
+}
+
func readWriteCon(fpath string, val string) (string, error) {
if fpath == "" {
return "", ErrEmptyPath
@@ -461,17 +489,17 @@ func SocketLabel() (string, error) {
// PeerLabel retrieves the label of the client on the other side of a socket
func PeerLabel(fd uintptr) (string, error) {
- return unix.GetsockoptString(int(fd), syscall.SOL_SOCKET, syscall.SO_PEERSEC)
+ return unix.GetsockoptString(int(fd), unix.SOL_SOCKET, unix.SO_PEERSEC)
}
// SetKeyLabel takes a process label and tells the kernel to assign the
// label to the next kernel keyring that gets created
func SetKeyLabel(label string) error {
err := writeCon("/proc/self/attr/keycreate", label)
- if os.IsNotExist(err) {
+ if os.IsNotExist(errors.Cause(err)) {
return nil
}
- if label == "" && os.IsPermission(err) {
+ if label == "" && os.IsPermission(errors.Cause(err)) {
return nil
}
return err
@@ -772,14 +800,14 @@ func badPrefix(fpath string) error {
badPrefixes := []string{"/usr"}
for _, prefix := range badPrefixes {
if strings.HasPrefix(fpath, prefix) {
- return fmt.Errorf("relabeling content in %s is not allowed", prefix)
+ return errors.Errorf("relabeling content in %s is not allowed", prefix)
}
}
return nil
}
-// Chcon changes the `fpath` file object to the SELinux label `label`.
-// If `fpath` is a directory and `recurse`` is true, Chcon will walk the
+// Chcon changes the fpath file object to the SELinux label label.
+// If fpath is a directory and recurse is true, Chcon will walk the
// directory tree setting the label.
func Chcon(fpath string, label string, recurse bool) error {
if fpath == "" {
@@ -791,19 +819,19 @@ func Chcon(fpath string, label string, recurse bool) error {
if err := badPrefix(fpath); err != nil {
return err
}
- callback := func(p string, info os.FileInfo, err error) error {
+
+ if !recurse {
+ return SetFileLabel(fpath, label)
+ }
+
+ return pwalk.Walk(fpath, func(p string, info os.FileInfo, err error) error {
e := SetFileLabel(p, label)
- if os.IsNotExist(e) {
+ // Walk a file tree can race with removal, so ignore ENOENT
+ if os.IsNotExist(errors.Cause(e)) {
return nil
}
return e
- }
-
- if recurse {
- return filepath.Walk(fpath, callback)
- }
-
- return SetFileLabel(fpath, label)
+ })
}
// DupSecOpt takes an SELinux process label and returns security options that
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
index 0c2e1cd38..f349513d9 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux_stub.go
@@ -1,4 +1,4 @@
-// +build !selinux
+// +build !selinux !linux
package selinux
@@ -35,6 +35,11 @@ func GetEnabled() bool {
return false
}
+// ClassIndex returns the int index for an object class in the loaded policy, or -1 and an error
+func ClassIndex(class string) (int, error) {
+ return -1, nil
+}
+
// SetFileLabel sets the SELinux label for this path or returns an error.
func SetFileLabel(fpath string, label string) error {
return nil
@@ -89,6 +94,13 @@ func CanonicalizeContext(val string) (string, error) {
}
/*
+ComputeCreateContext requests the type transition from source to target for class from the kernel.
+*/
+func ComputeCreateContext(source string, target string, class string) (string, error) {
+ return "", nil
+}
+
+/*
SetExecLabel sets the SELinux label that the kernel will use for any programs
that are executed by the current process thread, or an error.
*/
diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go
index 4e711a9f8..de5c80ef3 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/xattrs.go
@@ -12,8 +12,8 @@ func lgetxattr(path string, attr string) ([]byte, error) {
// Start with a 128 length byte array
dest := make([]byte, 128)
sz, errno := unix.Lgetxattr(path, attr, dest)
- if errno == unix.ERANGE {
- // Buffer too small, get the real size first
+ for errno == unix.ERANGE {
+ // Buffer too small, use zero-sized buffer to get the actual size
sz, errno = unix.Lgetxattr(path, attr, []byte{})
if errno != nil {
return nil, errno
@@ -28,7 +28,3 @@ func lgetxattr(path string, attr string) ([]byte, error) {
return dest[:sz], nil
}
-
-func lsetxattr(path string, attr string, data []byte, flags int) error {
- return unix.Lsetxattr(path, attr, data, flags)
-}
diff --git a/vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md b/vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md
new file mode 100644
index 000000000..16c4dfd3e
--- /dev/null
+++ b/vendor/github.com/opencontainers/selinux/pkg/pwalk/README.md
@@ -0,0 +1,42 @@
+## pwalk: parallel implementation of filepath.Walk
+
+This is a wrapper for [filepath.Walk](https://pkg.go.dev/path/filepath?tab=doc#Walk)
+which may speed it up by calling multiple callback functions (WalkFunc) in parallel,
+utilizing goroutines.
+
+By default, it utilizes 2\*runtime.NumCPU() goroutines for callbacks.
+This can be changed by using WalkN function which has the additional
+parameter, specifying the number of goroutines (concurrency).
+
+### Caveats
+
+Please note the following limitations of this code:
+
+* Unlike filepath.Walk, the order of calls is non-deterministic;
+
+* Only primitive error handling is supported:
+
+ * filepath.SkipDir is not supported;
+
+ * no errors are ever passed to WalkFunc;
+
+ * once any error is returned from any WalkFunc instance, no more new calls
+ to WalkFunc are made, and the error is returned to the caller of Walk;
+
+ * if more than one walkFunc instance will return an error, only one
+ of such errors will be propagated and returned by Walk, others
+ will be silently discarded.
+
+### Documentation
+
+For the official documentation, see
+https://pkg.go.dev/github.com/opencontainers/selinux/pkg/pwalk?tab=doc
+
+### Benchmarks
+
+For a WalkFunc that consists solely of the return statement, this
+implementation is about 10% slower than the standard library's
+filepath.Walk.
+
+Otherwise (if a WalkFunc is doing something) this is usually faster,
+except when the WalkN(..., 1) is used.
diff --git a/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go b/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
new file mode 100644
index 000000000..2ee0d0150
--- /dev/null
+++ b/vendor/github.com/opencontainers/selinux/pkg/pwalk/pwalk.go
@@ -0,0 +1,99 @@
+package pwalk
+
+import (
+ "os"
+ "path/filepath"
+ "runtime"
+ "sync"
+
+ "github.com/pkg/errors"
+)
+
+type WalkFunc = filepath.WalkFunc
+
+// Walk is a wrapper for filepath.Walk which can call multiple walkFn
+// in parallel, allowing to handle each item concurrently. A maximum of
+// twice the runtime.NumCPU() walkFn will be called at any one time.
+// If you want to change the maximum, use WalkN instead.
+//
+// The order of calls is non-deterministic.
+//
+// Note that this implementation only supports primitive error handling:
+//
+// * no errors are ever passed to WalkFn
+//
+// * once a walkFn returns any error, all further processing stops
+// and the error is returned to the caller of Walk;
+//
+// * filepath.SkipDir is not supported;
+//
+// * if more than one walkFn instance will return an error, only one
+// of such errors will be propagated and returned by Walk, others
+// will be silently discarded.
+//
+func Walk(root string, walkFn WalkFunc) error {
+ return WalkN(root, walkFn, runtime.NumCPU()*2)
+}
+
+// WalkN is a wrapper for filepath.Walk which can call multiple walkFn
+// in parallel, allowing to handle each item concurrently. A maximum of
+// num walkFn will be called at any one time.
+func WalkN(root string, walkFn WalkFunc, num int) error {
+ // make sure limit is sensible
+ if num < 1 {
+ return errors.Errorf("walk(%q): num must be > 0", root)
+ }
+
+ files := make(chan *walkArgs, 2*num)
+ errCh := make(chan error, 1) // get the first error, ignore others
+
+ // Start walking a tree asap
+ var err error
+ go func() {
+ err = filepath.Walk(root, func(p string, info os.FileInfo, err error) error {
+ if err != nil {
+ close(files)
+ return err
+ }
+ // add a file to the queue unless a callback sent an error
+ select {
+ case e := <-errCh:
+ close(files)
+ return e
+ default:
+ files <- &walkArgs{path: p, info: &info}
+ return nil
+ }
+ })
+ if err == nil {
+ close(files)
+ }
+ }()
+
+ var wg sync.WaitGroup
+ wg.Add(num)
+ for i := 0; i < num; i++ {
+ go func() {
+ for file := range files {
+ if e := walkFn(file.path, *file.info, nil); e != nil {
+ select {
+ case errCh <- e: // sent ok
+ default: // buffer full
+ }
+ }
+ }
+ wg.Done()
+ }()
+ }
+
+ wg.Wait()
+
+ return err
+}
+
+// walkArgs holds the arguments that were passed to the Walk or WalkLimit
+// functions.
+type walkArgs struct {
+ path string
+ info *os.FileInfo
+}