This section covers how file system security contexts are defined and stored.
SELinux stores file security labels in xattrs[1]. For more information about xattrs, read the manual pages for attr(5), getfattr(1), and setfattr(1). Xattrs are stored as name-value property pairs associated with files. SELinux uses the security.selinux attribute. The xattrs can be stored with files on a disk or in memory with pseudo file systems. Currently, most file system types support the API for xattr, which allows for retrieving attribute information with getxattr(2).
Some non-persistent objects can be controlled through the API. The pseudo-tty system controlled through /dev/pts is manipulated through setxattr(2), enabling programs such as sshd to change the context of a tty device. Information about the tty is exported and available through getxattr(2). However, libselinux provides a more useful set of functions layered on top of the xattr API, such as getfilecon(3), setfilecon(3), and setfscreatecon(3).
Tip | |
---|---|
It is recommended to use libselinux when managing file attributes in SELinux programmatically. |
There are two approaches to take for storing file security labels on a file system, such as ext2 or ext3. One approach is to label every file system object (all files) with an individual security attribute[2]. Once these labels are on the file system, the xattrs become authoritative for holding the state of security labels on the system.
The other option is to label the entire file system with a single security attribute. This is called genfs labeling. One example of this is with ISO9660 file systems, which are used for CD-ROMs and .iso files. This example from $SELINUX_SRC/genfs_contexts defines the context for every file on an ISO9660 file system.
genfscon iso9660 / system_u:object_r:iso9660_t |
The file genfs_contexts has labels to associate with the most common mounted file systems that do not support xattrs.
You can set the context at the time of mounting the file system with the option -o context=<user>:<role>:<type>. A complete list of file system types can be found at $SELINUX_SRC/types/file.te. This option is also known as mountpoint labeling and is new in the 2.6.x kernel. Mountpoint labeling occurs in the kernel memory only, the labels are not written to disk. This example overrides the setting in genfs_contexts that would normally mount the file system as nfs_t:
mount -t nfs -o context=user_u:object_r:user_home_t \ <hostname>:/shares/homes/ /home/ |
The -o context= option is useful when mounting file systems that do not support extended attributes, such as a floppy or hard disk formatted with VFAT, or systems that are not normally running under SELinux, such as an ext3 formatted disk from a non-SELinux workstation. You can also use -o context= on file systems you do not trust, such as a floppy. It also helps in compatibility with xattr-supporting file systems on earlier 2.4.<x> kernel versions. Even where xattrs are supported, you can save time not having to label every file by assigning the entire disk one security context.
Two other options are -o fscontext= and -o defcontext=, both of which are mutually exclusive of the context option. This means you can use fscontext and defcontext with each other, but neither can be used with context.
The fscontext option works for all file systems, regardless of their xattr support. The fscontext option sets the overarching file system label to a specific security context. This file system label is separate from the individual labels on the files. It represents the entire file system for certain kinds of permission checks, such as during mount or file creation. Individual file labels are still obtained from the xattrs on the files themselves. The context option actually sets the aggregate context that fscontext provides, in addition to supplying the same label for individual files.
You can set the default security context for unlabeled files using defcontext. This overrides the value set for unlabeled files in the policy and requires a file system that supports xattr labeling. This example might be for a shared volume that gets file drops of security quarantined code, so the dropped files are labeled as being unsafe and can be controlled specially by policy:
mount -t ext3 defcontext=user_u:object_r:insecure_t \ /shares/quarantined |
This all works because SELinux acts as a transparent layer for the mounted file system. After parsing the security options, SELinux only passes normal file system specific code to the mounted file system. SELinux is able to seamlessly handle the text name-value pairs that most file systems use for mount options. File systems with binary mount option data, such as NFS and SMBFS, need to be handled as special cases. Currently, NFSv3 is the only one supported.
SELinux uses LSM hooks in the kernel in key locations, where they interject access vector decisions. For example, there is a hook just prior to a file being read by a user, where SELinux steps from the normal kernel workflow to request the AVC decision. This mainly occurs between a subject (a process such as less) and an object (a file such as /etc/ssh/sshd_config) for a specific permission need (such as read).
Based on the result read back from the AVC, the hook either continues the workflow or returns EACCES, that is, Permission denied.
The way SELinux implements its label in the xattr is different from other labeling schemes. SELinux stores its labels in human-readable strings. This provides a meaningful label with the file that can help in backup, restoration, and moving files between systems. Standard attributes do not provide a label that has continuous meaning for the file.
In this example under the targeted policy, the policy does not specify anything about files created by unconfined_t in the directory /tmp, so the files inherit the context from the parent directory:
id -Z root:system_r:unconfined_t ls -dZ /tmp drwxrwxrwt root root system_u:object_r:tmp_t /tmp/ touch /tmp/foo ls -Z /tmp/foo -rw-r--r-- root root root:object_r:tmp_t /tmp/foo |
In this example under a different policy, the policy explicitly states that files created by user_t in /tmp have a type of user_tmp_t:
id -Z user_u:staff_r:user_t ls -dZ /tmp drwxrwxrwt usera usera system_u:object_r:tmp_t /tmp/ touch /tmp/foo ls -Z /tmp/foo -rw-r--r-- usera usera root:object_r:user_tmp_t /tmp/foo |
This finer grained control is implemented via policy using the tmp_domain() macro, which defines a temporary type per domain. In this macro, the variable $1_tmp_t is expanded by substituting the subject's type base, so that user_t creates files with a type of user_tmp_t.
Having separate types for /tmp/ protects a domain's temporary files against tampering or disclosure by other domains. It also protects against misdirection through a malicious symlink. In the targeted policy, the confined daemons have separate types for their temporary files, keeping those daemons from interfering with other /tmp/ files.
A privileged application can override any stated labeling rule by writing a security context to /proc/self/attr/fscreate using setfscreatecon(3). This action must still be allowed by policy. The context is then used to label the next newly created file object, and the fscreate is automatically reset after the next execve or through setfscreatecon(NULL). This ensures that a program starts in a known state without having to be concerned what context was left by the previous program in /proc/self/attr/fscreate.
[1] | Extended attributes are also called EAs. To be more concise, the term xattr is used in this guide. |
[2] | These are defined initially for the system in $SELINUX_SRC/file_contexts/types.fc. This file uses regular expression matching to associate the files on a particular path with a particular security label. These contexts are rendered into the installed version at /etc/selinux/targeted/contexts/files/file_contexts, and are used during installation of the operating system and software packages, or for checking or restoring files to their original state. |