4.4. Object Class Permission ExamplesTo provide a greater understanding of how permissions control access to system resources, let's further discuss the permissions for two object classes: file and process. We provide a detailed description of all permissions for each object class in Appendix C.
4.4.1. File Object Class PermissionsTable 4-5 lists the permissions for the file object class. Most of the permissions are common to all file-related object classes; only execute_no_trans, entrypoint, and execmod are specific to the file object class (these are marked with a an asterisk, *). There are three categories of permissions for the file object class: permissions that map directly to standard Linux access control permissions, extensions of the standard Linux permissions, and SELinux-specific permissions.
4.4.1.1. Standard Linux PermissionsThe permissions read, write, and execute correspond loosely to the standard Linux permissions read, write, and execute (that is, r, w, and x). There are some differences from the standard permission checks. In standard Linux, access is usually checked only when the file is opened. In SELinux, access is checked on every use when feasible. The read and write permissions are checked both at file open and on each subsequent read or write operation. The read permission covers the ability to read a file in its entirety. It includes the permissions to access the file in a random access manner. The write permission includes the permission to write to a file, including appending. Like read permission, write permission covers random access writing. The read and write permissions are also checked when a file is memory mapped, for example, mmap(2) system call, or the protections on an existing mapping are changed with mprotect(2) system call. The execute permission controls the ability to execute the file using the execve(2) system call. It is required regardless of whether there is a domain transition (see exec_no_trans below). The execute permission is also required to successfully use a file as a shared library. 4.4.1.2. Extensions to the Standard Linux Access ControlOne of the benefits of SELinux is that it provides additional permissions that give a finer granularity of control than what is available with standard Linux. In standard Linux, the ability to create a file is governed by the ability to write to the containing directory. In SELinux, the create permission directly controls the ability to create a file of a specific SELinux type. Using this permission, we can allow a domain type to create files of type etc_t, but not of type shadow_t. Like many permissions in SELinux, the file create permission is necessary but not sufficient. For example, the creating domain type must also have permission to create objects in the containing dir object and the permissions to create permission the file object. We likely require write permission for the object class to which we give create permission for any practical application. The ability to view or modify file attributes, including permission modes and ownership information, is controlled separately with the getattr and setattr permissions. The getattr permission controls the reading of file attributes (for example, using the stat(2) system call). The setattr permission controls the writing of file attributes (for example, using the chmod(2) system call). Locking files, either via the flock(2) or fnctl(2) system calls, is controlled by the lock permission. No other permissions are required to obtain the lock, though practically you are required to have read, write, or append permission to obtain a file descriptor to pass to the relevant locking system call. It is often useful to allow append-only access to a file. For example, it is important that log files can never be overwritten to prevent attackers from erasing evidence. SELinux provides the separate append permission, which strongly enforces the O_APPEND mode for open. Allowing a domain type append permissions without write permissions means that process with that domain type can only add data to a file. Just as creation is controlled separately with the create permission, creating and removing hard links to a file is controlled with the link and unlink permissions. In Linux, files can be referenced by one or more names, called hard links. There is no "real" name for a file; all hard links are equally valid names for a file. There are many security implications to this semantic of Linux filesystems. Unlinking a file, which is controlled by the unlink permission, is essentially deleting a file (although if there are multiple hard links that file will in fact not be deleted, just that name). Likewise, linking a file, controlled by the link permission, is really creating a new name for a file. The ability to change the name of a hard link, using the rename(2) system call, is controlled by a third permission, rename. All three hard link-related permissions require additional permissions on the effected directories to successfully complete. The final extended permissions for files are mounton, quotaon, and swapon. The mounton permission controls the ability to mount (mount(2) system call) using the file as a mount point. It is more common to use directories as a mount point; when performing bind mounts (MS_BIND), however, it is possible to use a file as a mount point. The quotaon permission controls the use of a file to store quota information. When turning quotas on using the quotactl(2) system call (Q_QUOTAON), the path of the file used to store the quota information is provided. The calling process domain type must have quotaon permission to that file to successfully complete the system call. 4.4.1.3. SELinux Specific PermissionsThere are five SELinux specific permissions for files: relabelfrom, relabelto, execute_no_trans, enTRypoint, and execmod. The relabelfrom and relabelto permissions control the capability of a domain type to change the type of a file from one type to another type, respectively. To successfully relabel a file, a domain type must have relabelfrom permission for file objects of the current type and relabelto permission for file objects of the new type. Notice that these permissions do not allow control over the exact pairs of permissions; a domain can relabel from any type for which it has relabelfrom permission to any type for which it has relabelto permission. It is possible to add contraints on relabeling, as you will see with the validatetrans rule in Chapter 7, "Constraints." Relabeling objects is a potentially dangerous operation to the security of the system and should be tightly controlled. The execute_no_trans permission allows a domain to execute a file without a domain transition. This permission is not sufficient to execute a file; the execute permission is also required. Without the execute_no_trans permission, a process may execute only the file with a domain transition. We want to exclude execute_no_trans permission if we want to ensure that an execution will always cause a domain transition (or fail). For example, when the login process executes a shell for a user login, we always want the shell process to transition from the privileged login domain type. The entrypoint permission, which we discussed in the description of domain transitions in Chapter 2, controls the ability to use the executable file to allow a domain type transition. The execute, execute_no_trans, and entrypoint permissions allow fine-grained control over what code can execute with what domain type. SELinux's capability to control the domain type of individual programs is a primary reason for its capability to provide strong yet flexible security. The execmod permission controls the ability to execute memory-mapped files that have been modified in the process memory. This is most useful in preventing shared libraries from being modified within a process. Without this permission, if a memory mapped file is modified in memory, the process will no longer be able to execute the file. 4.4.2. Process Object Class PermissionsTable 4-6 list the process object class permissions. Unlike the file permissions, many of the process permissions do not directly correspond to standard Linux access controls as Linux does not traditionally treat processes as formal objects.
4.4.2.1. Process CreationThe fork permission controls the ability of a process to use the fork(2) system call. This system call creates a copy of the process that differs only in its process identifier and resource utilization data. The security context of a process does not change as the result of forking. Forking is usually the first step in executing a new program. Controlling the ability of a process to fork limits its ability to use system resources and can potentially prevent certain types of denial-of-service attacks. Three additional permissions control the sharing of state on process transition. The share permission controls sharing of process state, such as file descriptors and memory address space, on a execve(2) system call. The siginh permission controls the inheritance of signal state, including any pending signals. Finally, the rlimitnh permission controls the inheritance of resource limits from the parent process. 4.4.2.2. Process Domain Type TransitionAs described for domain transitions in Chapter 2, the transition permission controls the ability of a process in one domain to transition into another via the execve(2) system call. A domain transition can occur, if allowed, automatically as a result of a type_transition rule or when explicitly requested. The ability to request an explicit transition is controlled by the setexec permission. Programmatically, this request is made by writing to a special file in the proc filesystem. This procedure is abstracted in the setexeccon(3) library function. The ability to see the currently requested transition for the next call to execve(2) system call is controlled by the getattr permission. The noatsecure permission causes the kernel to not set the secure mode of glibc on a domain transition. In secure mode, glibc cleanses the process environment, including powerful environment variables such as LD_PRELOAD. Without cleansing the environment the source domain can potentially control critical aspects of the target domain. Allowing the noatsecure permission is especially dangerous when the domain transition is into a more privileged domain. The dyntransition permission is similar to the transition permission but controls the ability to change the domain type on a process at any time, [4] not just when executing an application. This permission is much more dangerous than the transition permission because it allows the starting domain to always execute arbitrary code in the new domain. For this reason, the dyntransition permission can safely be used only to transition to a domain with a strict subset of the access of the starting domain. Otherwise, the perceived protection of the domain change is false, and any access granted to the target domain must be assumed to be accessible to the starting domain.
Warning The ability to change the process domain type arbitrarily using the dyntransition permission for process object class breaks the important property of label tranquility. In SELinux, label tranquality simply means that in a running system, after an object is created, its type will not change. Although there always exists a need for trusted operating system components to occasionally change types of objects, SELinux has traditionally tightly controlled type changes for processes with the domain transition concept. The introduction of dyntransition permission breaks this property, which greatly complicates any security analysis of the policy. We highly recommend that you never use this permission unless you are writing userspace object managers or other SELinux extensions. The setcurrent permission for the dyntransition permission is analogous to the setexec permission for the transition permission. It controls the ability to request the change of the process domain type. Successfully changing the domain type requires the dyntransition permission in addition to the setcurrent permission. Like setexec, the request is made by writing to a special file in the proc filesystem. This procedure is abstracted in the setcon(3) library function. 4.4.2.3. File CreationLike domain transitions, the setting of the security context of file-related objects created by a process can either be automatic, through inheritance or type_transition rules, or explicit. A program explicitly sets the context for file-related objects by writing to special files in the proc filesystem. This procedure is abstracted in the setfscreatecon(3) library call. The setfscreate permission controls the ability to make this explicit request. Like setexeccon, the ability to see the current state of the filesystem object context request is controlled by the gettattr permission. 4.4.2.4. Process SignalingThe ability to signal processes can be powerful because it potentially allows for the termination or stopping of processes. In addition, signaling can be used to transfer information between two processes. The sigchld, sigkill, and sigstop permissions control the ability to send the SIGCHLD, SIGKILL, and SIGSTOP signals, respectively. The signull permission controls the ability to send a null signal, for example, by passing 0 as the signal argument for the kill(2) system call. Finally, the signal permission controls the ability to send all other signals. There are a couple reasons why some signals have an explicit permission defined and the rest are grouped under the general signal permission. Two signal, SIGKILL and SIGSTOP, were given an explicit permission because they cannot be blocked by a process. The SIGCHLD signal has its own permission primarily because it is used pervasively (for example, often from every process to init). The rest have the same security properties, so they were grouped under the signal permission. 4.4.2.5. Process AttributesThe ability to query or set the scheduling priority and policy for a process is controlled by the getsched and setsched permissions. Setting scheduling priority and policy, particularly setting the SCHED_FIFO policy, with the sched_setscheduler(2) system call can allow a process to take up possibly unlimited amounts of CPU time. This can be used to for denial-of-service attacks. The process group and session identifiers control many aspects of a process' interaction with its environment, including terminal handling and signal delivery. The getpgid and setpgid permissions control the querying and setting of the process group identifier for the process. The getsession permission controls querying of the session identifier. The getcap and setcap permissions control querying and setting Linux capabilities for the process. To successfully set a capability, the capability must also be allowed for the capability object class labeled with the domain type of the process. Resource limits, such as the maximum core dump size or CPU time, are set using the setrlimit(2) system call. The setrlimit permission controls the ability to set hard resource limits. 4.4.2.6. Executing Writable MemoryAs mentioned during the discussion of the execmod permission of the file object class, the ability to execute writable segments of memory is a source of many security concerns. To help address these concerns the execmem, execstack, and execheap permissions were created. They control the creation of executable anonymous mappings, stacks, and heaps, respectively. The enforcement of the permissions relies on additional software, such as ExecShield, [5] hardware features, such as NX. [6]
|