Skip to content

Commit

Permalink
LinuxContainerSecurityContext field apparmor_profile has been depreca…
Browse files Browse the repository at this point in the history
…ted in favor of the newer structured apparmor field.

Introduce new tests for new field Apparmor alongside the old ApparmorProfile

Signed-off-by: roman-kiselenko <roman.kiselenko.dev@gmail.com>
  • Loading branch information
roman-kiselenko committed Apr 27, 2024
1 parent 5c770d7 commit 6362c63
Showing 1 changed file with 119 additions and 11 deletions.
130 changes: 119 additions & 11 deletions pkg/validate/apparmor_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ profile cri-validate-apparmor-test-audit-write flags=(attach_disconnected) {
`
)

// The AppArmor profile to the CRI via the deprecated apparmor_profile field
// in favor of the newer structured apparmor field.
// CRI provides the AppArmor profile via both fields to maintain backwards compatibility.
var _ = framework.KubeDescribe("AppArmor", func() {
f := framework.NewDefaultCRIFramework()

Expand All @@ -66,7 +69,7 @@ var _ = framework.KubeDescribe("AppArmor", func() {
Expect(loadTestProfiles()).NotTo(HaveOccurred())
})

Context("runtime should support apparmor", func() {
Context("runtime should support depracated apparmor_profile field", func() {
var sandboxID string
var sandboxConfig *runtimeapi.PodSandboxConfig

Expand All @@ -81,38 +84,143 @@ var _ = framework.KubeDescribe("AppArmor", func() {
rc.RemovePodSandbox(context.TODO(), sandboxID)
})

It("should fail with an unloaded profile", func() {
profile := apparmorProfileNamePrefix + "non-existent-profile"
It("should fail with an unloaded apparmor_profile", func() {
profile := &runtimeapi.LinuxContainerSecurityContext{
ApparmorProfile: apparmorProfileNamePrefix + "non-existent-profile",
}
containerID := createContainerWithAppArmor(rc, ic, sandboxID, sandboxConfig, profile, false)
Expect(containerID).To(BeEmpty())
})

It("should enforce a profile blocking writes", func() {
profile := apparmorProfileNamePrefix + "cri-validate-apparmor-test-deny-write"
It("should enforce a apparmor_profile blocking writes", func() {
profile := &runtimeapi.LinuxContainerSecurityContext{
ApparmorProfile: apparmorProfileNamePrefix + "cri-validate-apparmor-test-deny-write",
}
containerID := createContainerWithAppArmor(rc, ic, sandboxID, sandboxConfig, profile, true)
checkContainerApparmor(rc, containerID, false)
})

It("should enforce a permissive profile", func() {
profile := apparmorProfileNamePrefix + "cri-validate-apparmor-test-audit-write"
It("should enforce a permissive depracated profile", func() {
profile := &runtimeapi.LinuxContainerSecurityContext{
ApparmorProfile: apparmorProfileNamePrefix + "cri-validate-apparmor-test-audit-write",
}
containerID := createContainerWithAppArmor(rc, ic, sandboxID, sandboxConfig, profile, true)
checkContainerApparmor(rc, containerID, true)
})
})

Context("runtime should support apparmor field", func() {
var sandboxID string
var sandboxConfig *runtimeapi.PodSandboxConfig

BeforeEach(func() {
sandboxID, sandboxConfig = framework.CreatePodSandboxForContainer(rc)
})

AfterEach(func() {
By("stop PodSandbox")
rc.StopPodSandbox(context.TODO(), sandboxID)
By("delete PodSandbox")
rc.RemovePodSandbox(context.TODO(), sandboxID)
})

It("should fail with an unloaded apparmor_profile", func() {
profile := &runtimeapi.LinuxContainerSecurityContext{
Apparmor: &runtimeapi.SecurityProfile{
ProfileType: runtimeapi.SecurityProfile_Localhost,
LocalhostRef: apparmorProfileNamePrefix + "non-existent-profile",
},
}
containerID := createContainerWithAppArmor(rc, ic, sandboxID, sandboxConfig, profile, false)
Expect(containerID).To(BeEmpty())
})

It("should enforce a apparmor_profile blocking writes", func() {
profile := &runtimeapi.LinuxContainerSecurityContext{
Apparmor: &runtimeapi.SecurityProfile{
ProfileType: runtimeapi.SecurityProfile_Localhost,
LocalhostRef: apparmorProfileNamePrefix + "cri-validate-apparmor-test-deny-write",
},
}
containerID := createContainerWithAppArmor(rc, ic, sandboxID, sandboxConfig, profile, true)
checkContainerApparmor(rc, containerID, false)
})

It("should enforce a permissive depracated profile", func() {
profile := &runtimeapi.LinuxContainerSecurityContext{
Apparmor: &runtimeapi.SecurityProfile{
ProfileType: runtimeapi.SecurityProfile_Localhost,
LocalhostRef: apparmorProfileNamePrefix + "cri-validate-apparmor-test-audit-write",
},
}
containerID := createContainerWithAppArmor(rc, ic, sandboxID, sandboxConfig, profile, true)
checkContainerApparmor(rc, containerID, true)
})
})

Context("runtime should prefer new apparmor field", func() {
var sandboxID string
var sandboxConfig *runtimeapi.PodSandboxConfig

BeforeEach(func() {
sandboxID, sandboxConfig = framework.CreatePodSandboxForContainer(rc)
})

AfterEach(func() {
By("stop PodSandbox")
rc.StopPodSandbox(context.TODO(), sandboxID)
By("delete PodSandbox")
rc.RemovePodSandbox(context.TODO(), sandboxID)
})

It("should fail with an unloaded apparmor_profile", func() {
profile := &runtimeapi.LinuxContainerSecurityContext{
ApparmorProfile: apparmorProfileNamePrefix + "non-existent-profile",
Apparmor: &runtimeapi.SecurityProfile{
ProfileType: runtimeapi.SecurityProfile_Localhost,
LocalhostRef: apparmorProfileNamePrefix + "non-existent-profile",
},
}
containerID := createContainerWithAppArmor(rc, ic, sandboxID, sandboxConfig, profile, false)
Expect(containerID).To(BeEmpty())
})

It("should enforce a apparmor_profile blocking writes", func() {
profile := &runtimeapi.LinuxContainerSecurityContext{
ApparmorProfile: apparmorProfileNamePrefix + "non-existent-profile",
Apparmor: &runtimeapi.SecurityProfile{
ProfileType: runtimeapi.SecurityProfile_Localhost,
LocalhostRef: apparmorProfileNamePrefix + "cri-validate-apparmor-test-deny-write",
},
}
containerID := createContainerWithAppArmor(rc, ic, sandboxID, sandboxConfig, profile, true)
checkContainerApparmor(rc, containerID, false)
})

It("should work with apparmor profile", func() {
profile := &runtimeapi.LinuxContainerSecurityContext{
ApparmorProfile: apparmorProfileNamePrefix + "non-existent-profile",
Apparmor: &runtimeapi.SecurityProfile{
ProfileType: runtimeapi.SecurityProfile_Localhost,
LocalhostRef: apparmorProfileNamePrefix + "cri-validate-apparmor-test-audit-write",
},
}
containerID := createContainerWithAppArmor(rc, ic, sandboxID, sandboxConfig, profile, true)
checkContainerApparmor(rc, containerID, true)
})
})
}
})

func createContainerWithAppArmor(rc internalapi.RuntimeService, ic internalapi.ImageManagerService, sandboxID string, sandboxConfig *runtimeapi.PodSandboxConfig, profile string, shouldSucceed bool) string {
func createContainerWithAppArmor(rc internalapi.RuntimeService, ic internalapi.ImageManagerService, sandboxID string, sandboxConfig *runtimeapi.PodSandboxConfig, profile *runtimeapi.LinuxContainerSecurityContext, shouldSucceed bool) string {
By("create a container with apparmor")
containerName := "apparmor-test-" + framework.NewUUID()
containerConfig := &runtimeapi.ContainerConfig{
Metadata: framework.BuildContainerMetadata(containerName, framework.DefaultAttempt),
Image: &runtimeapi.ImageSpec{Image: framework.TestContext.TestImageList.DefaultTestContainerImage},
Command: []string{"touch", "/tmp/foo"},
Linux: &runtimeapi.LinuxContainerConfig{
SecurityContext: &runtimeapi.LinuxContainerSecurityContext{
ApparmorProfile: profile,
},
SecurityContext: profile,
},
}

Expand Down

0 comments on commit 6362c63

Please sign in to comment.