Skip to content

Commit

Permalink
Fix for selinux policy constantly being processed
Browse files Browse the repository at this point in the history
  • Loading branch information
novaesis committed Aug 22, 2023
1 parent f8fab34 commit 6b0f54f
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 7 deletions.
22 changes: 22 additions & 0 deletions api/selinuxprofile/v1alpha2/selinuxprofile_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ package v1alpha2

import (
"context"
"sort"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"

profilebasev1alpha1 "sigs.k8s.io/security-profiles-operator/api/profilebase/v1alpha1"
"sigs.k8s.io/security-profiles-operator/internal/pkg/util"
)

const (
Expand Down Expand Up @@ -77,11 +79,31 @@ func (lk LabelKey) String() string {

type ObjectClassKey string

func (ock ObjectClassKey) String() string {
return string(ock)
}

type PermissionSet []string

// Allow defines the allow policy for the profile.
type Allow map[LabelKey]map[ObjectClassKey]PermissionSet

func SortLabelKeys(allow Allow) []LabelKey {
keys := util.MapKeys(allow)
sort.SliceStable(keys, func(i, j int) bool {
return keys[i].String() < keys[j].String()
})
return keys
}

func SortObjectClassKeys(ock map[ObjectClassKey]PermissionSet) []ObjectClassKey {
keys := util.MapKeys(ock)
sort.SliceStable(keys, func(i, j int) bool {
return keys[i].String() < keys[j].String()
})
return keys
}

// SelinuxProfileStatus defines the observed state of SelinuxProfile.
type SelinuxProfileStatus struct {
// Common status fields for all profiles.
Expand Down
8 changes: 4 additions & 4 deletions internal/pkg/daemon/selinuxprofile/common_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,7 @@ func (r *ReconcileSelinux) reconcilePolicyFile(
}
policyContent := []byte(cil)

l.Info("Writing to policy file", "policyPath", policyPath)

if err := writeFileIfDiffers(policyPath, policyContent); err != nil {
if err := writeFileIfDiffers(policyPath, policyContent, l); err != nil {
return fmt.Errorf("writing policy file: %w", err)
}

Expand Down Expand Up @@ -475,7 +473,7 @@ func selinuxdGetRequest(ctx context.Context, url string) (*http.Response, error)
// Reopening the same file may seem wasteful and even look like a TOCTOU issue, but the policy
// drop dir is private to this pod, but mostly just calling a single write is much easier codepath
// than mucking around with seeks and truncates to account for all the corner cases.
func writeFileIfDiffers(filePath string, contents []byte) error {
func writeFileIfDiffers(filePath string, contents []byte, l logr.Logger) error {
const filePermissions = 0o600
file, err := os.OpenFile(filePath, os.O_RDONLY, filePermissions)
if os.IsNotExist(err) {
Expand All @@ -495,5 +493,7 @@ func writeFileIfDiffers(filePath string, contents []byte) error {
return nil
}

l.Info("Writing to policy file", "policyPath", filePath)

return os.WriteFile(filePath, contents, filePermissions)
}
8 changes: 5 additions & 3 deletions internal/pkg/translator/obj2cil.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,13 @@ func Object2CIL(
cilbuilder.WriteString(typePermissive)
cilbuilder.WriteString("\n")
}
for ttype, tclassMap := range sp.Spec.Allow {
for tclass, perms := range tclassMap {
cilbuilder.WriteString(getCILAllowLine(sp, ttype, tclass, perms))

for _, ttype := range selxv1alpha2.SortLabelKeys(sp.Spec.Allow) {
for _, tclass := range selxv1alpha2.SortObjectClassKeys(sp.Spec.Allow[ttype]) {
cilbuilder.WriteString(getCILAllowLine(sp, ttype, tclass, sp.Spec.Allow[ttype][tclass]))
}
}

cilbuilder.WriteString(getCILEnd())
return cilbuilder.String()
}
Expand Down
12 changes: 12 additions & 0 deletions internal/pkg/util/maps.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package util

// To avoid having to use experimental library imports, the below is taken from https://cs.opensource.google/go/x/exp/+/master:maps/maps.go
// Keys returns the keys of the map m.
// The keys will be in an indeterminate order
func MapKeys[M ~map[K]V, K comparable, V any](m M) []K {
r := make([]K, 0, len(m))
for k := range m {
r = append(r, k)
}
return r
}

0 comments on commit 6b0f54f

Please sign in to comment.