Skip to content

Commit

Permalink
selinux: Allow using other container-selinux policy templates than co…
Browse files Browse the repository at this point in the history
…ntainer

The container-selinux package (at least on RHEL/Fedora) ships a number
of policy templates. One of them is called simply `container` is special
in the sense that using it also creates a `type process`, the
others do not.

The effect is that if the other templates such as `net_container` should
be used, the CIL policy must also include the raw container type.

This patch amends the generation of the CIL policy from the SPO-specific
format so that the `container` type is always used.
  • Loading branch information
jhrozek authored and k8s-ci-robot committed Feb 23, 2023
1 parent e37aef5 commit ff004a2
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 1 deletion.
13 changes: 12 additions & 1 deletion internal/pkg/translator/obj2cil.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ import (
)

const (
typePermissive = "(typepermissive process)"
typePermissive = "(typepermissive process)"
systemContainerInherit = "container"
)

func Object2CIL(
Expand All @@ -37,7 +38,17 @@ func Object2CIL(
) string {
cilbuilder := strings.Builder{}
cilbuilder.WriteString(getCILStart(sp))

// all templates must inherit from the system container. Without explicitly
// inheriting from the system container, the policy will not be loaded
// if it uses e.g. net_container or any other template because only the
// container template includes a "process" definition
cilbuilder.WriteString(getCILInheritline(systemContainerInherit))
for _, inherit := range systemInherits {
if inherit == systemContainerInherit {
// already appended above
continue
}
cilbuilder.WriteString(getCILInheritline(inherit))
}
for _, inherit := range objInherits {
Expand Down
42 changes: 42 additions & 0 deletions internal/pkg/translator/obj2cil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,48 @@ func TestObject2CIL(t *testing.T) {
"container",
},
},
{
name: "Test translation with another template than container",
profile: &selxv1alpha2.SelinuxProfile{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Namespace: "bar",
},
Spec: selxv1alpha2.SelinuxProfileSpec{
Inherit: []selxv1alpha2.PolicyRef{
{
Name: "net_container",
},
},
Allow: selxv1alpha2.Allow{
"var_log_t": {
"dir": []string{
"open",
},
"file": []string{
"getattr",
},
"sock_file": []string{
"getattr",
},
},
},
},
},
wantMatches: []string{
"\\(block foo_bar",
"\\(blockinherit container\\)",
"\\(blockinherit net_container\\)",
// We match on several lines since we don't care about the order
"\\(allow process var_log_t \\( dir \\(.*open.*\\)\\)\\)\n",
"\\(allow process var_log_t \\( file \\(.*getattr.*\\)\\)\\)\n",
"\\(allow process var_log_t \\( sock_file \\(.*getattr.*\\)\\)\\)\n",
},
inheritsys: []string{
"container",
"net_container",
},
},
}
for _, tt := range tests {
tt := tt
Expand Down
4 changes: 4 additions & 0 deletions test/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ func (e *e2e) TestSecurityProfilesOperator() {
"SELinux: base case (install policy, run pod and delete)",
e.testCaseSelinuxBaseUsage,
},
{
"SELinux: non-default template",
e.testCaseSelinuxNonDefaultTemplate,
},
{
"SELinux: Metrics (update, delete)",
e.testCaseSelinuxMetrics,
Expand Down
3 changes: 3 additions & 0 deletions test/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,9 @@ func (e *e2e) enableSelinuxInSpod() {
if !strings.Contains(selinuxEnabledInSPODDS, "--with-selinux=true") {
e.logf("Enable selinux in SPOD")
e.kubectlOperatorNS("patch", "spod", "spod", "-p", `{"spec":{"enableSelinux": true}}`, "--type=merge")
e.kubectlOperatorNS("patch", "spod", "spod", "-p",
`{"spec":{"selinuxOptions":{"allowedSystemProfiles":["container","net_container"]}}}`,
"--type=merge")

time.Sleep(defaultWaitTime)
e.waitInOperatorNSFor("condition=ready", "spod", "spod")
Expand Down
34 changes: 34 additions & 0 deletions test/tc_selinux_base_usage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,20 @@ spec:
- open
`

netContainerPolicy = `
apiVersion: security-profiles-operator.x-k8s.io/v1alpha2
kind: SelinuxProfile
metadata:
name: net-container-policy
spec:
inherit:
- name: net_container
allow:
var_run_t:
sock_file:
- write
`

//nolint:lll // full yaml
podWithPolicyFmt = `
apiVersion: v1
Expand Down Expand Up @@ -212,6 +226,26 @@ func (e *e2e) testCaseSelinuxIncompletePolicy() {
e.kubectl("delete", "selinuxprofile", enforcingProfileName)
}

func (e *e2e) testCaseSelinuxNonDefaultTemplate(nodes []string) {
const netContainerPolicyName = "net-container-policy"

e.selinuxOnlyTestCase()

e.logf("Should be able to install a policy using a different template than container")
e.logf("creating policy")

rmFn := e.writeAndCreate(netContainerPolicy, "net-container-policy.yml")
defer rmFn()

e.kubectl("wait", "--timeout", defaultSelinuxOpTimeout,
"--for", "condition=ready", "selinuxprofile", netContainerPolicyName)

rawPolicyName := e.getSELinuxPolicyName(netContainerPolicyName)

e.logf("assert policy is installed")
e.assertSelinuxPolicyIsInstalled(nodes, rawPolicyName, maxNodeIterations, sleepBetweenIterations)
}

func (e *e2e) testCaseSelinuxIncompletePermissivePolicy() {
e.selinuxOnlyTestCase()
permissiveProfileName := "errorlogger-incomplete-permissive"
Expand Down

0 comments on commit ff004a2

Please sign in to comment.