Section 4.4. Object Class Permission Examples


4.4. Object Class Permission Examples

To 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.

Access Revocation

The revocation of previously granted access is an important part of creating a flexible and dynamic security mechanism. Revocation is needed either when the policy changes or when the security context of an object is changed. For example, if the security context of a file is changed, processes that have that file open may no longer be allowed the same access to the file by the new policy. Mechanically, the system would have to revoke any existing access to the file if that access is not consistent with the change. Ensuring access revocation in all circumstances is a difficult task for any complex operating system.

SELinux supports revocation in many circumstances and provides much more access revocation support than standard Linux. For example, file access is checked on every read and write to a file; so if the security context of the file changes, the access is revoked on the next read or write attempt.

There are circumstances where access is not revoked (for example, with memory-mapped file access and outstanding asynchronous I/O requests). It is likely that revocation support will increase in SELinux, but it is unlikely that full coverage can be achieved. This is partly due to the nature of the UNIX application programming interfaces (APIs), partly due to community resistance to invasive changes to certain kernel subsystems, and partly due to the inherent complexity of the task.

In general, you can avoid most revocation issues by designing systems that do not relabel objects. SELinux provides permissions (relabelfrom and relabelto) to restrict this ability.


4.4.1. File Object Class Permissions

Table 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.

Table 4-5. File Object Class Permissions

Permission

Description

append

Append to file contents (that is, opened with O_APPEND flag).

create

Create new file.

entrypoint*

File can be used as the entry point of the new domain via a domain transition.

execmod*

Make executable a file mapping that has been modified (implied by a copy-on-write).

execute

Execute; corresponds to x access in standard Linux.

execute_no_trans*

Execute file in the caller's domain (that is, without a domain transition).

getattr

Get attributes for file, such as access mode (for example, stat, some ioctls).

ioctl

ioctl(2) system call requests not addressed by other permissions.

link

Create hard link to file.

lock

Set and unset file locks.

mounton

Use as mount point.

quotaon

Allow file to be used as a quota database.

read

Read file contents; corresponds to r access in standard Linux.

relabelfrom

Change the security context from the existing type.

relabelto

Change the security context to the new type.

rename

Rename a hard link.

setattr

Change attributes for file such as access mode (for example, chmod, some ioctls).

swapon

Deprecated; was used to allow file to be used for paging/swapping space.

unlink

Remove hard link (delete).

write

Write file contents; corresponds to w access in standard Linux.


4.4.1.1. Standard Linux Permissions

The 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 Control

One 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 Permissions

There 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 Permissions

Table 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.

Table 4-6. Process Object Class Permissions

Permissions

Description

dyntransition

Allow a process to dynamically transition to a new context.

execheap

Make the heap executable.

execmem

Make executable an anonymous mapping or private file mapping that is writable.

execstack

Make the process stack executable.

fork

Fork into two processes.

getattr

Get attributes of a process through the /proc/[pid]/attr/ directory.

getcap

Get Linux capabilities allowed for this process.

getpgid

Get group process ID of process.

getsched

Get priority of process.

getsession

Get session ID of process.

noatsecure

Disable secure mode environment cleansing. Allows process to disable secure mode feature of glibc on execve(2).

ptrace

Trace program execution of parent or child.

rlimitnh

Inherit process resource limits on execve(2).

setcap

Set Linux capabilities allowed for this process.

setcurrent

Set the current process context. This is the first capability checked when a process tries to perform a dynamic domain transition.

setexec

Override the default context for the next execve(2).

setfscreate

Allow a process to set the context of an object created by the process to something other than the default context.

setpgid

Set group process ID of process.

setrlimit

Change process hard resource limits.

setsched

Set priority of process.

share

Allow state sharing with cloned or forked process.

siginh

Inherit signal state on execve(2).

sigkill

Send SIGKILL signal.

sigchld

Send SIGCHLD signal.

signal

Send a signal other than SIGKILL, SIGSTOP, or SIGCHLD.

signull

Test for existence of another process without sending a signal.

sigstop

Send SIGSTOP signal.

TRansition

Transition to a new context on execve(2).


4.4.2.1. Process Creation

The 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 Transition

As 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.

[4] The only limitation to when dynamic context transitions can occur is that they cannot occur while a process has more than one thread running. This is to prevent a multithreaded process from having a different security context for each thread, which is an even weaker domain separation than offered by the current dynamic context transition. You can find the discussion of dynamic context transitions that occurred when it was introduced into SELinux at www.nsa.gov/selinux/list-archive/0411/9364.cfm. Included is information about multithreaded applications and dynamic context transitions.

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 Creation

Like 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 Signaling

The 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 Attributes

The 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 Memory

As 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]

[5] ExecShield is a Red Hat-developed kernel patch to control memory execution and add other security features. It is included in all Fedora releases and Red Hat Enterprise Linux since version 3. See www.redhat.com/f/pdf/rhel/WHP0006US_Execshield.pdf for a description.

[6] NX is a hardware feature that accomplishes many of the same goals as ExecShield. A description is available at http://en.wikipedia.org/wiki/NX_bit.




SELinux by Example(c) Using Security Enhanced Linux
SELinux by Example: Using Security Enhanced Linux
ISBN: 0131963694
EAN: 2147483647
Year: 2007
Pages: 154

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net