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:
Jan Safranek
2022-11-03 17:40:16 +01:00
parent 95bd687a28
commit e575e60ea4
16 changed files with 225 additions and 28 deletions

View File

@@ -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")
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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)
}
}
}

View File

@@ -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
}

View File

@@ -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
}