Skip to content

Commit

Permalink
Merge pull request #169 from rhatdan/lgetfile
Browse files Browse the repository at this point in the history
Add LFileLabel and LSetFileLabel
  • Loading branch information
rhatdan authored Nov 19, 2021
2 parents 0cb05ae + 1b18907 commit 66c8503
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 5 deletions.
18 changes: 16 additions & 2 deletions go-selinux/selinux.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,30 @@ func ClassIndex(class string) (int, error) {
return classIndex(class)
}

// SetFileLabel sets the SELinux label for this path or returns an error.
// SetFileLabel sets the SELinux label for this path, following symlinks,
// or returns an error.
func SetFileLabel(fpath string, label string) error {
return setFileLabel(fpath, label)
}

// FileLabel returns the SELinux label for this path or returns an error.
// LsetFileLabel sets the SELinux label for this path, not following symlinks,
// or returns an error.
func LsetFileLabel(fpath string, label string) error {
return lSetFileLabel(fpath, label)
}

// FileLabel returns the SELinux label for this path, following symlinks,
// or returns an error.
func FileLabel(fpath string) (string, error) {
return fileLabel(fpath)
}

// LfileLabel returns the SELinux label for this path, not following symlinks,
// or returns an error.
func LfileLabel(fpath string) (string, error) {
return lFileLabel(fpath)
}

// SetFSCreateLabel tells the kernel what label to use for all file system objects
// created by this task.
// Set the label to an empty string to return to the default label. Calls to SetFSCreateLabel
Expand Down
45 changes: 42 additions & 3 deletions go-selinux/selinux_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,9 @@ func classIndex(class string) (int, error) {
return index, nil
}

// setFileLabel sets the SELinux label for this path or returns an error.
func setFileLabel(fpath string, label string) error {
// lSetFileLabel sets the SELinux label for this path, not following symlinks,
// or returns an error.
func lSetFileLabel(fpath string, label string) error {
if fpath == "" {
return ErrEmptyPath
}
Expand All @@ -334,12 +335,50 @@ func setFileLabel(fpath string, label string) error {
return nil
}

// fileLabel returns the SELinux label for this path or returns an error.
// setFileLabel sets the SELinux label for this path, following symlinks,
// or returns an error.
func setFileLabel(fpath string, label string) error {
if fpath == "" {
return ErrEmptyPath
}
for {
err := unix.Setxattr(fpath, xattrNameSelinux, []byte(label), 0)
if err == nil {
break
}
if err != unix.EINTR { //nolint:errorlint // unix errors are bare
return &os.PathError{Op: "setxattr", Path: fpath, Err: err}
}
}

return nil
}

// fileLabel returns the SELinux label for this path, following symlinks,
// or returns an error.
func fileLabel(fpath string) (string, error) {
if fpath == "" {
return "", ErrEmptyPath
}

label, err := getxattr(fpath, xattrNameSelinux)
if err != nil {
return "", &os.PathError{Op: "getxattr", Path: fpath, Err: err}
}
// Trim the NUL byte at the end of the byte buffer, if present.
if len(label) > 0 && label[len(label)-1] == '\x00' {
label = label[:len(label)-1]
}
return string(label), nil
}

// lFileLabel returns the SELinux label for this path, not following symlinks,
// or returns an error.
func lFileLabel(fpath string) (string, error) {
if fpath == "" {
return "", ErrEmptyPath
}

label, err := lgetxattr(fpath, xattrNameSelinux)
if err != nil {
return "", &os.PathError{Op: "lgetxattr", Path: fpath, Err: err}
Expand Down
8 changes: 8 additions & 0 deletions go-selinux/selinux_stub.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,18 @@ func setFileLabel(fpath string, label string) error {
return nil
}

func lSetFileLabel(fpath string, label string) error {
return nil
}

func fileLabel(fpath string) (string, error) {
return "", nil
}

func lFileLabel(fpath string) (string, error) {
return "", nil
}

func setFSCreateLabel(label string) error {
return nil
}
Expand Down
33 changes: 33 additions & 0 deletions go-selinux/xattrs_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,36 @@ func doLgetxattr(path, attr string, dest []byte) (int, error) {
}
}
}

// getxattr returns a []byte slice containing the value of
// an extended attribute attr set for path.
func getxattr(path, attr string) ([]byte, error) {
// Start with a 128 length byte array
dest := make([]byte, 128)
sz, errno := dogetxattr(path, attr, dest)
for errno == unix.ERANGE { //nolint:errorlint // unix errors are bare
// Buffer too small, use zero-sized buffer to get the actual size
sz, errno = dogetxattr(path, attr, []byte{})
if errno != nil {
return nil, errno
}

dest = make([]byte, sz)
sz, errno = dogetxattr(path, attr, dest)
}
if errno != nil {
return nil, errno
}

return dest[:sz], nil
}

// dogetxattr is a wrapper that retries on EINTR
func dogetxattr(path, attr string, dest []byte) (int, error) {
for {
sz, err := unix.Getxattr(path, attr, dest)
if err != unix.EINTR { //nolint:errorlint // unix errors are bare
return sz, err
}
}
}

0 comments on commit 66c8503

Please sign in to comment.