vendor: cadvisor v0.38.4

This commit is contained in:
David Porter
2020-11-13 19:52:57 +00:00
parent ec734aced7
commit 8af7405f17
396 changed files with 73154 additions and 18510 deletions

View File

@@ -3,6 +3,8 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "go_default_library",
srcs = [
"doc.go",
"selinux.go",
"selinux_linux.go",
"selinux_stub.go",
"xattrs.go",
@@ -10,15 +12,17 @@ go_library(
importmap = "k8s.io/kubernetes/vendor/github.com/opencontainers/selinux/go-selinux",
importpath = "github.com/opencontainers/selinux/go-selinux",
visibility = ["//visibility:public"],
deps = select({
deps = [
"//vendor/github.com/pkg/errors:go_default_library",
] + select({
"@io_bazel_rules_go//go/platform:android": [
"//vendor/github.com/opencontainers/selinux/pkg/pwalk:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/willf/bitset:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library",
],
"@io_bazel_rules_go//go/platform:linux": [
"//vendor/github.com/opencontainers/selinux/pkg/pwalk:go_default_library",
"//vendor/github.com/pkg/errors:go_default_library",
"//vendor/github.com/willf/bitset:go_default_library",
"//vendor/golang.org/x/sys/unix:go_default_library",
],
"//conditions:default": [],

View File

@@ -0,0 +1,21 @@
/*
Package selinux provides a high-level interface for interacting with selinux.
This package uses a selinux build tag to enable the selinux functionality. This
allows non-linux and linux users who do not have selinux support to still use
tools that rely on this library.
To compile with full selinux support use the -tags=selinux option in your build
and test commands.
Usage:
import "github.com/opencontainers/selinux/go-selinux"
// Ensure that selinux is enforcing mode.
if selinux.EnforceMode() != selinux.Enforcing {
selinux.SetEnforceMode(selinux.Enforcing)
}
*/
package selinux

View File

@@ -73,9 +73,9 @@ func InitLabels(options []string) (plabel string, mlabel string, Err error) {
selinux.ReleaseLabel(processLabel)
}
processLabel = pcon.Get()
mountLabel = mcon.Get()
selinux.ReserveLabel(processLabel)
}
mountLabel = mcon.Get()
}
return processLabel, mountLabel, nil
}

View File

@@ -30,7 +30,6 @@ func Relabel(path string, fileLabel string, shared bool) error {
// 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
}

View File

@@ -0,0 +1,249 @@
package selinux
import (
"github.com/pkg/errors"
)
const (
// Enforcing constant indicate SELinux is in enforcing mode
Enforcing = 1
// Permissive constant to indicate SELinux is in permissive mode
Permissive = 0
// Disabled constant to indicate SELinux is disabled
Disabled = -1
// DefaultCategoryRange is the upper bound on the category range
DefaultCategoryRange = uint32(1024)
)
var (
// ErrMCSAlreadyExists is returned when trying to allocate a duplicate MCS.
ErrMCSAlreadyExists = errors.New("MCS label already exists")
// ErrEmptyPath is returned when an empty path has been specified.
ErrEmptyPath = errors.New("empty path")
// InvalidLabel is returned when an invalid label is specified.
InvalidLabel = errors.New("Invalid Label")
// ErrIncomparable is returned two levels are not comparable
ErrIncomparable = errors.New("incomparable levels")
// ErrLevelSyntax is returned when a sensitivity or category do not have correct syntax in a level
ErrLevelSyntax = errors.New("invalid level syntax")
// CategoryRange allows the upper bound on the category range to be adjusted
CategoryRange = DefaultCategoryRange
)
// Context is a representation of the SELinux label broken into 4 parts
type Context map[string]string
// SetDisabled disables SELinux support for the package
func SetDisabled() {
setDisabled()
}
// GetEnabled returns whether SELinux is currently enabled.
func GetEnabled() bool {
return getEnabled()
}
// 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 classIndex(class)
}
// SetFileLabel sets the SELinux label for this path 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.
func FileLabel(fpath string) (string, error) {
return fileLabel(fpath)
}
// SetFSCreateLabel tells kernel the label to create all file system objects
// created by this task. Setting label="" to return to default.
func SetFSCreateLabel(label string) error {
return setFSCreateLabel(label)
}
// FSCreateLabel returns the default label the kernel which the kernel is using
// for file system objects created by this task. "" indicates default.
func FSCreateLabel() (string, error) {
return fsCreateLabel()
}
// CurrentLabel returns the SELinux label of the current process thread, or an error.
func CurrentLabel() (string, error) {
return currentLabel()
}
// PidLabel returns the SELinux label of the given pid, or an error.
func PidLabel(pid int) (string, error) {
return pidLabel(pid)
}
// ExecLabel returns the SELinux label that the kernel will use for any programs
// that are executed by the current process thread, or an error.
func ExecLabel() (string, error) {
return execLabel()
}
// CanonicalizeContext takes a context string and writes it to the kernel
// the function then returns the context that the kernel will use. Use this
// function to check if two contexts are equivalent
func CanonicalizeContext(val string) (string, error) {
return canonicalizeContext(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) {
return computeCreateContext(source, target, class)
}
// CalculateGlbLub computes the glb (greatest lower bound) and lub (least upper bound)
// of a source and target range.
// The glblub is calculated as the greater of the low sensitivities and
// the lower of the high sensitivities and the and of each category bitset.
func CalculateGlbLub(sourceRange, targetRange string) (string, error) {
return calculateGlbLub(sourceRange, targetRange)
}
// SetExecLabel sets the SELinux label that the kernel will use for any programs
// that are executed by the current process thread, or an error.
func SetExecLabel(label string) error {
return setExecLabel(label)
}
// SetTaskLabel sets the SELinux label for the current thread, or an error.
// This requires the dyntransition permission.
func SetTaskLabel(label string) error {
return setTaskLabel(label)
}
// SetSocketLabel takes a process label and tells the kernel to assign the
// label to the next socket that gets created
func SetSocketLabel(label string) error {
return setSocketLabel(label)
}
// SocketLabel retrieves the current socket label setting
func SocketLabel() (string, error) {
return socketLabel()
}
// PeerLabel retrieves the label of the client on the other side of a socket
func PeerLabel(fd uintptr) (string, error) {
return peerLabel(fd)
}
// 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 {
return setKeyLabel(label)
}
// KeyLabel retrieves the current kernel keyring label setting
func KeyLabel() (string, error) {
return keyLabel()
}
// Get returns the Context as a string
func (c Context) Get() string {
return c.get()
}
// NewContext creates a new Context struct from the specified label
func NewContext(label string) (Context, error) {
return newContext(label)
}
// ClearLabels clears all reserved labels
func ClearLabels() {
clearLabels()
}
// ReserveLabel reserves the MLS/MCS level component of the specified label
func ReserveLabel(label string) {
reserveLabel(label)
}
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
func EnforceMode() int {
return enforceMode()
}
// SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
// Disabled is not valid, since this needs to be set at boot time.
func SetEnforceMode(mode int) error {
return setEnforceMode(mode)
}
// DefaultEnforceMode returns the systems default SELinux mode Enforcing,
// Permissive or Disabled. Note this is is just the default at boot time.
// EnforceMode tells you the systems current mode.
func DefaultEnforceMode() int {
return defaultEnforceMode()
}
// ReleaseLabel un-reserves the MLS/MCS Level field of the specified label,
// allowing it to be used by another process.
func ReleaseLabel(label string) {
releaseLabel(label)
}
// ROFileLabel returns the specified SELinux readonly file label
func ROFileLabel() string {
return roFileLabel()
}
// KVMContainerLabels returns the default processLabel and mountLabel to be used
// for kvm containers by the calling process.
func KVMContainerLabels() (string, string) {
return kvmContainerLabels()
}
// InitContainerLabels returns the default processLabel and file labels to be
// used for containers running an init system like systemd by the calling process.
func InitContainerLabels() (string, string) {
return initContainerLabels()
}
// ContainerLabels returns an allocated processLabel and fileLabel to be used for
// container labeling by the calling process.
func ContainerLabels() (processLabel string, fileLabel string) {
return containerLabels()
}
// SecurityCheckContext validates that the SELinux label is understood by the kernel
func SecurityCheckContext(val string) error {
return securityCheckContext(val)
}
// CopyLevel returns a label with the MLS/MCS level from src label replaced on
// the dest label.
func CopyLevel(src, dest string) (string, error) {
return copyLevel(src, dest)
}
// Chcon changes the fpath file object to the SELinux label label.
// If fpath is a directory and recurse is true, then Chcon walks the
// directory tree setting the label.
func Chcon(fpath string, label string, recurse bool) error {
return chcon(fpath, label, recurse)
}
// DupSecOpt takes an SELinux process label and returns security options that
// can be used to set the SELinux Type and Level for future container processes.
func DupSecOpt(src string) ([]string, error) {
return dupSecOpt(src)
}
// DisableSecOpt returns a security opt that can be used to disable SELinux
// labeling support for future container processes.
func DisableSecOpt() []string {
return disableSecOpt()
}

View File

@@ -20,17 +20,12 @@ import (
"github.com/opencontainers/selinux/pkg/pwalk"
"github.com/pkg/errors"
"github.com/willf/bitset"
"golang.org/x/sys/unix"
)
const (
// Enforcing constant indicate SELinux is in enforcing mode
Enforcing = 1
// Permissive constant to indicate SELinux is in permissive mode
Permissive = 0
// Disabled constant to indicate SELinux is disabled
Disabled = -1
minSensLen = 2
contextFile = "/usr/share/containers/selinux/contexts"
selinuxDir = "/etc/selinux/"
selinuxConfig = selinuxDir + "config"
@@ -49,17 +44,27 @@ type selinuxState struct {
sync.Mutex
}
var (
// ErrMCSAlreadyExists is returned when trying to allocate a duplicate MCS.
ErrMCSAlreadyExists = errors.New("MCS label already exists")
// ErrEmptyPath is returned when an empty path has been specified.
ErrEmptyPath = errors.New("empty path")
// InvalidLabel is returned when an invalid label is specified.
InvalidLabel = errors.New("Invalid Label")
type level struct {
sens uint
cats *bitset.BitSet
}
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
roFileLabel string
state = selinuxState{
type mlsRange struct {
low *level
high *level
}
type levelItem byte
const (
sensitivity levelItem = 's'
category levelItem = 'c'
)
var (
assignRegex = regexp.MustCompile(`^([^=]+)=(.*)$`)
readOnlyFileLabel string
state = selinuxState{
mcsList: make(map[string]bool),
}
@@ -68,9 +73,6 @@ var (
haveThreadSelf bool
)
// Context is a representation of the SELinux label broken into 4 parts
type Context map[string]string
func (s *selinuxState) setEnable(enabled bool) bool {
s.Lock()
defer s.Unlock()
@@ -97,8 +99,8 @@ func (s *selinuxState) getEnabled() bool {
return s.setEnable(enabled)
}
// SetDisabled disables selinux support for the package
func SetDisabled() {
// setDisabled disables SELinux support for the package
func setDisabled() {
state.setEnable(false)
}
@@ -190,15 +192,15 @@ func (s *selinuxState) getSELinuxfs() string {
// getSelinuxMountPoint returns the path to the mountpoint of an selinuxfs
// filesystem or an empty string if no mountpoint is found. Selinuxfs is
// a proc-like pseudo-filesystem that exposes the selinux policy API to
// a proc-like pseudo-filesystem that exposes the SELinux policy API to
// processes. The existence of an selinuxfs mount is used to determine
// whether selinux is currently enabled or not.
// whether SELinux is currently enabled or not.
func getSelinuxMountPoint() string {
return state.getSELinuxfs()
}
// GetEnabled returns whether selinux is currently enabled.
func GetEnabled() bool {
// getEnabled returns whether SELinux is currently enabled.
func getEnabled() bool {
return state.getEnabled()
}
@@ -282,8 +284,9 @@ 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) {
// 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)
@@ -299,8 +302,8 @@ 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 {
// setFileLabel sets the SELinux label for this path or returns an error.
func setFileLabel(fpath string, label string) error {
if fpath == "" {
return ErrEmptyPath
}
@@ -310,8 +313,8 @@ func SetFileLabel(fpath string, label string) error {
return nil
}
// FileLabel returns the SELinux label for this path or returns an error.
func FileLabel(fpath string) (string, error) {
// fileLabel returns the SELinux label for this path or returns an error.
func fileLabel(fpath string) (string, error) {
if fpath == "" {
return "", ErrEmptyPath
}
@@ -327,37 +330,31 @@ func FileLabel(fpath string) (string, error) {
return string(label), nil
}
/*
SetFSCreateLabel tells kernel the label to create all file system objects
created by this task. Setting label="" to return to default.
*/
func SetFSCreateLabel(label string) error {
// setFSCreateLabel tells kernel the label to create all file system objects
// created by this task. Setting label="" to return to default.
func setFSCreateLabel(label string) error {
return writeAttr("fscreate", label)
}
/*
FSCreateLabel returns the default label the kernel which the kernel is using
for file system objects created by this task. "" indicates default.
*/
func FSCreateLabel() (string, error) {
// fsCreateLabel returns the default label the kernel which the kernel is using
// for file system objects created by this task. "" indicates default.
func fsCreateLabel() (string, error) {
return readAttr("fscreate")
}
// CurrentLabel returns the SELinux label of the current process thread, or an error.
func CurrentLabel() (string, error) {
// currentLabel returns the SELinux label of the current process thread, or an error.
func currentLabel() (string, error) {
return readAttr("current")
}
// PidLabel returns the SELinux label of the given pid, or an error.
func PidLabel(pid int) (string, error) {
// pidLabel returns the SELinux label of the given pid, or an error.
func pidLabel(pid int) (string, error) {
return readCon(fmt.Sprintf("/proc/%d/attr/current", pid))
}
/*
ExecLabel returns the SELinux label that the kernel will use for any programs
that are executed by the current process thread, or an error.
*/
func ExecLabel() (string, error) {
// ExecLabel returns the SELinux label that the kernel will use for any programs
// that are executed by the current process thread, or an error.
func execLabel() (string, error) {
return readAttr("exec")
}
@@ -366,7 +363,7 @@ func writeCon(fpath, val string) error {
return ErrEmptyPath
}
if val == "" {
if !GetEnabled() {
if !getEnabled() {
return nil
}
}
@@ -418,20 +415,17 @@ func writeAttr(attr, val string) error {
return writeCon(attrPath(attr), val)
}
/*
CanonicalizeContext takes a context string and writes it to the kernel
the function then returns the context that the kernel will use. This function
can be used to see if two contexts are equivalent
*/
func CanonicalizeContext(val string) (string, error) {
// canonicalizeContext takes a context string and writes it to the kernel
// the function then returns the context that the kernel will use. Use this
// function to check if two contexts are equivalent
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)
// 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
}
@@ -439,6 +433,217 @@ func ComputeCreateContext(source string, target string, class string) (string, e
return readWriteCon(filepath.Join(getSelinuxMountPoint(), "create"), fmt.Sprintf("%s %s %d", source, target, classidx))
}
// catsToBitset stores categories in a bitset.
func catsToBitset(cats string) (*bitset.BitSet, error) {
bitset := &bitset.BitSet{}
catlist := strings.Split(cats, ",")
for _, r := range catlist {
ranges := strings.SplitN(r, ".", 2)
if len(ranges) > 1 {
catstart, err := parseLevelItem(ranges[0], category)
if err != nil {
return nil, err
}
catend, err := parseLevelItem(ranges[1], category)
if err != nil {
return nil, err
}
for i := catstart; i <= catend; i++ {
bitset.Set(i)
}
} else {
cat, err := parseLevelItem(ranges[0], category)
if err != nil {
return nil, err
}
bitset.Set(cat)
}
}
return bitset, nil
}
// parseLevelItem parses and verifies that a sensitivity or category are valid
func parseLevelItem(s string, sep levelItem) (uint, error) {
if len(s) < minSensLen || levelItem(s[0]) != sep {
return 0, ErrLevelSyntax
}
val, err := strconv.ParseUint(s[1:], 10, 32)
if err != nil {
return 0, err
}
return uint(val), nil
}
// parseLevel fills a level from a string that contains
// a sensitivity and categories
func (l *level) parseLevel(levelStr string) error {
lvl := strings.SplitN(levelStr, ":", 2)
sens, err := parseLevelItem(lvl[0], sensitivity)
if err != nil {
return errors.Wrap(err, "failed to parse sensitivity")
}
l.sens = sens
if len(lvl) > 1 {
cats, err := catsToBitset(lvl[1])
if err != nil {
return errors.Wrap(err, "failed to parse categories")
}
l.cats = cats
}
return nil
}
// rangeStrToMLSRange marshals a string representation of a range.
func rangeStrToMLSRange(rangeStr string) (*mlsRange, error) {
mlsRange := &mlsRange{}
levelSlice := strings.SplitN(rangeStr, "-", 2)
switch len(levelSlice) {
// rangeStr that has a low and a high level, e.g. s4:c0.c1023-s6:c0.c1023
case 2:
mlsRange.high = &level{}
if err := mlsRange.high.parseLevel(levelSlice[1]); err != nil {
return nil, errors.Wrapf(err, "failed to parse high level %q", levelSlice[1])
}
fallthrough
// rangeStr that is single level, e.g. s6:c0,c3,c5,c30.c1023
case 1:
mlsRange.low = &level{}
if err := mlsRange.low.parseLevel(levelSlice[0]); err != nil {
return nil, errors.Wrapf(err, "failed to parse low level %q", levelSlice[0])
}
}
if mlsRange.high == nil {
mlsRange.high = mlsRange.low
}
return mlsRange, nil
}
// bitsetToStr takes a category bitset and returns it in the
// canonical selinux syntax
func bitsetToStr(c *bitset.BitSet) string {
var str string
i, e := c.NextSet(0)
len := 0
for e {
if len == 0 {
if str != "" {
str += ","
}
str += "c" + strconv.Itoa(int(i))
}
next, e := c.NextSet(i + 1)
if e {
// consecutive cats
if next == i+1 {
len++
i = next
continue
}
}
if len == 1 {
str += ",c" + strconv.Itoa(int(i))
} else if len > 1 {
str += ".c" + strconv.Itoa(int(i))
}
if !e {
break
}
len = 0
i = next
}
return str
}
func (l1 *level) equal(l2 *level) bool {
if l2 == nil || l1 == nil {
return l1 == l2
}
if l1.sens != l2.sens {
return false
}
return l1.cats.Equal(l2.cats)
}
// String returns an mlsRange as a string.
func (m mlsRange) String() string {
low := "s" + strconv.Itoa(int(m.low.sens))
if m.low.cats != nil && m.low.cats.Count() > 0 {
low += ":" + bitsetToStr(m.low.cats)
}
if m.low.equal(m.high) {
return low
}
high := "s" + strconv.Itoa(int(m.high.sens))
if m.high.cats != nil && m.high.cats.Count() > 0 {
high += ":" + bitsetToStr(m.high.cats)
}
return low + "-" + high
}
func max(a, b uint) uint {
if a > b {
return a
}
return b
}
func min(a, b uint) uint {
if a < b {
return a
}
return b
}
// calculateGlbLub computes the glb (greatest lower bound) and lub (least upper bound)
// of a source and target range.
// The glblub is calculated as the greater of the low sensitivities and
// the lower of the high sensitivities and the and of each category bitset.
func calculateGlbLub(sourceRange, targetRange string) (string, error) {
s, err := rangeStrToMLSRange(sourceRange)
if err != nil {
return "", err
}
t, err := rangeStrToMLSRange(targetRange)
if err != nil {
return "", err
}
if s.high.sens < t.low.sens || t.high.sens < s.low.sens {
/* these ranges have no common sensitivities */
return "", ErrIncomparable
}
outrange := &mlsRange{low: &level{}, high: &level{}}
/* take the greatest of the low */
outrange.low.sens = max(s.low.sens, t.low.sens)
/* take the least of the high */
outrange.high.sens = min(s.high.sens, t.high.sens)
/* find the intersecting categories */
if s.low.cats != nil && t.low.cats != nil {
outrange.low.cats = s.low.cats.Intersection(t.low.cats)
}
if s.high.cats != nil && t.high.cats != nil {
outrange.high.cats = s.high.cats.Intersection(t.high.cats)
}
return outrange.String(), nil
}
func readWriteCon(fpath string, val string) (string, error) {
if fpath == "" {
return "", ErrEmptyPath
@@ -461,41 +666,37 @@ func readWriteCon(fpath string, val string) (string, error) {
return strings.Trim(retval, "\x00"), 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.
*/
func SetExecLabel(label string) error {
// setExecLabel sets the SELinux label that the kernel will use for any programs
// that are executed by the current process thread, or an error.
func setExecLabel(label string) error {
return writeAttr("exec", label)
}
/*
SetTaskLabel sets the SELinux label for the current thread, or an error.
This requires the dyntransition permission.
*/
func SetTaskLabel(label string) error {
// setTaskLabel sets the SELinux label for the current thread, or an error.
// This requires the dyntransition permission.
func setTaskLabel(label string) error {
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
func SetSocketLabel(label string) error {
func setSocketLabel(label string) error {
return writeAttr("sockcreate", label)
}
// SocketLabel retrieves the current socket label setting
func SocketLabel() (string, error) {
// socketLabel retrieves the current socket label setting
func socketLabel() (string, error) {
return readAttr("sockcreate")
}
// PeerLabel retrieves the label of the client on the other side of a socket
func PeerLabel(fd uintptr) (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), unix.SOL_SOCKET, unix.SO_PEERSEC)
}
// SetKeyLabel takes a process label and tells the kernel to assign the
// 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 {
func setKeyLabel(label string) error {
err := writeCon("/proc/self/attr/keycreate", label)
if os.IsNotExist(errors.Cause(err)) {
return nil
@@ -506,21 +707,21 @@ func SetKeyLabel(label string) error {
return err
}
// KeyLabel retrieves the current kernel keyring label setting
func KeyLabel() (string, error) {
// keyLabel retrieves the current kernel keyring label setting
func keyLabel() (string, error) {
return readCon("/proc/self/attr/keycreate")
}
// Get returns the Context as a string
func (c Context) Get() string {
// get returns the Context as a string
func (c Context) get() string {
if c["level"] != "" {
return fmt.Sprintf("%s:%s:%s:%s", c["user"], c["role"], c["type"], c["level"])
}
return fmt.Sprintf("%s:%s:%s", c["user"], c["role"], c["type"])
}
// NewContext creates a new Context struct from the specified label
func NewContext(label string) (Context, error) {
// newContext creates a new Context struct from the specified label
func newContext(label string) (Context, error) {
c := make(Context)
if len(label) != 0 {
@@ -538,15 +739,15 @@ func NewContext(label string) (Context, error) {
return c, nil
}
// ClearLabels clears all reserved labels
func ClearLabels() {
// clearLabels clears all reserved labels
func clearLabels() {
state.Lock()
state.mcsList = make(map[string]bool)
state.Unlock()
}
// ReserveLabel reserves the MLS/MCS level component of the specified label
func ReserveLabel(label string) {
// reserveLabel reserves the MLS/MCS level component of the specified label
func reserveLabel(label string) {
if len(label) != 0 {
con := strings.SplitN(label, ":", 4)
if len(con) > 3 {
@@ -559,8 +760,8 @@ func selinuxEnforcePath() string {
return path.Join(getSelinuxMountPoint(), "enforce")
}
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
func EnforceMode() int {
// enforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
func enforceMode() int {
var enforce int
enforceB, err := ioutil.ReadFile(selinuxEnforcePath())
@@ -574,20 +775,16 @@ func EnforceMode() int {
return enforce
}
/*
SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
Disabled is not valid, since this needs to be set at boot time.
*/
func SetEnforceMode(mode int) error {
// setEnforceMode sets the current SELinux mode Enforcing, Permissive.
// Disabled is not valid, since this needs to be set at boot time.
func setEnforceMode(mode int) error {
return ioutil.WriteFile(selinuxEnforcePath(), []byte(strconv.Itoa(mode)), 0644)
}
/*
DefaultEnforceMode returns the systems default SELinux mode Enforcing,
Permissive or Disabled. Note this is is just the default at boot time.
EnforceMode tells you the systems current mode.
*/
func DefaultEnforceMode() int {
// defaultEnforceMode returns the systems default SELinux mode Enforcing,
// Permissive or Disabled. Note this is is just the default at boot time.
// EnforceMode tells you the systems current mode.
func defaultEnforceMode() int {
switch readConfig(selinuxTag) {
case "enforcing":
return Enforcing
@@ -667,11 +864,9 @@ func uniqMcs(catRange uint32) string {
return mcs
}
/*
ReleaseLabel will unreserve the MLS/MCS Level field of the specified label.
Allowing it to be used by another process.
*/
func ReleaseLabel(label string) {
// releaseLabel un-reserves the MLS/MCS Level field of the specified label,
// allowing it to be used by another process.
func releaseLabel(label string) {
if len(label) != 0 {
con := strings.SplitN(label, ":", 4)
if len(con) > 3 {
@@ -680,9 +875,9 @@ func ReleaseLabel(label string) {
}
}
// ROFileLabel returns the specified SELinux readonly file label
func ROFileLabel() string {
return roFileLabel
// roFileLabel returns the specified SELinux readonly file label
func roFileLabel() string {
return readOnlyFileLabel
}
func openContextFile() (*os.File, error) {
@@ -737,11 +932,9 @@ func loadLabels() map[string]string {
return labels
}
/*
KVMContainerLabels returns the default processLabel and mountLabel to be used
for kvm containers by the calling process.
*/
func KVMContainerLabels() (string, string) {
// kvmContainerLabels returns the default processLabel and mountLabel to be used
// for kvm containers by the calling process.
func kvmContainerLabels() (string, string) {
processLabel := labels["kvm_process"]
if processLabel == "" {
processLabel = labels["process"]
@@ -750,11 +943,9 @@ func KVMContainerLabels() (string, string) {
return addMcs(processLabel, labels["file"])
}
/*
InitContainerLabels returns the default processLabel and file labels to be
used for containers running an init system like systemd by the calling process.
*/
func InitContainerLabels() (string, string) {
// initContainerLabels returns the default processLabel and file labels to be
// used for containers running an init system like systemd by the calling process.
func initContainerLabels() (string, string) {
processLabel := labels["init_process"]
if processLabel == "" {
processLabel = labels["process"]
@@ -763,25 +954,23 @@ func InitContainerLabels() (string, string) {
return addMcs(processLabel, labels["file"])
}
/*
ContainerLabels returns an allocated processLabel and fileLabel to be used for
container labeling by the calling process.
*/
func ContainerLabels() (processLabel string, fileLabel string) {
if !GetEnabled() {
// containerLabels returns an allocated processLabel and fileLabel to be used for
// container labeling by the calling process.
func containerLabels() (processLabel string, fileLabel string) {
if !getEnabled() {
return "", ""
}
processLabel = labels["process"]
fileLabel = labels["file"]
roFileLabel = labels["ro_file"]
readOnlyFileLabel = labels["ro_file"]
if processLabel == "" || fileLabel == "" {
return "", fileLabel
}
if roFileLabel == "" {
roFileLabel = fileLabel
if readOnlyFileLabel == "" {
readOnlyFileLabel = fileLabel
}
return addMcs(processLabel, fileLabel)
@@ -790,7 +979,7 @@ func ContainerLabels() (processLabel string, fileLabel string) {
func addMcs(processLabel, fileLabel string) (string, string) {
scon, _ := NewContext(processLabel)
if scon["level"] != "" {
mcs := uniqMcs(1024)
mcs := uniqMcs(CategoryRange)
scon["level"] = mcs
processLabel = scon.Get()
scon, _ = NewContext(fileLabel)
@@ -800,16 +989,14 @@ func addMcs(processLabel, fileLabel string) (string, string) {
return processLabel, fileLabel
}
// SecurityCheckContext validates that the SELinux label is understood by the kernel
func SecurityCheckContext(val string) error {
// securityCheckContext validates that the SELinux label is understood by the kernel
func securityCheckContext(val string) error {
return ioutil.WriteFile(path.Join(getSelinuxMountPoint(), "context"), []byte(val), 0644)
}
/*
CopyLevel returns a label with the MLS/MCS level from src label replaced on
the dest label.
*/
func CopyLevel(src, dest string) (string, error) {
// copyLevel returns a label with the MLS/MCS level from src label replaced on
// the dest label.
func copyLevel(src, dest string) (string, error) {
if src == "" {
return "", nil
}
@@ -833,7 +1020,7 @@ func CopyLevel(src, dest string) (string, error) {
return tcon.Get(), nil
}
// Prevent users from relabing system files
// Prevent users from relabeling system files
func badPrefix(fpath string) error {
if fpath == "" {
return ErrEmptyPath
@@ -848,10 +1035,10 @@ func badPrefix(fpath string) error {
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, then chcon walks the
// directory tree setting the label.
func Chcon(fpath string, label string, recurse bool) error {
func chcon(fpath string, label string, recurse bool) error {
if fpath == "" {
return ErrEmptyPath
}
@@ -876,9 +1063,9 @@ func Chcon(fpath string, label string, recurse bool) error {
})
}
// DupSecOpt takes an SELinux process label and returns security options that
// dupSecOpt takes an SELinux process label and returns security options that
// can be used to set the SELinux Type and Level for future container processes.
func DupSecOpt(src string) ([]string, error) {
func dupSecOpt(src string) ([]string, error) {
if src == "" {
return nil, nil
}
@@ -903,8 +1090,8 @@ func DupSecOpt(src string) ([]string, error) {
return dup, nil
}
// DisableSecOpt returns a security opt that can be used to disable SELinux
// disableSecOpt returns a security opt that can be used to disable SELinux
// labeling support for future container processes.
func DisableSecOpt() []string {
func disableSecOpt() []string {
return []string{"disable"}
}

View File

@@ -2,253 +2,147 @@
package selinux
import (
"errors"
)
const (
// Enforcing constant indicate SELinux is in enforcing mode
Enforcing = 1
// Permissive constant to indicate SELinux is in permissive mode
Permissive = 0
// Disabled constant to indicate SELinux is disabled
Disabled = -1
)
var (
// ErrMCSAlreadyExists is returned when trying to allocate a duplicate MCS.
ErrMCSAlreadyExists = errors.New("MCS label already exists")
// ErrEmptyPath is returned when an empty path has been specified.
ErrEmptyPath = errors.New("empty path")
)
// Context is a representation of the SELinux label broken into 4 parts
type Context map[string]string
// SetDisabled disables selinux support for the package
func SetDisabled() {
return
func setDisabled() {
}
// GetEnabled returns whether selinux is currently enabled.
func GetEnabled() bool {
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) {
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 {
func setFileLabel(fpath string, label string) error {
return nil
}
// FileLabel returns the SELinux label for this path or returns an error.
func FileLabel(fpath string) (string, error) {
func fileLabel(fpath string) (string, error) {
return "", nil
}
/*
SetFSCreateLabel tells kernel the label to create all file system objects
created by this task. Setting label="" to return to default.
*/
func SetFSCreateLabel(label string) error {
func setFSCreateLabel(label string) error {
return nil
}
/*
FSCreateLabel returns the default label the kernel which the kernel is using
for file system objects created by this task. "" indicates default.
*/
func FSCreateLabel() (string, error) {
func fsCreateLabel() (string, error) {
return "", nil
}
// CurrentLabel returns the SELinux label of the current process thread, or an error.
func CurrentLabel() (string, error) {
func currentLabel() (string, error) {
return "", nil
}
// PidLabel returns the SELinux label of the given pid, or an error.
func PidLabel(pid int) (string, error) {
func pidLabel(pid int) (string, error) {
return "", nil
}
/*
ExecLabel returns the SELinux label that the kernel will use for any programs
that are executed by the current process thread, or an error.
*/
func ExecLabel() (string, error) {
func execLabel() (string, error) {
return "", nil
}
/*
CanonicalizeContext takes a context string and writes it to the kernel
the function then returns the context that the kernel will use. This function
can be used to see if two contexts are equivalent
*/
func CanonicalizeContext(val string) (string, error) {
func canonicalizeContext(val string) (string, error) {
return "", nil
}
/*
ComputeCreateContext requests the type transition from source to target for class from the kernel.
*/
func ComputeCreateContext(source string, target string, class string) (string, error) {
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.
*/
func SetExecLabel(label string) error {
func calculateGlbLub(sourceRange, targetRange string) (string, error) {
return "", nil
}
func setExecLabel(label string) error {
return nil
}
/*
SetTaskLabel sets the SELinux label for the current thread, or an error.
This requires the dyntransition permission.
*/
func SetTaskLabel(label string) error {
func setTaskLabel(label string) error {
return nil
}
/*
SetSocketLabel sets the SELinux label that the kernel will use for any programs
that are executed by the current process thread, or an error.
*/
func SetSocketLabel(label string) error {
func setSocketLabel(label string) error {
return nil
}
// SocketLabel retrieves the current socket label setting
func SocketLabel() (string, error) {
func socketLabel() (string, error) {
return "", nil
}
// PeerLabel retrieves the label of the client on the other side of a socket
func PeerLabel(fd uintptr) (string, error) {
func peerLabel(fd uintptr) (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
func SetKeyLabel(label string) error {
func setKeyLabel(label string) error {
return nil
}
// KeyLabel retrieves the current kernel keyring label setting
func KeyLabel() (string, error) {
func keyLabel() (string, error) {
return "", nil
}
// Get returns the Context as a string
func (c Context) Get() string {
func (c Context) get() string {
return ""
}
// NewContext creates a new Context struct from the specified label
func NewContext(label string) (Context, error) {
func newContext(label string) (Context, error) {
c := make(Context)
return c, nil
}
// ClearLabels clears all reserved MLS/MCS levels
func ClearLabels() {
return
func clearLabels() {
}
// ReserveLabel reserves the MLS/MCS level component of the specified label
func ReserveLabel(label string) {
return
func reserveLabel(label string) {
}
// EnforceMode returns the current SELinux mode Enforcing, Permissive, Disabled
func EnforceMode() int {
func enforceMode() int {
return Disabled
}
/*
SetEnforceMode sets the current SELinux mode Enforcing, Permissive.
Disabled is not valid, since this needs to be set at boot time.
*/
func SetEnforceMode(mode int) error {
func setEnforceMode(mode int) error {
return nil
}
/*
DefaultEnforceMode returns the systems default SELinux mode Enforcing,
Permissive or Disabled. Note this is is just the default at boot time.
EnforceMode tells you the systems current mode.
*/
func DefaultEnforceMode() int {
func defaultEnforceMode() int {
return Disabled
}
/*
ReleaseLabel will unreserve the MLS/MCS Level field of the specified label.
Allowing it to be used by another process.
*/
func ReleaseLabel(label string) {
return
func releaseLabel(label string) {
}
// ROFileLabel returns the specified SELinux readonly file label
func ROFileLabel() string {
func roFileLabel() string {
return ""
}
// KVMContainerLabels returns the default processLabel and mountLabel to be used
// for kvm containers by the calling process.
func KVMContainerLabels() (string, string) {
func kvmContainerLabels() (string, string) {
return "", ""
}
// InitContainerLabels returns the default processLabel and file labels to be
// used for containers running an init system like systemd by the calling
func InitContainerLabels() (string, string) {
func initContainerLabels() (string, string) {
return "", ""
}
/*
ContainerLabels returns an allocated processLabel and fileLabel to be used for
container labeling by the calling process.
*/
func ContainerLabels() (processLabel string, fileLabel string) {
func containerLabels() (processLabel string, fileLabel string) {
return "", ""
}
// SecurityCheckContext validates that the SELinux label is understood by the kernel
func SecurityCheckContext(val string) error {
func securityCheckContext(val string) error {
return nil
}
/*
CopyLevel returns a label with the MLS/MCS level from src label replaced on
the dest label.
*/
func CopyLevel(src, dest string) (string, error) {
func copyLevel(src, dest string) (string, error) {
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
// directory tree setting the label.
func Chcon(fpath string, label string, recurse bool) error {
func chcon(fpath string, label string, recurse bool) error {
return nil
}
// DupSecOpt takes an SELinux process label and returns security options that
// can be used to set the SELinux Type and Level for future container processes.
func DupSecOpt(src string) ([]string, error) {
func dupSecOpt(src string) ([]string, error) {
return nil, nil
}
// DisableSecOpt returns a security opt that can be used to disable SELinux
// labeling support for future container processes.
func DisableSecOpt() []string {
func disableSecOpt() []string {
return []string{"disable"}
}

View File

@@ -48,7 +48,11 @@ func WalkN(root string, walkFn WalkFunc, num int) error {
errCh := make(chan error, 1) // get the first error, ignore others
// Start walking a tree asap
var err error
var (
err error
wg sync.WaitGroup
)
wg.Add(1)
go func() {
err = filepath.Walk(root, func(p string, info os.FileInfo, err error) error {
if err != nil {
@@ -68,9 +72,9 @@ func WalkN(root string, walkFn WalkFunc, num int) error {
if err == nil {
close(files)
}
wg.Done()
}()
var wg sync.WaitGroup
wg.Add(num)
for i := 0; i < num; i++ {
go func() {