update opencontainers/selinux to 1.3.2

This commit is contained in:
Davanum Srinivas 2020-02-26 09:51:54 -05:00
parent e483fa9658
commit 043bcb03a4
No known key found for this signature in database
GPG Key ID: 80D83A796103BF59
8 changed files with 231 additions and 114 deletions

2
go.mod
View File

@ -61,7 +61,7 @@ require (
github.com/opencontainers/image-spec v1.0.1 // indirect github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/opencontainers/runc v1.0.0-rc8.0.20190906011214-a6606a7ae9d9 github.com/opencontainers/runc v1.0.0-rc8.0.20190906011214-a6606a7ae9d9
github.com/opencontainers/runtime-spec v1.0.1 github.com/opencontainers/runtime-spec v1.0.1
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52 // indirect github.com/opencontainers/selinux v1.3.2 // indirect
github.com/pborman/uuid v0.0.0-20150824212802-cccd189d45f7 // indirect github.com/pborman/uuid v0.0.0-20150824212802-cccd189d45f7 // indirect
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13 // indirect github.com/pquerna/ffjson v0.0.0-20171002144729-d49c2bc1aa13 // indirect

3
go.sum
View File

@ -219,6 +219,8 @@ github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/
github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs=
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52 h1:B8hYj3NxHmjsC3T+tnlZ1UhInqUgnyF1zlGPmzNg2Qk= github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52 h1:B8hYj3NxHmjsC3T+tnlZ1UhInqUgnyF1zlGPmzNg2Qk=
github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs= github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52/go.mod h1:+BLncwf63G4dgOzykXAxcmnFlUaOlkDdmw/CqsW6pjs=
github.com/opencontainers/selinux v1.3.2 h1:DR4lL9SYVjgcTZKEZIncvDU06fKSc/eygjmNGOA3E1s=
github.com/opencontainers/selinux v1.3.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g=
github.com/pborman/uuid v0.0.0-20150824212802-cccd189d45f7 h1:7Nb5cK6zZrR39niF9np62PLldWkL0R0XJGDbmsRQ96E= github.com/pborman/uuid v0.0.0-20150824212802-cccd189d45f7 h1:7Nb5cK6zZrR39niF9np62PLldWkL0R0XJGDbmsRQ96E=
github.com/pborman/uuid v0.0.0-20150824212802-cccd189d45f7/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v0.0.0-20150824212802-cccd189d45f7/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@ -326,6 +328,7 @@ golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ= golang.org/x/sys v0.0.0-20191210023423-ac6580df4449 h1:gSbV7h1NRL2G1xTg/owz62CST1oJBmxy4QpMMregXVQ=
golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200107162124-548cf772de50 h1:YvQ10rzcqWXLlJZ3XCUoO25savxmscf4+SC+ZqiCHhA= golang.org/x/sys v0.0.0-20200107162124-548cf772de50 h1:YvQ10rzcqWXLlJZ3XCUoO25savxmscf4+SC+ZqiCHhA=

7
vendor/github.com/mindprince/gonvml/.travis.gofmt.sh generated vendored Normal file
View File

@ -0,0 +1,7 @@
#!/bin/bash
if [ -n "$(gofmt -s -l .)" ]; then
echo "Go code is not properly formatted:"
gofmt -s -d -e .
exit 1
fi

9
vendor/github.com/mindprince/gonvml/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,9 @@
language: go
go:
- "1.8"
- "1.9"
- "1.10"
script:
- make presubmit

115
vendor/github.com/mindprince/gonvml/bindings_nocgo.go generated vendored Normal file
View File

@ -0,0 +1,115 @@
// +build !cgo
package gonvml
import (
"errors"
"time"
)
var errNoCgo = errors.New("this binary is built without CGO, NVML is disabled")
// Initialize initializes NVML.
// Call this before calling any other methods.
func Initialize() error {
return errNoCgo
}
// Shutdown shuts down NVML.
// Call this once NVML is no longer being used.
func Shutdown() error {
return errNoCgo
}
// SystemDriverVersion returns the the driver version on the system.
func SystemDriverVersion() (string, error) {
return "", errNoCgo
}
// DeviceCount returns the number of nvidia devices on the system.
func DeviceCount() (uint, error) {
return 0, errNoCgo
}
// Device is the handle for the device.
// This handle is obtained by calling DeviceHandleByIndex().
type Device struct {
}
// DeviceHandleByIndex returns the device handle for a particular index.
// The indices range from 0 to DeviceCount()-1. The order in which NVML
// enumerates devices has no guarantees of consistency between reboots.
func DeviceHandleByIndex(idx uint) (Device, error) {
return Device{}, errNoCgo
}
// MinorNumber returns the minor number for the device.
// The minor number for the device is such that the Nvidia device node
// file for each GPU will have the form /dev/nvidia[minor number].
func (d Device) MinorNumber() (uint, error) {
return 0, errNoCgo
}
// UUID returns the globally unique immutable UUID associated with this device.
func (d Device) UUID() (string, error) {
return "", errNoCgo
}
// Name returns the product name of the device.
func (d Device) Name() (string, error) {
return "", errNoCgo
}
// MemoryInfo returns the total and used memory (in bytes) of the device.
func (d Device) MemoryInfo() (uint64, uint64, error) {
return 0, 0, errNoCgo
}
// UtilizationRates returns the percent of time over the past sample period during which:
// utilization.gpu: one or more kernels were executing on the GPU.
// utilizatoin.memory: global (device) memory was being read or written.
func (d Device) UtilizationRates() (uint, uint, error) {
return 0, 0, errNoCgo
}
// PowerUsage returns the power usage for this GPU and its associated circuitry
// in milliwatts. The reading is accurate to within +/- 5% of current power draw.
func (d Device) PowerUsage() (uint, error) {
return 0, errNoCgo
}
// AveragePowerUsage returns the power usage for this GPU and its associated circuitry
// in milliwatts averaged over the samples collected in the last `since` duration.
func (d Device) AveragePowerUsage(since time.Duration) (uint, error) {
return 0, errNoCgo
}
// AverageGPUUtilization returns the utilization.gpu metric (percent of time
// one of more kernels were executing on the GPU) averaged over the samples
// collected in the last `since` duration.
func (d Device) AverageGPUUtilization(since time.Duration) (uint, error) {
return 0, errNoCgo
}
// Temperature returns the temperature for this GPU in Celsius.
func (d Device) Temperature() (uint, error) {
return 0, errNoCgo
}
// FanSpeed returns the temperature for this GPU in the percentage of its full
// speed, with 100 being the maximum.
func (d Device) FanSpeed() (uint, error) {
return 0, errNoCgo
}
// EncoderUtilization returns the percent of time over the last sample period during which the GPU video encoder was being used.
// The sampling period is variable and is returned in the second return argument in microseconds.
func (d Device) EncoderUtilization() (uint, uint, error) {
return 0, 0, errNoCgo
}
// DecoderUtilization returns the percent of time over the last sample period during which the GPU video decoder was being used.
// The sampling period is variable and is returned in the second return argument in microseconds.
func (d Device) DecoderUtilization() (uint, uint, error) {
return 0, 0, errNoCgo
}

View File

@ -7,11 +7,11 @@ import (
"bytes" "bytes"
"crypto/rand" "crypto/rand"
"encoding/binary" "encoding/binary"
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"os" "os"
"path"
"path/filepath" "path/filepath"
"regexp" "regexp"
"strconv" "strconv"
@ -19,6 +19,7 @@ import (
"sync" "sync"
"syscall" "syscall"
"github.com/pkg/errors"
"golang.org/x/sys/unix" "golang.org/x/sys/unix"
) )
@ -37,15 +38,14 @@ const (
selinuxTag = "SELINUX" selinuxTag = "SELINUX"
xattrNameSelinux = "security.selinux" xattrNameSelinux = "security.selinux"
stRdOnly = 0x01 stRdOnly = 0x01
selinuxfsMagic = 0xf97cff8c
) )
type selinuxState struct { type selinuxState struct {
enabledSet bool enabledSet bool
enabled bool enabled bool
selinuxfsSet bool selinuxfsOnce sync.Once
selinuxfs string selinuxfs string
mcsList map[string]bool mcsList map[string]bool
sync.Mutex sync.Mutex
} }
@ -62,6 +62,10 @@ var (
state = selinuxState{ state = selinuxState{
mcsList: make(map[string]bool), mcsList: make(map[string]bool),
} }
// for attrPath()
attrPathOnce sync.Once
haveThreadSelf bool
) )
// Context is a representation of the SELinux label broken into 4 parts // Context is a representation of the SELinux label broken into 4 parts
@ -98,14 +102,6 @@ func SetDisabled() {
state.setEnable(false) state.setEnable(false)
} }
func (s *selinuxState) setSELinuxfs(selinuxfs string) string {
s.Lock()
defer s.Unlock()
s.selinuxfsSet = true
s.selinuxfs = selinuxfs
return s.selinuxfs
}
func verifySELinuxfsMount(mnt string) bool { func verifySELinuxfsMount(mnt string) bool {
var buf syscall.Statfs_t var buf syscall.Statfs_t
for { for {
@ -118,7 +114,8 @@ func verifySELinuxfsMount(mnt string) bool {
} }
return false return false
} }
if uint32(buf.Type) != uint32(selinuxfsMagic) {
if buf.Type != unix.SELINUX_MAGIC {
return false return false
} }
if (buf.Flags & stRdOnly) != 0 { if (buf.Flags & stRdOnly) != 0 {
@ -166,33 +163,29 @@ func findSELinuxfs() string {
// if there is one, or an empty string in case of EOF or error. // if there is one, or an empty string in case of EOF or error.
func findSELinuxfsMount(s *bufio.Scanner) string { func findSELinuxfsMount(s *bufio.Scanner) string {
for s.Scan() { for s.Scan() {
txt := s.Text() txt := s.Bytes()
// The first field after - is fs type. // The first field after - is fs type.
// Safe as spaces in mountpoints are encoded as \040 // Safe as spaces in mountpoints are encoded as \040
if !strings.Contains(txt, " - selinuxfs ") { if !bytes.Contains(txt, []byte(" - selinuxfs ")) {
continue continue
} }
const mPos = 5 // mount point is 5th field const mPos = 5 // mount point is 5th field
fields := strings.SplitN(txt, " ", mPos+1) fields := bytes.SplitN(txt, []byte(" "), mPos+1)
if len(fields) < mPos+1 { if len(fields) < mPos+1 {
continue continue
} }
return fields[mPos-1] return string(fields[mPos-1])
} }
return "" return ""
} }
func (s *selinuxState) getSELinuxfs() string { func (s *selinuxState) getSELinuxfs() string {
s.Lock() s.selinuxfsOnce.Do(func() {
selinuxfs := s.selinuxfs s.selinuxfs = findSELinuxfs()
selinuxfsSet := s.selinuxfsSet })
s.Unlock()
if selinuxfsSet {
return selinuxfs
}
return s.setSELinuxfs(findSELinuxfs()) return s.selinuxfs
} }
// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs // getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs
@ -254,10 +247,17 @@ func getSELinuxPolicyRoot() string {
return filepath.Join(selinuxDir, readConfig(selinuxTypeTag)) return filepath.Join(selinuxDir, readConfig(selinuxTypeTag))
} }
func isProcHandle(fh *os.File) (bool, error) { func isProcHandle(fh *os.File) error {
var buf unix.Statfs_t var buf unix.Statfs_t
err := unix.Fstatfs(int(fh.Fd()), &buf) err := unix.Fstatfs(int(fh.Fd()), &buf)
return buf.Type == unix.PROC_SUPER_MAGIC, err if err != nil {
return fmt.Errorf("statfs(%q) failed: %v", fh.Name(), err)
}
if buf.Type != unix.PROC_SUPER_MAGIC {
return fmt.Errorf("file %q is not on procfs", fh.Name())
}
return nil
} }
func readCon(fpath string) (string, error) { func readCon(fpath string) (string, error) {
@ -271,10 +271,8 @@ func readCon(fpath string) (string, error) {
} }
defer in.Close() defer in.Close()
if ok, err := isProcHandle(in); err != nil { if err := isProcHandle(in); err != nil {
return "", err return "", err
} else if !ok {
return "", fmt.Errorf("%s not on procfs", fpath)
} }
var retval string var retval string
@ -289,7 +287,10 @@ func SetFileLabel(fpath string, label string) error {
if fpath == "" { if fpath == "" {
return ErrEmptyPath return ErrEmptyPath
} }
return lsetxattr(fpath, xattrNameSelinux, []byte(label), 0) if err := lsetxattr(fpath, xattrNameSelinux, []byte(label), 0); err != nil {
return errors.Wrapf(err, "failed to set file label on %s", fpath)
}
return nil
} }
// FileLabel returns the SELinux label for this path or returns an error. // FileLabel returns the SELinux label for this path or returns an error.
@ -314,7 +315,7 @@ SetFSCreateLabel tells kernel the label to create all file system objects
created by this task. Setting label="" to return to default. created by this task. Setting label="" to return to default.
*/ */
func SetFSCreateLabel(label string) error { func SetFSCreateLabel(label string) error {
return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid()), label) return writeAttr("fscreate", label)
} }
/* /*
@ -322,12 +323,12 @@ FSCreateLabel returns the default label the kernel which the kernel is using
for file system objects created by this task. "" indicates default. for file system objects created by this task. "" indicates default.
*/ */
func FSCreateLabel() (string, error) { func FSCreateLabel() (string, error) {
return readCon(fmt.Sprintf("/proc/self/task/%d/attr/fscreate", syscall.Gettid())) return readAttr("fscreate")
} }
// CurrentLabel returns the SELinux label of the current process thread, or an error. // CurrentLabel returns the SELinux label of the current process thread, or an error.
func CurrentLabel() (string, error) { func CurrentLabel() (string, error) {
return readCon(fmt.Sprintf("/proc/self/task/%d/attr/current", syscall.Gettid())) return readAttr("current")
} }
// PidLabel returns the SELinux label of the given pid, or an error. // PidLabel returns the SELinux label of the given pid, or an error.
@ -340,10 +341,10 @@ ExecLabel returns the SELinux label that the kernel will use for any programs
that are executed by the current process thread, or an error. that are executed by the current process thread, or an error.
*/ */
func ExecLabel() (string, error) { func ExecLabel() (string, error) {
return readCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid())) return readAttr("exec")
} }
func writeCon(fpath string, val string) error { func writeCon(fpath, val string) error {
if fpath == "" { if fpath == "" {
return ErrEmptyPath return ErrEmptyPath
} }
@ -359,10 +360,8 @@ func writeCon(fpath string, val string) error {
} }
defer out.Close() defer out.Close()
if ok, err := isProcHandle(out); err != nil { if err := isProcHandle(out); err != nil {
return err return err
} else if !ok {
return fmt.Errorf("%s not on procfs", fpath)
} }
if val != "" { if val != "" {
@ -370,7 +369,36 @@ func writeCon(fpath string, val string) error {
} else { } else {
_, err = out.Write(nil) _, err = out.Write(nil)
} }
return err if err != nil {
return errors.Wrapf(err, "failed to set %s on procfs", fpath)
}
return nil
}
func attrPath(attr string) string {
// Linux >= 3.17 provides this
const threadSelfPrefix = "/proc/thread-self/attr"
attrPathOnce.Do(func() {
st, err := os.Stat(threadSelfPrefix)
if err == nil && st.Mode().IsDir() {
haveThreadSelf = true
}
})
if haveThreadSelf {
return path.Join(threadSelfPrefix, attr)
}
return path.Join("/proc/self/task/", strconv.Itoa(syscall.Gettid()), "/attr/", attr)
}
func readAttr(attr string) (string, error) {
return readCon(attrPath(attr))
}
func writeAttr(attr, val string) error {
return writeCon(attrPath(attr), val)
} }
/* /*
@ -409,7 +437,7 @@ SetExecLabel sets the SELinux label that the kernel will use for any programs
that are executed by the current process thread, or an error. that are executed by the current process thread, or an error.
*/ */
func SetExecLabel(label string) error { func SetExecLabel(label string) error {
return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/exec", syscall.Gettid()), label) return writeAttr("exec", label)
} }
/* /*
@ -417,18 +445,18 @@ SetTaskLabel sets the SELinux label for the current thread, or an error.
This requires the dyntransition permission. This requires the dyntransition permission.
*/ */
func SetTaskLabel(label string) error { func SetTaskLabel(label string) error {
return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/current", syscall.Gettid()), label) return writeAttr("current", label)
} }
// SetSocketLabel takes a process label and tells the kernel to assign the // SetSocketLabel takes a process label and tells the kernel to assign the
// label to the next socket that gets created // label to the next socket that gets created
func SetSocketLabel(label string) error { func SetSocketLabel(label string) error {
return writeCon(fmt.Sprintf("/proc/self/task/%d/attr/sockcreate", syscall.Gettid()), label) return writeAttr("sockcreate", label)
} }
// SocketLabel retrieves the current socket label setting // SocketLabel retrieves the current socket label setting
func SocketLabel() (string, error) { func SocketLabel() (string, error) {
return readCon(fmt.Sprintf("/proc/self/task/%d/attr/sockcreate", syscall.Gettid())) return readAttr("sockcreate")
} }
// PeerLabel retrieves the label of the client on the other side of a socket // PeerLabel retrieves the label of the client on the other side of a socket
@ -443,7 +471,7 @@ func SetKeyLabel(label string) error {
if os.IsNotExist(err) { if os.IsNotExist(err) {
return nil return nil
} }
if label == "" && os.IsPermission(err) && !GetEnabled() { if label == "" && os.IsPermission(err) {
return nil return nil
} }
return err return err
@ -499,19 +527,18 @@ func ReserveLabel(label string) {
} }
func selinuxEnforcePath() string { func selinuxEnforcePath() string {
return fmt.Sprintf("%s/enforce", getSelinuxMountPoint()) return path.Join(getSelinuxMountPoint(), "enforce")
} }
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled // EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
func EnforceMode() int { func EnforceMode() int {
var enforce int var enforce int
enforceS, err := readCon(selinuxEnforcePath()) enforceB, err := ioutil.ReadFile(selinuxEnforcePath())
if err != nil { if err != nil {
return -1 return -1
} }
enforce, err = strconv.Atoi(string(enforceB))
enforce, err = strconv.Atoi(string(enforceS))
if err != nil { if err != nil {
return -1 return -1
} }
@ -523,7 +550,7 @@ SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
Disabled is not valid, since this needs to be set at boot time. Disabled is not valid, since this needs to be set at boot time.
*/ */
func SetEnforceMode(mode int) error { func SetEnforceMode(mode int) error {
return writeCon(selinuxEnforcePath(), fmt.Sprintf("%d", mode)) return ioutil.WriteFile(selinuxEnforcePath(), []byte(strconv.Itoa(mode)), 0644)
} }
/* /*
@ -705,7 +732,7 @@ exit:
// SecurityCheckContext validates that the SELinux label is understood by the kernel // SecurityCheckContext validates that the SELinux label is understood by the kernel
func SecurityCheckContext(val string) error { func SecurityCheckContext(val string) error {
return writeCon(fmt.Sprintf("%s/context", getSelinuxMountPoint()), val) return ioutil.WriteFile(path.Join(getSelinuxMountPoint(), "context"), []byte(val), 0644)
} }
/* /*

View File

@ -3,76 +3,32 @@
package selinux package selinux
import ( import (
"syscall" "golang.org/x/sys/unix"
"unsafe"
) )
var _zero uintptr
// Returns a []byte slice if the xattr is set and nil otherwise // Returns a []byte slice if the xattr is set and nil otherwise
// Requires path and its attribute as arguments // Requires path and its attribute as arguments
func lgetxattr(path string, attr string) ([]byte, error) { func lgetxattr(path string, attr string) ([]byte, error) {
var sz int
pathBytes, err := syscall.BytePtrFromString(path)
if err != nil {
return nil, err
}
attrBytes, err := syscall.BytePtrFromString(attr)
if err != nil {
return nil, err
}
// Start with a 128 length byte array // Start with a 128 length byte array
sz = 128 dest := make([]byte, 128)
dest := make([]byte, sz) sz, errno := unix.Lgetxattr(path, attr, dest)
destBytes := unsafe.Pointer(&dest[0]) if errno == unix.ERANGE {
_sz, _, errno := syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) // Buffer too small, get the real size first
sz, errno = unix.Lgetxattr(path, attr, []byte{})
if errno != nil {
return nil, errno
}
switch {
case errno == syscall.ENODATA:
return nil, errno
case errno == syscall.ENOTSUP:
return nil, errno
case errno == syscall.ERANGE:
// 128 byte array might just not be good enough,
// A dummy buffer is used ``uintptr(0)`` to get real size
// of the xattrs on disk
_sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(unsafe.Pointer(nil)), uintptr(0), 0, 0)
sz = int(_sz)
if sz < 0 {
return nil, errno
}
dest = make([]byte, sz) dest = make([]byte, sz)
destBytes := unsafe.Pointer(&dest[0]) sz, errno = unix.Lgetxattr(path, attr, dest)
_sz, _, errno = syscall.Syscall6(syscall.SYS_LGETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(destBytes), uintptr(len(dest)), 0, 0) }
if errno != 0 { if errno != nil {
return nil, errno
}
case errno != 0:
return nil, errno return nil, errno
} }
sz = int(_sz)
return dest[:sz], nil return dest[:sz], nil
} }
func lsetxattr(path string, attr string, data []byte, flags int) error { func lsetxattr(path string, attr string, data []byte, flags int) error {
pathBytes, err := syscall.BytePtrFromString(path) return unix.Lsetxattr(path, attr, data, flags)
if err != nil {
return err
}
attrBytes, err := syscall.BytePtrFromString(attr)
if err != nil {
return err
}
var dataBytes unsafe.Pointer
if len(data) > 0 {
dataBytes = unsafe.Pointer(&data[0])
} else {
dataBytes = unsafe.Pointer(&_zero)
}
_, _, errno := syscall.Syscall6(syscall.SYS_LSETXATTR, uintptr(unsafe.Pointer(pathBytes)), uintptr(unsafe.Pointer(attrBytes)), uintptr(dataBytes), uintptr(len(data)), uintptr(flags), 0)
if errno != 0 {
return errno
}
return nil
} }

2
vendor/modules.txt vendored
View File

@ -189,7 +189,7 @@ github.com/opencontainers/runc/libcontainer/user
github.com/opencontainers/runc/libcontainer/utils github.com/opencontainers/runc/libcontainer/utils
# github.com/opencontainers/runtime-spec v1.0.1 # github.com/opencontainers/runtime-spec v1.0.1
github.com/opencontainers/runtime-spec/specs-go github.com/opencontainers/runtime-spec/specs-go
# github.com/opencontainers/selinux v1.3.1-0.20190929122143-5215b1806f52 # github.com/opencontainers/selinux v1.3.2
github.com/opencontainers/selinux/go-selinux github.com/opencontainers/selinux/go-selinux
github.com/opencontainers/selinux/go-selinux/label github.com/opencontainers/selinux/go-selinux/label
# github.com/pkg/errors v0.8.1 # github.com/pkg/errors v0.8.1