diff --git a/pkg/volume/iscsi/attacher.go b/pkg/volume/iscsi/attacher.go index f4871d901af..8aa184c3a59 100644 --- a/pkg/volume/iscsi/attacher.go +++ b/pkg/volume/iscsi/attacher.go @@ -98,7 +98,7 @@ func (attacher *iscsiAttacher) GetDeviceMountPath( return attacher.manager.MakeGlobalPDName(*mounter.iscsiDisk), nil } -func (attacher *iscsiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string, _ volume.DeviceMounterArgs) error { +func (attacher *iscsiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string, mountArgs volume.DeviceMounterArgs) error { mounter := attacher.host.GetMounter(iscsiPluginName) notMnt, err := mounter.IsLikelyNotMountPoint(deviceMountPath) if err != nil { @@ -120,6 +120,9 @@ func (attacher *iscsiAttacher) MountDevice(spec *volume.Spec, devicePath string, if readOnly { options = append(options, "ro") } + if mountArgs.SELinuxLabel != "" { + options = volumeutil.AddSELinuxMountOption(options, mountArgs.SELinuxLabel) + } if notMnt { diskMounter := &mount.SafeFormatAndMount{Interface: mounter, Exec: attacher.host.GetExec(iscsiPluginName)} mountOptions := volumeutil.MountOptionFromSpec(spec, options...) diff --git a/pkg/volume/iscsi/iscsi.go b/pkg/volume/iscsi/iscsi.go index f19f670c2c7..7390e59b341 100644 --- a/pkg/volume/iscsi/iscsi.go +++ b/pkg/volume/iscsi/iscsi.go @@ -93,7 +93,7 @@ func (plugin *iscsiPlugin) SupportsBulkVolumeVerification() bool { } func (plugin *iscsiPlugin) SupportsSELinuxContextMount(spec *volume.Spec) (bool, error) { - return false, nil + return true, nil } func (plugin *iscsiPlugin) GetAccessModes() []v1.PersistentVolumeAccessMode { @@ -336,13 +336,14 @@ func (iscsi *iscsiDisk) iscsiPodDeviceMapPath() (string, string) { type iscsiDiskMounter struct { *iscsiDisk - readOnly bool - fsType string - volumeMode v1.PersistentVolumeMode - mounter *mount.SafeFormatAndMount - exec utilexec.Interface - deviceUtil ioutil.DeviceUtil - mountOptions []string + readOnly bool + fsType string + volumeMode v1.PersistentVolumeMode + mounter *mount.SafeFormatAndMount + exec utilexec.Interface + deviceUtil ioutil.DeviceUtil + mountOptions []string + mountedWithSELinuxContext bool } var _ volume.Mounter = &iscsiDiskMounter{} @@ -351,7 +352,7 @@ func (b *iscsiDiskMounter) GetAttributes() volume.Attributes { return volume.Attributes{ ReadOnly: b.readOnly, Managed: !b.readOnly, - SELinuxRelabel: true, + SELinuxRelabel: !b.mountedWithSELinuxContext, } } @@ -365,6 +366,9 @@ func (b *iscsiDiskMounter) SetUpAt(dir string, mounterArgs volume.MounterArgs) e if err != nil { klog.Errorf("iscsi: failed to setup") } + // The volume must have been mounted in MountDevice with -o context. + // TODO: extract from mount table in GetAttributes() to be sure? + b.mountedWithSELinuxContext = mounterArgs.SELinuxLabel != "" return err } diff --git a/pkg/volume/util/util.go b/pkg/volume/util/util.go index 807ea4b379f..dae2ec59c37 100644 --- a/pkg/volume/util/util.go +++ b/pkg/volume/util/util.go @@ -35,11 +35,13 @@ import ( utypes "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" + utilfeature "k8s.io/apiserver/pkg/util/feature" clientset "k8s.io/client-go/kubernetes" storagehelpers "k8s.io/component-helpers/storage/volume" "k8s.io/klog/v2" "k8s.io/kubernetes/pkg/api/legacyscheme" podutil "k8s.io/kubernetes/pkg/api/v1/pod" + "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/securitycontext" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/util/types" @@ -273,6 +275,16 @@ func JoinMountOptions(userOptions []string, systemOptions []string) []string { return allMountOptions.List() } +// AddSELinuxMountOption adds -o context="XYZ mount option to a given list +func AddSELinuxMountOption(options []string, seLinuxContext string) []string { + if !utilfeature.DefaultFeatureGate.Enabled(features.SELinuxMountReadWriteOncePod) { + return options + } + // Use double quotes to support a comma "," in the SELinux context string. + // For example: dirsync,context="system_u:object_r:container_file_t:s0:c15,c25",noatime + return append(options, "context=%q", seLinuxContext) +} + // ContainsAccessMode returns whether the requested mode is contained by modes func ContainsAccessMode(modes []v1.PersistentVolumeAccessMode, mode v1.PersistentVolumeAccessMode) bool { for _, m := range modes {