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
16 changes: 13 additions & 3 deletions openshift-hack/e2e/annotate/generated/zz_generated.annotations.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 32 additions & 2 deletions pkg/controller/volume/selinuxwarning/cache/volumecache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ func TestVolumeCache_AddVolumeSendConflicts(t *testing.T) {
expectedConflicts: []Conflict{},
},
{
name: "existing volume in a new pod with existing policy and new incomparable label (missing categories)",
name: "existing volume in a new pod with existing policy and new comparable label (missing categories)",
initialPods: existingPods,
podToAdd: podWithVolume{
podNamespace: "testns",
Expand All @@ -354,7 +354,16 @@ func TestVolumeCache_AddVolumeSendConflicts(t *testing.T) {
label: "system_u:system_r:label7",
changePolicy: v1.SELinuxChangePolicyMountOption,
},
expectedConflicts: []Conflict{},
expectedConflicts: []Conflict{
{
PropertyName: "SELinuxLabel",
EventReason: "SELinuxLabelConflict",
Pod: cache.ObjectName{Namespace: "testns", Name: "testpod"},
PropertyValue: "system_u:system_r:label7",
OtherPod: cache.ObjectName{Namespace: "ns7", Name: "pod7"},
OtherPropertyValue: "::label7:c0,c1",
},
},
},
{
name: "existing volume in a new pod with existing policy and new incomparable label (missing everything)",
Expand All @@ -368,6 +377,27 @@ func TestVolumeCache_AddVolumeSendConflicts(t *testing.T) {
},
expectedConflicts: []Conflict{},
},
{
name: "existing volume in a new pod with existing policy and new comparable label (missing everything but categories)",
initialPods: existingPods,
podToAdd: podWithVolume{
podNamespace: "testns",
podName: "testpod",
volumeName: "vol8",
label: "system_u:system_r:label8:c0,c1",
changePolicy: v1.SELinuxChangePolicyMountOption,
},
expectedConflicts: []Conflict{
{
PropertyName: "SELinuxLabel",
EventReason: "SELinuxLabelConflict",
Pod: cache.ObjectName{Namespace: "testns", Name: "testpod"},
PropertyValue: "system_u:system_r:label8:c0,c1",
OtherPod: cache.ObjectName{Namespace: "ns8", Name: "pod8"},
OtherPropertyValue: "",
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,15 @@ func (c *ControllerSELinuxTranslator) SELinuxOptionsToFileLabel(opts *v1.SELinux
// Conflicts returns true if two SELinux labels conflict.
// These labels must be generated by SELinuxOptionsToFileLabel above
// (the function expects strict nr. of elements in the labels).
// Since this translator cannot default missing components,
// the missing components are treated as incomparable and they do not
// conflict with anything.
// Since this translator cannot default missing label components from the operating system,
// the first three components can be empty. In this case, the empty components don't lead to a
// conflict when compared to a real SELinux label and this function returns false (as no
// conflict can be detected).
// The last component (level) is always compared, as it is not defaulted by the operating system.
// Example: "system_u:system_r:container_t:s0:c1,c2" *does not* conflict with ":::s0:c1,c2",
// because the node that will run such a Pod may expand "":::s0:c1,c2" to "system_u:system_r:container_t:s0:c1,c2".
// However, "system_u:system_r:container_t:s0:c1,c2" *does* conflict with ":::s0:c98,c99".
// because the node that will run such a Pod may expand ":::s0:c1,c2" to "system_u:system_r:container_t:s0:c1,c2".
// However: "system_u:system_r:container_t:s0:c1,c2" *does* conflict with ":::s0:c98,c99".
// And ":::s0:c1,c2" *does* conflict with "" or ":::", because it's never defaulted by the OS.
func (c *ControllerSELinuxTranslator) Conflicts(labelA, labelB string) bool {
partsA := strings.SplitN(labelA, ":", 4)
partsB := strings.SplitN(labelB, ":", 4)
Expand All @@ -82,16 +85,20 @@ func (c *ControllerSELinuxTranslator) Conflicts(labelA, labelB string) bool {
if partsA[i] == partsB[i] {
continue
}
if i == 3 {
// The last component must always match
return true
}
// i<3, empty parts are incomparable
if partsA[i] == "" {
// incomparable part, no conflict
continue
}
if partsB[i] == "" {
// incomparable part, no conflict
continue
}
// Parts are not equal and neither of them is "" -> conflict
return true
}

return false
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,26 +93,32 @@ func TestLabelsConflict(t *testing.T) {
conflict: false,
},
{
name: "empty string don't conflict with anything",
name: "empty strings don't conflict with anything except the level",
a: "",
b: "system_u:system_r:container_t",
conflict: false,
},
{
name: "empty string conflicts with level",
a: "",
b: "system_u:system_r:container_t:s0:c1,c2",
conflict: true,
},
{
name: "empty parts don't conflict with anything",
a: ":::::::::::::",
a: ":::",
b: "system_u:system_r:container_t",
conflict: false,
},
{
name: "different lengths don't conflict if the common parts are the same",
a: "system_u:system_r:container_t:c0,c2",
b: "system_u:system_r:container_t",
a: "system_u:system_r:container_t:",
b: "system_u:system_r",
conflict: false,
},
{
name: "different lengths conflict if the common parts differ",
a: "system_u:system_r:conflict_t:c0,c2",
a: "system_u:system_r:conflict_t:",
b: "system_u:system_r:container_t",
conflict: true,
},
Expand All @@ -125,9 +131,15 @@ func TestLabelsConflict(t *testing.T) {
{
name: "non-conflicting empty parts",
a: "system_u::container_t",
b: ":system_r::c0,c2",
b: ":system_r::",
conflict: false,
},
{
name: "empty level conflicts with non-empty level",
a: ":::s0:c1,c2",
b: "",
conflict: true,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
Expand Down
9 changes: 6 additions & 3 deletions test/e2e/storage/csimock/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ func (m *mockDriverSetup) createPodWithFSGroup(ctx context.Context, fsGroup *int
return class, claim, pod
}

func (m *mockDriverSetup) createPodWithSELinux(ctx context.Context, accessModes []v1.PersistentVolumeAccessMode, mountOptions []string, seLinuxOpts *v1.SELinuxOptions, policy *v1.PodSELinuxChangePolicy) (*storagev1.StorageClass, *v1.PersistentVolumeClaim, *v1.Pod) {
func (m *mockDriverSetup) createPodWithSELinux(ctx context.Context, accessModes []v1.PersistentVolumeAccessMode, mountOptions []string, seLinuxOpts *v1.SELinuxOptions, policy *v1.PodSELinuxChangePolicy, privileged bool) (*storagev1.StorageClass, *v1.PersistentVolumeClaim, *v1.Pod) {
ginkgo.By("Creating pod with SELinux context")
f := m.f
nodeSelection := m.config.ClientNodeSelection
Expand All @@ -480,7 +480,7 @@ func (m *mockDriverSetup) createPodWithSELinux(ctx context.Context, accessModes
ReclaimPolicy: m.tp.reclaimPolicy,
}
class, claim := createClaim(ctx, f.ClientSet, scTest, nodeSelection, m.tp.scName, f.Namespace.Name, accessModes)
pod, err := startPausePodWithSELinuxOptions(f.ClientSet, claim, nodeSelection, f.Namespace.Name, seLinuxOpts, policy)
pod, err := startPausePodWithSELinuxOptions(f.ClientSet, claim, nodeSelection, f.Namespace.Name, seLinuxOpts, policy, privileged)
framework.ExpectNoError(err, "Failed to create pause pod with SELinux context %s: %v", seLinuxOpts, err)

if class != nil {
Expand Down Expand Up @@ -802,7 +802,7 @@ func startBusyBoxPodWithVolumeSource(cs clientset.Interface, volumeSource v1.Vol
return cs.CoreV1().Pods(ns).Create(context.TODO(), pod, metav1.CreateOptions{})
}

func startPausePodWithSELinuxOptions(cs clientset.Interface, pvc *v1.PersistentVolumeClaim, node e2epod.NodeSelection, ns string, seLinuxOpts *v1.SELinuxOptions, policy *v1.PodSELinuxChangePolicy) (*v1.Pod, error) {
func startPausePodWithSELinuxOptions(cs clientset.Interface, pvc *v1.PersistentVolumeClaim, node e2epod.NodeSelection, ns string, seLinuxOpts *v1.SELinuxOptions, policy *v1.PodSELinuxChangePolicy, privileged bool) (*v1.Pod, error) {
pod := &v1.Pod{
ObjectMeta: metav1.ObjectMeta{
GenerateName: "pvc-volume-tester-",
Expand All @@ -816,6 +816,9 @@ func startPausePodWithSELinuxOptions(cs clientset.Interface, pvc *v1.PersistentV
{
Name: "volume-tester",
Image: imageutils.GetE2EImage(imageutils.Pause),
SecurityContext: &v1.SecurityContext{
Privileged: &privileged,
},
VolumeMounts: []v1.VolumeMount{
{
Name: "my-volume",
Expand Down
Loading