Section 7.2. Constrain Statement


7.2. Constrain Statement

The constrain statement has three elements: a set of object classes to which the constraint applies, a set of permissions for those classes that are being constrained, and a Boolean expression of the constraint. Constraints are organized and stored within the policy by object class. You can see the full syntax for the constrain statement in the sidebar on page 152.

Constrain Statement Syntax

The constrain statement enables you to restrict specified permissions for specified object classes by defining constraints based on relationships between source and target security contexts. The full syntax for the constrain statement is as follows:

 constrain class_set perm_set expression ;


class_set

One or more object classes. Multiple object classes must be separated by spaces and enclosed in braces ({ })for example, {file lnk_file}. The special operators *, ~, and - are not allowed in class sets for this statement.

perm_set

One or more permissions. All permissions must be valid for all object classes in the class_set. Multiple permissions must be separated by spaces and enclosed in braces ({ })for example, {read create}. The special operators *, ~, and - are not allowed in permission sets for this statement.

expression

A Boolean expression of the constraint.


The Boolean expression syntax supports the following keywords:

t1, r1, u1

Source type, role, and user, respectively

t2, r2, u2

Target type, role, and user, respectively


Constraint expression syntax also support the following operators:

==

Set member of or equivalent

!=

Set not member of or not equivalent

eq

(Roles keyword only) equivalent

dom

(Roles keyword only) dominates

domby

(Role keyword only) dominated by

incomp

(Role keyword only) incomparable


The complete semantic meaning and allowed parameters for each operator is described in Table 7-1.

Constrain statements are valid only in monolithic policies and base loadable modules. They are not valid in conditional statements or non-base loadable modules.


The constrain statement lets you express constraints on any combination of the three elements of a security context (user, role, and type). Constraint expressions compare the contexts of the source (subject) process and the target (object) with each other and/or with explicit names (such as type or role identifiers).

Constraint expressions can be complex, but in practice are usually small and specifically targeted. Here is an example constraint:

constrain process transition (u1 == u2) ;


Let's take a closer look at this constraint. First, note that it applies to the process object class only, and only constrains the transition permission for processes. Recall that the transition permission is required to allow a domain transition; in effect, this constraint further restricts domain transitions.

Now let's look at the constraint expression (u1 == u2). The keywords u1 and u2 indicate, respectively, the source and target user identifiers for the security contexts. So, this expression resolves to true when the source and target user identifiers are the same. In the case of domain transitions, the source is the "current" security context, and the target is the "new" security context for the process.

Looking at the preceding constraint in its entirety, we see that it requires that the source and target user identifiers remain the same for all domain transitions. How? Recall the description of the access algorithm earlier. When a process requests transition permission, and the AVC calls the security server to determine allowed access for the triple source-target-class, the preceding constraint would become effective (for the process object class) and would check the user identifier in the source and target security contexts. If the user identifiers are not the same, the bit in the mask indicating transition permission is removed before the granted access mask is returned to the AVC.

Let's look at another example:

constrain process transition (r1 == r2) ;


This constraint is similar to the previous statement except that it constrains role identifiers rather than user identifiers. The keywords r1 and r2 indicate source and target role identifiers, respectively. This constraint requires that role identifiers not change on a domain transition in much the same way that the previous constraint requires user identifiers not to change.

Because these two constraints relate to the same object class and permission, the constrain expression syntax allows us to combine them into a single Boolean expression:

constrain process transition (u1 == u2 and r1 == r2) ;


This single statement is equivalent to the two previous statements. Either form will have the same effect of restricting user and role identifier changes relating to domain transitions.

Let's take our example a little further. In some situations, we want to allow the user and/or role identifier to change on a domain transition. For example, the login process needs to change the user and role identifiers to those of the user logging in. Another example is a program that allows you to change your role, which must be able to change the role identifier during a domain transition. In general, such programs are trusted processes, and we need a way to allow them to change user/role identifiers while ensuring that the constraint is active for all other programs.

To achieve this goal, let's first define a way to recognize those domain types that are trusted to change user and role identifiers. We do this via a type attribute. In particular, let's assume that there are two attributes defined in the policy: privuser and privrole. The former is associated with all types allowed to change user identifiers, and the latter with those allowed to change role identifiers. With these attributes, we can change our constraint as follows:

constrain process transition (u1 == u2 or t1 == privuser) ; constrain process transition (r1 == r2 or t1 == privrole) ;


In both statements, t1 refers to the source type (just as t2, if used, refers to the target type). The first statement allows the user identifier to be changed in a domain transition only if the source type has the privuser attribute. Likewise, the role can be changed if the source type has the privrole attribute.

Let's make sure you understand how attributes affect these constraints. Recall that the kernel expands attributes into the list of types that contain the attribute. So, to the kernel, the constraint really is a list of types rather than a single attribute. In the case of a list of types (or an attribute) on the right side of the operator, the == operator really means "is a member of" the set of types listed. Likewise the != means "is not a member of" the set of types. So, in our preceding example, the partial statement t1 == privuser really means "if the source type is in the list of types that have the privuser attribute."

Note

For constraint expressions, the left side of all operators must be one of the allowed keywords (for example, u1 or u2) and may never be a type, attribute, role, or user identifier (or list of identifiers). The right side of an operator may be a key word or one or more identifier names.


If the left and right sides of the operator are the role keywords r1 and r2, you have a few more role operators to choose from; specifically eq, dom, domby, and incomp, although these are rarely used. Table 7-1 summarizes the operators allowed for expressions in constrain statements.

Table 7-1. Allowed Arguments and Semantic Meaning for Constrain Expressions

Operator

Left Side

Right Side

Semantic Meaning

==

t1

t2

Source type equals target type.

t1 (t2)

type and/or attribute name(s)

Source (target) type is a member of the set of types indicated by names.

r1

r2

Source role equals target role.

r1 (r2)

role name(s)

Source (target) role is a member of the set of roles indicated by names.

u1

u2

Source user equals target user.

u1 (u2)

user name(s)

Source (target) user is a member of the set of users indicated by names.

!=

t1

t2

Source type does not equal target type.

t1 (t2)

type and/or attribute name(s)

Source (target) type is not a member of the set of types indicated by names.

r1

r2

Source role does not equal target role.

r1 (r2)

role name(s)

Source (target) role is not a member of the set of roles indicated by names.

u1

u2

Source user does not equal target user.

u1 (u2)

user name(s)

Source (target) user is not a member of the set of users indicated by names.

eq

r1

r2

Source role equals target role (exactly same semantics as r1 == r2).

dom

r1

r2

Source role was defined to dominate target role using role dominates statement.

domby

r1

r2

Target role was defined to dominate source role using role dominates statement.

incomp

r1

r2

Neither source nor target role dominates the other.





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