Section 5.4. Type Rules


5.4. Type Rules

Type rules specify default types for objects created or relabeled at runtime. We have already seen one example of this in Chapter 2 in the form of default domain transitions using the type_transition rule. There are two type rules defined in the policy language:

type_transition

Specifies default type labeling behavior for domain transition and object creation

type_change

Specifies default types for relabeling performed by SELinux-aware applications


We call these rules "type rules" because they are similar to AV rules except that the last field in the rule is a type name rather than a list of permissions.

5.4.1. Common Type Rule Syntax

As with AV rules, each of the type rules has a different purpose and semantics, but they all share common syntax. Each type rule has five elements:

Rule name

type_transition or type_change

Source type(s)

The type(s) of the creating or owning process

Target type(s)

The type(s) of the object containing the new or relabeled object

Object class(es)

The class(es) of object(s) being created or relabeled

Default type

The single default type for the new or relabeled object


The full syntax for the type rules is in the sidebar on page 117.

Much of the type rule syntax is similar to AV rules, but there are important differences. First, there are no permissions. Unlike AV rules, type rules do not specify access or auditing, so there is no need for permissions. The second major difference is that the object class is not associated with the target types. Instead, the object class refers to the objects that will be labeled with the default type.

The simplest form of a type rule has one source, target, and default types, and one object class, as follows:

type_transition user_t passwd_exec_t : process passwd_t;


This rule, which you saw in Chapter 2, specifies that when a process of type user_t executes a file of type passwd_exec_t, the process type will attempt to transition, by default, to passwd_t unless otherwise requested. The target type is implicitly associated with the file object class when the stated object class is process. The stated object class (process) is associated with the source and default types. This subtle and implicit association is easy to overlook, even after you become an experienced policy writer.

As with AV rules, we can specify more than one object class by using a space-separated list enclosed in braces. Likewise, we can use attributes, and lists of types and attributes in type rules, as follows:

type_transition { user_t sysadm_t } passwd_exec_t : process passwd_t;


This type_transition rule includes two types, user_t and sysadm_t, in the source list. As with AV rules, this rule would be expanded into two rules. The preceding rule has the exact same meaning as the following two rules:

# These two rules... type_transition user_t passwd_exec_t : process passwd_t; type_transition sysadm_t passwd_exec_t : process passwd_t; # are equivalent to this single rule. type_transition { user_t sysadm_t } passwd_exec_t : process passwd_t;


The use of attributes also works the same as in AV rules.

Unlike source and target type fields, attributes and/or multiple types cannot be used for the default type. The reason for this restriction is clear when you understand the purpose of this rule (that is, to specify a single default type). If we could list more than one default type, the rule would be ambiguous and it would be impossible for the kernel to determine which default type to use.

The restriction for a single default type also means that we cannot have two separate type rules that have the same source, target, and object class, as this would be semantically equivalent to two default types. For example, the following two rules would conflict:

# These two rules conflict and will cause a compile-time problem type_transition user_t passwd_exec_t : process passwd_t; type_transition user_t passwd_exec_t : process user_passwd_t;


The policy compiler generates an error if both of these rules are present in a policy. These conflicting type_transition rules also make the reason for the restriction clear. If both rules were present, which type, passwd_t or user_passwd_t, would be used for the default type?

Common Type Rule Syntax

The full common syntax for type rules is as follows:

rule_name  type_set  type_set : class_set  default_type;


rule_name

The name of the type rule. Valid rule names are type_transition, type_change, and type_member.

type_set

One or more types or attributes. There is a separate type_set for each of the source and target types of the rules. Multiple types and attributes are specified using a space-separated list enclosed in braces ({ })for example, { bin_t sbin_t }. Types can be excluded from the list by prepending - to the type name (for example, { exec_type -sbin_t }).

class_set

One or more object classes. Multiple object classes must be enclosed in braces ({ })for example, { file lnk_file }.

default_type

A single type that is the default for the newly created or relabeled object. Attributes or multiple types cannot be used.


All type rules are valid in monolithic policies, base loadable modules, non-base loadable modules, and conditional statements.


5.4.2. Type Transition Rules

We use type_transition rules to specify default type labeling rules for certain events. Currently, there are two forms of the type_transition rule. The first supports default domain transition events, which is the form of type_transition rule introduced in Chapter 2. The second form of this rule supports object transitions, which allow us to specify default object labeling.

Both forms of the type_transition rule help make the enhanced security of SELinux transparent to the Linux user. In SELinux, by default, newly created objects receive the type of their containing object (for example, directory), and processes inherit the type of their parent process. The type_transition rule enables us to override these defaults. This is useful, for example, to ensure that when the password program creates a file in the /tmp/ directory, that its file is given a different type than those of ordinary users.

The type_transition rule does not allow access; it provides only a new type labeling default. A successful type transition always requires the associated set of allow rules that permit the process type the ability to create the object and label the object as specified. In addition, the default labeling specified in type_transition rules takes effect only if the creating process does not explicitly override the default labeling behavior.

5.4.2.1. Default Domain Transitions

Let's examine the domain transition form of this rule in more detail. Domain transitions change the type of a process when executing a file. For example, look at this rule:

type_transition init_t apache_exec_t : process apache_t;


This type_transition rule states that when processes of type init_t execute a file of type apache_exec_t the process type should be changed to apache_t. The object class process is the only indication that this is a domain transition form of the rule. Figure 5-1 shows a domain transition. Domain transitions actually change the type of an existing process instead of labeling a newly created process. This is because in Linux a new process is created by first making a copy of an existing process using the fork() system call. If the process type were changed on fork, it would allow the calling domain to execute arbitrary code in the new domain. It is much safer for the domain transition to happen when executing a new program via the execve() system call.

Figure 5-1. A depiction of a default domain transition


Warning

Recent versions of SELinux introduced the process object class permission dyntransition. This permission, which was added primarily for compatibility with other systems, allows a process to change its domain type at request instead of just on execute. This type of process transition is not safe because it allows the calling domain to execute arbitrary code in the new domain, destroying the separation between the two domains. In addition, the same functionality can often be achieved using other, safer mechanisms. We recommend that you never use this permission in your policies unless you are building a userspace object manager or if you are absolutely sure it is required.


As mentioned previously, a type transition can occur only if the policy allows the associated access. For a domain transition to succeed, the policy must allow at least three accesses:

  • execute The source type (init_t) must have execute permission for files with the target type (apache_exec_t).

  • transition The source domain (init_t) must have TRansition permission to the default type (apache_t).

  • entrypoint The new (default) type (apache_t) must have entrypoint permission to files with the target type (apache_exec_t).

The domain transition above would require at least the following allow rules to succeed:

# This domain transition rule... type_transition init_t apache_exec_t : process apache_t; # would require at least the following 3 allow rules to succeed allow init_t apache_exec_t : file execute; allow init_t apache_t : process transition; allow apache_t apache_exec_t : file entrypoint;


In practice, we will likely want to allow additional access beside the above minimum. For example, it is common to allow the default type to signal the source type upon exit (that is, sigchld permission), inherit file descriptors, and communicate using pipes.

The key concept with domain transitions is that there is a clearly defined entry pointthat is, the file labeled with the type (apache_exec_t) for which the new (default) type (apache_exec_t) has enTRypoint permission. The entry point file allows us to strictly control which programs may execute in which domains (arguably the security trait that makes type enforcement so strong). We know that the only program that can be used to enter a given domain is that program whose executable file is labeled with a type to which the domain has entrypoint access. Thus we can know and control which programs have which privileges.

5.4.2.2. Default Object Transitions

Object transition rules specify a default type for newly created objects. In practice, we commonly use this form of the type_transition rule primarily for filesystem-related objects (for example, file, dir, lnk_file). Like domain transitions, these rules cause only a default object labeling to be attempted; the attempt can succeed only if the policy allows the associated access.

Object transition rules are identified by object class, as follows:

type_transition passwd_t tmp_t : file passwd_tmp_t;


This type_transition rule states that when a process of type passwd_t creates an ordinary file (file object class) in a directory of type tmp_t the file, by default, should have the type passwd_tmp_t if allowed by the policy. Notice that the object class refers not to the target type (tmp_t) but to the default type (passwd_tmp_t). In this example, tmp_t is implicitly associated with the dir object class because that is the only object class that can contain files. Also, as before, the policy must allow the access for the default labeling to occur. Access required for the preceding example includes add_name, write, and search for directories of type tmp_t, and write and create for files of type passwd_tmp_t.

This example is typical and shows one technique for solving the security problems inherent in a directory shared by many applications such as a temporary directory. Object transition rules are useful for any objects that will be created at runtime and need to have types other than that of the containing object.

Some circumstances cannot be handled with object transition rules. Whenever a process needs to create objects with multiple different types in the same container object, a type_transition rule is not sufficient. For example, consider a process that creates two UNIX domain sockets in /tmp/ that will be used by other domains for communication. If we want to give each sock file a different type, object transition rules would not suffice. We would end up with two rules with the same source, target, and object class and a different default type, which would result in a compiler error. The possible solutions to this problem are to create the sock files at installation time and explicitly label them, place the sock files in separate directories with different directory types, or have the process explicitly request types on creation.

5.4.3. Type Change Rules

We use a type_change rule to specify default types for relabeling performed by SELinux-aware applications. Like type_transition rules, type_change rules specify labeling defaults but do not allow access. Unlike type_transition rules, the effects of type_change rules are not implemented in the kernel but rely on userspace applications, such as login or sshd, to relabel objects based on the policy. For example, consider this rule:

type_change sysadm_t tty_device_t : chr_file sysadm_tty_device_t;


This type_change rule states that when relabeling a character file of type tty_device_t on behalf of sysadm_t, the type sysadm_tty_device_t should be used.

This rule is an example of the most common use for type_change rulesthat is, relabeling a terminal device on user login. The login program would query the policy via a kernel interface to the SELinux module, passing in the types sysadm_t and tty_device_t and receiving the type sysadm_tty_device_t as the type to use for the relabel change. This mechanism allows the login process to label the tty device on behalf of the user during a new login session while leaving the specifics of the types encapsulated in the policy instead of hard-coded in the application.

We will probably seldom, if ever, write type_change rules because they are usually used only by core operating system services.

type_member Rule

The policy compiler also supports a third type rule, type_member. Currently, this rule has no semantic meaning and if used will have no effect. We mention it here because at the time of writing, work is ongoing that would create a need for it. A type_member rule is intended to support specifying the type for members of a polyinstantiated object. The type_member rule will be enabled with meaningful semantics. The syntax of this rule is the same as the other two type rules.





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