diff --git a/pkg/kubelet/BUILD b/pkg/kubelet/BUILD index 61e9e649ed1..f6da8c427ad 100644 --- a/pkg/kubelet/BUILD +++ b/pkg/kubelet/BUILD @@ -109,6 +109,7 @@ go_library( "//pkg/util/node:go_default_library", "//pkg/util/oom:go_default_library", "//pkg/util/removeall:go_default_library", + "//pkg/util/selinux:go_default_library", "//pkg/util/taints:go_default_library", "//pkg/volume:go_default_library", "//pkg/volume/csi:go_default_library", diff --git a/pkg/kubelet/cm/devicemanager/BUILD b/pkg/kubelet/cm/devicemanager/BUILD index f45f3fc9897..6301b6e2dba 100644 --- a/pkg/kubelet/cm/devicemanager/BUILD +++ b/pkg/kubelet/cm/devicemanager/BUILD @@ -26,6 +26,7 @@ go_library( "//pkg/kubelet/metrics:go_default_library", "//pkg/kubelet/util/pluginwatcher:go_default_library", "//pkg/scheduler/nodeinfo:go_default_library", + "//pkg/util/selinux:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/resource:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", diff --git a/pkg/kubelet/cm/devicemanager/manager.go b/pkg/kubelet/cm/devicemanager/manager.go index 22cd21d81a3..06ad0f68bd0 100644 --- a/pkg/kubelet/cm/devicemanager/manager.go +++ b/pkg/kubelet/cm/devicemanager/manager.go @@ -42,6 +42,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/metrics" watcher "k8s.io/kubernetes/pkg/kubelet/util/pluginwatcher" schedulernodeinfo "k8s.io/kubernetes/pkg/scheduler/nodeinfo" + "k8s.io/kubernetes/pkg/util/selinux" ) // ActivePodsFunc is a function that returns a list of pods to reconcile. @@ -206,6 +207,11 @@ func (m *ManagerImpl) Start(activePods ActivePodsFunc, sourcesReady config.Sourc socketPath := filepath.Join(m.socketdir, m.socketname) os.MkdirAll(m.socketdir, 0755) + if selinux.SELinuxEnabled() { + if err := selinux.SetFileLabel(m.socketdir, config.KubeletPluginsDirSELinuxLabel); err != nil { + klog.Warningf("Unprivileged containerized plugins might not work. Could not set selinux context on %s: %v", m.socketdir, err) + } + } // Removes all stale sockets in m.socketdir. Device plugins can monitor // this and use it as a signal to re-register with the new Kubelet. diff --git a/pkg/kubelet/config/defaults.go b/pkg/kubelet/config/defaults.go index 43f7162bfd8..6c1e4ebf411 100644 --- a/pkg/kubelet/config/defaults.go +++ b/pkg/kubelet/config/defaults.go @@ -26,4 +26,5 @@ const ( DefaultKubeletContainersDirName = "containers" DefaultKubeletPluginContainersDirName = "plugin-containers" DefaultKubeletPodResourcesDirName = "pod-resources" + KubeletPluginsDirSELinuxLabel = "system_u:object_r:container_file_t:s0" ) diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index 45ae42629fb..5a3d0d19cc9 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -113,6 +113,7 @@ import ( "k8s.io/kubernetes/pkg/util/mount" nodeutil "k8s.io/kubernetes/pkg/util/node" "k8s.io/kubernetes/pkg/util/oom" + "k8s.io/kubernetes/pkg/util/selinux" "k8s.io/kubernetes/pkg/volume" "k8s.io/kubernetes/pkg/volume/csi" utilexec "k8s.io/utils/exec" @@ -1225,6 +1226,8 @@ type Kubelet struct { // 4. the pod-resources directory func (kl *Kubelet) setupDataDirs() error { kl.rootDirectory = path.Clean(kl.rootDirectory) + pluginRegistrationDir := kl.getPluginsRegistrationDir() + pluginsDir := kl.getPluginsDir() if err := os.MkdirAll(kl.getRootDir(), 0750); err != nil { return fmt.Errorf("error creating root directory: %v", err) } @@ -1243,6 +1246,16 @@ func (kl *Kubelet) setupDataDirs() error { if err := os.MkdirAll(kl.getPodResourcesDir(), 0750); err != nil { return fmt.Errorf("error creating podresources directory: %v", err) } + if selinux.SELinuxEnabled() { + err := selinux.SetFileLabel(pluginRegistrationDir, config.KubeletPluginsDirSELinuxLabel) + if err != nil { + klog.Warningf("Unprivileged containerized plugins might not work. Could not set selinux context on %s: %v", pluginRegistrationDir, err) + } + err = selinux.SetFileLabel(pluginsDir, config.KubeletPluginsDirSELinuxLabel) + if err != nil { + klog.Warningf("Unprivileged containerized plugins might not work. Could not set selinux context on %s: %v", pluginsDir, err) + } + } return nil } diff --git a/pkg/kubelet/kubelet_getters.go b/pkg/kubelet/kubelet_getters.go index a577a6bfad7..98329038dcc 100644 --- a/pkg/kubelet/kubelet_getters.go +++ b/pkg/kubelet/kubelet_getters.go @@ -159,6 +159,11 @@ func (kl *Kubelet) getPodResourcesDir() string { return filepath.Join(kl.getRootDir(), config.DefaultKubeletPodResourcesDirName) } +// getPluginsDirSELinuxLabel returns the selinux label to be applied on plugin directories +func (kl *Kubelet) getPluginsDirSELinuxLabel() string { + return config.KubeletPluginsDirSELinuxLabel +} + // GetPods returns all pods bound to the kubelet and their spec, and the mirror // pods. func (kl *Kubelet) GetPods() []*v1.Pod { diff --git a/pkg/util/selinux/selinux_linux.go b/pkg/util/selinux/selinux_linux.go index bdaa505c5d5..33ae35884fe 100644 --- a/pkg/util/selinux/selinux_linux.go +++ b/pkg/util/selinux/selinux_linux.go @@ -50,3 +50,8 @@ func (_ *realSELinuxRunner) Getfilecon(path string) (string, error) { } return selinux.FileLabel(path) } + +// SetFileLabel applies the SELinux label on the path or returns an error. +func SetFileLabel(path string, label string) error { + return selinux.SetFileLabel(path, label) +} diff --git a/pkg/util/selinux/selinux_unsupported.go b/pkg/util/selinux/selinux_unsupported.go index 4f7767472c9..4c8f5f0b28c 100644 --- a/pkg/util/selinux/selinux_unsupported.go +++ b/pkg/util/selinux/selinux_unsupported.go @@ -31,3 +31,8 @@ var _ SELinuxRunner = &realSELinuxRunner{} func (_ *realSELinuxRunner) Getfilecon(path string) (string, error) { return "", nil } + +// FileLabel returns the SELinux label for this path or returns an error. +func SetFileLabel(path string, label string) error { + return nil +}