Skip to content

Commit

Permalink
refactor: optimize flags and SetLabel
Browse files Browse the repository at this point in the history
Do not do string lookups in repetitive calls. We do not support changing SELinux status during runtime, so once we read this we can assume status does not change.

Also avoid unneeded FS writes when appropriate label is already set on file.

Signed-off-by: Dmitry Sharshakov <[email protected]>
  • Loading branch information
dsseng committed Nov 19, 2024
1 parent 4dc58cf commit 14b71ac
Showing 1 changed file with 38 additions and 8 deletions.
46 changes: 38 additions & 8 deletions internal/pkg/selinux/selinux.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,54 +6,84 @@
package selinux

import (
"bytes"
_ "embed"
"log"
"os"

"github.com/pkg/xattr"
"github.com/siderolabs/go-procfs/procfs"
"golang.org/x/sys/unix"

"github.com/siderolabs/talos/pkg/machinery/constants"
)

//go:embed policy/policy.33
var policy []byte

var isEnabled, checkedEnabled, isEnforcing, checkedEnforcing bool

// IsEnabled checks if SELinux is enabled on the system by reading
// the kernel command line. It returns true if SELinux is enabled,
// otherwise it returns false. It also ensures we're not in a container.
// By default SELinux is disabled.
func IsEnabled() bool {
if checkedEnabled {
return isEnabled
}

if _, err := os.Stat("/usr/etc/in-container"); err == nil {
return false
isEnabled = false
checkedEnabled = true
return isEnabled
}

val := procfs.ProcCmdline().Get(constants.KernelParamSELinux).First()

return val != nil && *val == "1"
isEnabled = (val != nil && *val == "1")
checkedEnabled = true
return isEnabled
}

// IsEnforcing checks if SELinux is enabled and the mode should be enforcing.
// By default if SELinux is enabled we consider it to be permissive.
func IsEnforcing() bool {
if checkedEnforcing {
return isEnforcing
}

if !IsEnabled() {
return false
isEnforcing = false
checkedEnforcing = true
return isEnforcing
}

val := procfs.ProcCmdline().Get(constants.KernelParamSELinuxEnforcing).First()

return val != nil && *val == "1"
isEnforcing = (val != nil && *val == "1")
checkedEnforcing = true
return isEnforcing
}

// SetLabel sets label for file or directory, following symlinks
// It does not perform the operation in case SELinux is disabled or provided label is empty.
// SetLabel sets label for file, directory or symlink (not following symlinks)
// It does not perform the operation in case SELinux is disabled, provided label is empty or already set.
func SetLabel(filename string, label string) error {
if label == "" {
return nil
}

if IsEnabled() {
if err := unix.Lsetxattr(filename, "security.selinux", []byte(label), 0); err != nil {
// We use LGet/LSet so that we manipulate label on the exact path, not the symlink target.
currentLabel, err := xattr.LGet(filename, "security.selinux")
if err != nil {
return err
}

// Skip extra FS transactions when labels are okay.
if string(bytes.Trim(currentLabel, "\x00\n")) == label {
return nil
}

if err := xattr.LSet(filename, "security.selinux", []byte(label)); err != nil {
return err
}
}
Expand Down

0 comments on commit 14b71ac

Please sign in to comment.