Reconstruct SELinux mount option
When reconstructing volumes from disk after kubelet restart, reconstruct also context=XYZ mount option and add it to the ActualStateOfWorld.
This commit is contained in:
@@ -116,3 +116,9 @@ func (hu *FakeHostUtil) GetSELinuxSupport(pathname string) (bool, error) {
|
||||
func (hu *FakeHostUtil) GetMode(pathname string) (os.FileMode, error) {
|
||||
return 0, errors.New("not implemented")
|
||||
}
|
||||
|
||||
// GetSELinuxMountContext returns value of -o context=XYZ mount option on
|
||||
// given mount point.
|
||||
func (hu *FakeHostUtil) GetSELinuxMountContext(pathname string) (string, error) {
|
||||
return "", errors.New("not implemented")
|
||||
}
|
||||
|
@@ -68,6 +68,9 @@ type HostUtils interface {
|
||||
GetSELinuxSupport(pathname string) (bool, error)
|
||||
// GetMode returns permissions of the path.
|
||||
GetMode(pathname string) (os.FileMode, error)
|
||||
// GetSELinuxMountContext returns value of -o context=XYZ mount option on
|
||||
// given mount point.
|
||||
GetSELinuxMountContext(pathname string) (string, error)
|
||||
}
|
||||
|
||||
// Compile-time check to ensure all HostUtil implementations satisfy
|
||||
|
@@ -299,3 +299,35 @@ func GetModeLinux(pathname string) (os.FileMode, error) {
|
||||
}
|
||||
return info.Mode(), nil
|
||||
}
|
||||
|
||||
// GetSELinuxMountContext returns value of -o context=XYZ mount option on
|
||||
// given mount point.
|
||||
func (hu *HostUtil) GetSELinuxMountContext(pathname string) (string, error) {
|
||||
return getSELinuxMountContext(pathname, procMountInfoPath, selinux.GetEnabled)
|
||||
}
|
||||
|
||||
// getSELinux is common implementation of GetSELinuxSupport on Linux.
|
||||
// Using an extra function for unit tests.
|
||||
func getSELinuxMountContext(path string, mountInfoFilename string, selinuxEnabled seLinuxEnabledFunc) (string, error) {
|
||||
// Skip /proc/mounts parsing if SELinux is disabled.
|
||||
if !selinuxEnabled() {
|
||||
return "", nil
|
||||
}
|
||||
|
||||
info, err := findMountInfo(path, mountInfoFilename)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, opt := range info.SuperOptions {
|
||||
if !strings.HasPrefix(opt, "context=") {
|
||||
continue
|
||||
}
|
||||
// Remove context=
|
||||
context := strings.TrimPrefix(opt, "context=")
|
||||
// Remove double quotes
|
||||
context = strings.Trim(context, "\"")
|
||||
return context, nil
|
||||
}
|
||||
return "", nil
|
||||
}
|
||||
|
@@ -331,3 +331,60 @@ func writeFile(content string) (string, string, error) {
|
||||
}
|
||||
return tempDir, filename, nil
|
||||
}
|
||||
|
||||
func TestGetSELinuxMountContext(t *testing.T) {
|
||||
info :=
|
||||
`840 60 8:0 / /var/lib/kubelet/pods/d4f3b306-ad4c-4f7a-8983-b5b228039a8c/volumes/kubernetes.io~iscsi/mypv rw,relatime shared:421 - ext4 /dev/sda rw,context="system_u:object_r:container_file_t:s0:c314,c894"
|
||||
224 62 253:0 /var/lib/docker/devicemapper/test/shared /var/lib/docker/devicemapper/test/shared rw,relatime master:1 shared:44 - ext4 /dev/mapper/ssd-root rw,seclabel,data=ordered
|
||||
82 62 0:43 / /var/lib/foo rw,relatime shared:32 - tmpfs tmpfs rw
|
||||
83 63 0:44 / /var/lib/bar rw,relatime - tmpfs tmpfs rw
|
||||
`
|
||||
tempDir, filename, err := writeFile(info)
|
||||
if err != nil {
|
||||
t.Fatalf("cannot create temporary file: %v", err)
|
||||
}
|
||||
defer os.RemoveAll(tempDir)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
mountPoint string
|
||||
seLinuxEnabled bool
|
||||
expectedContext string
|
||||
}{
|
||||
{
|
||||
"no context",
|
||||
"/var/lib/foo",
|
||||
true,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"with context with SELinux",
|
||||
"/var/lib/kubelet/pods/d4f3b306-ad4c-4f7a-8983-b5b228039a8c/volumes/kubernetes.io~iscsi/mypv",
|
||||
true,
|
||||
"system_u:object_r:container_file_t:s0:c314,c894",
|
||||
},
|
||||
{
|
||||
"with context with no SELinux",
|
||||
"/var/lib/kubelet/pods/d4f3b306-ad4c-4f7a-8983-b5b228039a8c/volumes/kubernetes.io~iscsi/mypv",
|
||||
false,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"no context with seclabel",
|
||||
"/var/lib/docker/devicemapper/test/shared",
|
||||
true,
|
||||
"",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
out, err := getSELinuxMountContext(test.mountPoint, filename, func() bool { return test.seLinuxEnabled })
|
||||
if err != nil {
|
||||
t.Errorf("Test %s failed with error: %s", test.name, err)
|
||||
}
|
||||
if test.expectedContext != out {
|
||||
t.Errorf("Test %s failed: expected %v, got %v", test.name, test.expectedContext, out)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -101,3 +101,9 @@ func (hu *HostUtil) GetMode(pathname string) (os.FileMode, error) {
|
||||
func getDeviceNameFromMount(mounter mount.Interface, mountPath, pluginMountDir string) (string, error) {
|
||||
return "", errUnsupported
|
||||
}
|
||||
|
||||
// GetSELinuxMountContext returns value of -o context=XYZ mount option on
|
||||
// given mount point.
|
||||
func (hu *HostUtil) GetSELinuxMountContext(pathname string) (string, error) {
|
||||
return "", errUnsupported
|
||||
}
|
||||
|
@@ -123,3 +123,9 @@ func (hu *HostUtil) GetMode(pathname string) (os.FileMode, error) {
|
||||
}
|
||||
return info.Mode(), nil
|
||||
}
|
||||
|
||||
// GetSELinuxMountContext returns value of -o context=XYZ mount option on
|
||||
// given mount point.
|
||||
func (hu *HostUtil) GetSELinuxMountContext(pathname string) (string, error) {
|
||||
return "", nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user