Kernel Korner - Filesystem Labeling in SELinux
EAs can be managed manually with the getfattr(1) and setfattr(1) utilities. For example, to view the SELinux security context label of a file:
$ getfattr -n security.selinux /tmp/foo getfattr: Removing leading '/' from absolute path names # file: tmp/foo security.selinux="root:object_r:sysadm_tmp_t\000"
Notice the specification of the EA security namespace. A wrapper utility called getfilecon(1) is provided for use with SELinux. It saves you from having to specify the EA namespace, and it has a cleaner output.
The use of text-based labels ensures that meaningful, human-readable security attributes are stored along with the file data. These labels can be preserved or translated if the filesystem is mounted on a different system, possibly with a different security policy. A counter example is the way the owner of a file is stored as a numeric UID in the file's inode. The UID typically is mapped to a meaningful value by way of /etc/passwd; it may not have the same meaning on a different system.
For a filesystem to support SELinux security context labels, it needs EA support and a handler for the EA security namespace. Such filesystems currently include ext3, ext2, XFS and ReiserFS; the last uses an external patch. In addition, the devpts filesystem has a dummy security handler that allows EA-based access to the in-kernel labels of ptys.
So, when are files labeled? During an SELinux system installation, the setfiles(8) utility typically is used to label all of the files in filesystems that support EA security labeling. Package management tools such as RPM also may label files during installation, while system administrators often need to set security contexts manually with chcon(1) or setfilecon(1).
Evolution of SELinux Filesystem Labeling
The first release of SELinux in 2000 used a different mechanism for labeling filesystems than is used by the extended attributes approach discussed in this article. Persistent security IDs (PSIDs), integer representations of security context labels, were stored in an unused field of the ext2 inode. Mapping files on each filesystem were used by SELinux to look up a file's PSID by inode and then to map the PSID to a security context label.
This approach had the disadvantage of needing to modify each filesystem separately to support PSIDs. Thus, it was not a good general solution for extended security in the upstream kernel.
With the LSM Project, a generalized access control framework was implemented for the Linux kernel. As no filesystem-specific hooks are used in LSM, SELinux moved away from the modified filesystem approach and stored PSIDs in a normal file next to the mapping files. This allowed SELinux to be used purely as an LSM application with no kernel patching. It also allowed labeling to work for more filesystems, but it was not optimal in terms of performance and consistency. Accessing files from within the kernel remains generally problematic.
As part of the process of merging SELinux into the mainline kernel, with more feedback from the community, SELinux moved to the current filesystem labeling model based on extended attributes. Extended attributes provide applications with a standard API, eliminating the need for custom system calls to manipulate security labels, while filesystems also can be used similarly by other security modules, even on the same filesystem, using the separation provided by EA namespaces.
When a file is created, a matching rule in the security policy typically describes how to assign a label based on the security contexts of the parent directory and the current task. Here's an example:
$ id -Z root:staff_r:staff_t $ ls -dZ /tmp drwxrwxrwt+ root root system_u:object_r:tmp_t /tmp $ touch /tmp/hello $ getfilecon /tmp/hello /tmp/hello root:object_r:staff_tmp_t
In this case, the security policy contains a rule that states files created by staff_t in a directory labeled tmp_t must be labeled with the type staff_tmp_t. If there is no explicit rule, files are labeled with the context of the parent directory.
Privileged applications can override the above-stated rule by writing a security context to /proc/self/attr/fscreate. This security context then is used to label any newly created files. The setfscreatecon(3) library function encapsulates this operation.
Unlabeled files may exist if a filesystem has not been labeled properly before use or if files are created on a filesystem when SELinux is not enabled. In case of the latter, the SELinux kernel internally assigns a default context to unlabeled files for AVC calls, but it does not attempt to relabel them on disk. To restore a security context label manually, use restorecon(8).
An fsck-like utility is being developed for managing the scenario where unlabeled files have been created. To be run on boot, this utility will ensure that all files are labeled correctly before the system enters multiuser mode.