Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion go-selinux/label/label_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ func InitLabels(options []string) (plabel string, mlabel string, retErr error) {
if !selinux.GetEnabled() {
return "", "", nil
}
processLabel, mountLabel := selinux.ContainerLabels()
processLabel, mountLabel, err := selinux.ContainerLabels()
if err != nil {
return "", "", err
}
if processLabel != "" {
defer func() {
if retErr != nil {
Expand Down
6 changes: 3 additions & 3 deletions go-selinux/selinux.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,19 +257,19 @@ func ROFileLabel() string {

// 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, error) {
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) {
func InitContainerLabels() (string, string, error) {
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) {
func ContainerLabels() (processLabel string, fileLabel string, err error) {
return containerLabels()
}

Expand Down
35 changes: 22 additions & 13 deletions go-selinux/selinux_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ type selinuxState struct {
selinuxfsOnce sync.Once
enabledSet bool
enabled bool
sync.Mutex
sync.RWMutex
}

type level struct {
Expand Down Expand Up @@ -951,7 +951,7 @@ func mcsDelete(mcs string) {
}
state.Lock()
defer state.Unlock()
state.mcsList[mcs] = false
delete(state.mcsList, mcs)
}

func intToMcs(id int, catRange uint32) string {
Expand All @@ -974,14 +974,20 @@ func intToMcs(id int, catRange uint32) string {
return fmt.Sprintf("s0:c%d,c%d", TIER, ORD)
}

func uniqMcs(catRange uint32) string {
func uniqMcs(catRange uint32) (string, error) {
var (
n uint32
c1, c2 uint32
mcs string
)

maxMcsLen := int(catRange*(catRange-1)) / 2
for {
state.RLock()
if len(state.mcsList) == maxMcsLen {
state.Unlock()
return "", fmt.Errorf("mcsList is full, failed to create mcs")
}
state.Unlock()
_ = binary.Read(rand.Reader, binary.LittleEndian, &n)
c1 = n % catRange
_ = binary.Read(rand.Reader, binary.LittleEndian, &n)
Expand All @@ -997,7 +1003,7 @@ func uniqMcs(catRange uint32) string {
}
break
}
return mcs
return mcs, nil
}

// releaseLabel un-reserves the MLS/MCS Level field of the specified label,
Expand Down Expand Up @@ -1066,7 +1072,7 @@ func label(key string) string {

// 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, error) {
processLabel := label("kvm_process")
if processLabel == "" {
processLabel = label("process")
Expand All @@ -1077,7 +1083,7 @@ func kvmContainerLabels() (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) {
func initContainerLabels() (string, string, error) {
processLabel := label("init_process")
if processLabel == "" {
processLabel = label("process")
Expand All @@ -1088,17 +1094,17 @@ func initContainerLabels() (string, string) {

// 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, err error) {
if !getEnabled() {
return "", ""
return "", "", nil
}

processLabel = label("process")
fileLabel = label("file")
readOnlyFileLabel = label("ro_file")

if processLabel == "" || fileLabel == "" {
return "", fileLabel
return "", fileLabel, nil
}

if readOnlyFileLabel == "" {
Expand All @@ -1108,17 +1114,20 @@ func containerLabels() (processLabel string, fileLabel string) {
return addMcs(processLabel, fileLabel)
}

func addMcs(processLabel, fileLabel string) (string, string) {
func addMcs(processLabel, fileLabel string) (string, string, error) {
scon, _ := NewContext(processLabel)
if scon["level"] != "" {
mcs := uniqMcs(CategoryRange)
mcs, err := uniqMcs(CategoryRange)
if err != nil {
return "", "", err
}
scon["level"] = mcs
processLabel = scon.Get()
scon, _ = NewContext(fileLabel)
scon["level"] = mcs
fileLabel = scon.Get()
}
return processLabel, fileLabel
return processLabel, fileLabel, nil
}

// securityCheckContext validates that the SELinux label is understood by the kernel
Expand Down
30 changes: 24 additions & 6 deletions go-selinux/selinux_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,10 @@ func TestKVMLabels(t *testing.T) {
t.Skip("SELinux not enabled, skipping.")
}

plabel, flabel := KVMContainerLabels()
plabel, flabel, err := KVMContainerLabels()
if err != nil {
t.Fatal(err)
}
if plabel == "" {
t.Log("Failed to read kvm label")
}
Expand All @@ -108,7 +111,10 @@ func TestInitLabels(t *testing.T) {
t.Skip("SELinux not enabled, skipping.")
}

plabel, flabel := InitContainerLabels()
plabel, flabel, err := InitContainerLabels()
if err != nil {
t.Fatal(err)
}
if plabel == "" {
t.Log("Failed to read init label")
}
Expand Down Expand Up @@ -265,20 +271,32 @@ func TestSELinux(t *testing.T) {
plabel, flabel string
)

plabel, flabel = ContainerLabels()
plabel, flabel, err = ContainerLabels()
if err != nil {
t.Fatal(err)
}
t.Log(plabel)
t.Log(flabel)
plabel, flabel = ContainerLabels()
plabel, flabel, err = ContainerLabels()
if err != nil {
t.Fatal(err)
}
t.Log(plabel)
t.Log(flabel)
ReleaseLabel(plabel)

plabel, flabel = ContainerLabels()
plabel, flabel, err = ContainerLabels()
if err != nil {
t.Fatal(err)
}
t.Log(plabel)
t.Log(flabel)
ClearLabels()
t.Log("ClearLabels")
plabel, flabel = ContainerLabels()
plabel, flabel, err = ContainerLabels()
if err != nil {
t.Fatal("err")
}
t.Log(plabel)
t.Log(flabel)
ReleaseLabel(plabel)
Expand Down