Towards a Formal Model for Security Policies ... - CiteSeerX

10 downloads 7897 Views 251KB Size Report
A security policy for SELinux is complex and large: it is made by many configuration .... object is created and it is based on the security context of the creating ...
Towards a Formal Model for Security Policies Specification and Validation in the SELinux System Giorgio Zanin

Luigi Vincenzo Mancini

Università di Roma “La Sapienza” Dipartimento di Informatica Via Salaria 113, 00198 Rome, Italy +39 (06) 49918430

Università di Roma “La Sapienza” Dipartimento di Informatica Via Salaria 113, 00198 Rome, Italy +39 (06) 49918421

[email protected]

[email protected] configuration and analysis of an arbitrary security policy [6]. Indeed, both the configuration language and administration of the security policies are complex tasks to carry on. The security policy enforced in the system is the net result of the configuration of three different access control models, namely Type Enforcement, Role Based Access Control and User Identity [15]. Moreover it is possible to specify several constraints. The configuration language consists of several constructs relative to the sub-models; the configuration rules that form a security policy are instances of these constructs.

ABSTRACT This paper presents a formal model, called SELAC, for analyzing an arbitrary security policy configuration for the SELinux system. A security policy for SELinux is complex and large: it is made by many configuration rules that refer to the access control submodels implemented in the system. Among the rules composing a security policy configuration, many relationships occur and it is extremely difficult to understand their overall effects in the system. Our aim is to define semantics for the constructs of the SELinux configuration language and to model the relationships occurring among sets of configuration rules. Finally, we develop an algorithm based upon SELAC, which can verify whether, given an arbitrary security policy configuration, a given subject can access a given object in a given mode.

Although the configuration scheme is handy because it permits to set the security policy on several abstraction layers (corresponding to the different sub-models), it introduces notable difficulties in understanding exactly the net result of a set of rules and in stating whether a given set of security goals is achieved by a given configuration. This makes hard to answer to even simple questions like “can a given subject access a given object?”

Categories and Subject Descriptors D.4.6 [Operating System]: Security and Protection – access controls; K.6.5 [Management of Computing and Information Systems]: Security and Protection – unauthorized access; D.2.9 [Software Engineering]: Management – software configuration management

This paper proposes a formal model, called SELinux Access Control (SELAC), which aims at detailed understandings of an arbitrary security policy configuration of SELinux. SELAC defines semantics for the constructs of the configuration language and permits the statement of the relationships occurring among sets of configuration rules. Therefore SELAC permits the verification of the overall effects of any set of SELinux rules.

General Terms Security, Management, Languages, Verification

Keywords

With the formalism provided by SELAC it is easy to develop algorithms and tools for the analysis of SELinux configurations. The model is an effective aid in the definition of access control policies for the system: through the concept of Accessibility Space it is possible to detect what a given subject acting in the system can do, in terms of granted permissions, and what it cannot do.

Security Enhanced Linux, Configuration, Formal Model

1. INTRODUCTION The Security Enhanced Linux (SELinux) system is a secure operating system developed by the National Security Agency, which is receiving much attention by the community of researchers, developers and users of trusted operating systems.

The rest of the paper is organized as follows. In Section 2, we describe the main features of SELinux: its architecture, the most important concepts related to the security labels and the three submodels upon which it is possible to define an arbitrary security policy. Section 3 introduces the SELAC model: it consists of a number of sets, constructed in an incremental way from the configuration rules of a given security policy specification. For each set we provide its definition and its incremental construction. In section 4 we define the concept of Accessibility Space, which is a collection of permissions related to a subject. In particular, we identify seven important accessibility spaces, essential for the analysis of an arbitrary system configuration. Moreover, given an arbitrary SELinux configuration, we provide, in Section 5, an algorithm which permits to state whether a given subject can access a given object in a certain mode. This algorithm is an

Basically, SELinux [14] consists of a collection of security enhancements in the Linux kernel. The implemented mechanisms provide support for a wide range of security policies. The system is flexible and can be configured by a specific high-level language. However there is still an open problem concerning the

Permission to make digital or hard copies of all or part of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for profit or commercial advantage and that copies bear this notice and the full citation on the first page. To copy otherwise, or republish, to post on servers or to redistribute to lists, requires prior specific permission and/or a fee. SACMAT’04, June 2–4, 2004, Yorktown Heights, New York, USA. Copyright 2004 ACM 1-58113-000-0/00/0004…$5.00.

136

example of application of the SELAC model. Finally, Section 6 contains some concluding remarks.

rights, because an access mode is always specified with respect to a given object class.

2. BACKGROUND

2.3 Type Enforcement sub-model

SELinux implements a security architecture called Flask [16] in the Linux operating system. Basically, Flask is a flexible architecture supporting multiple mandatory security policies. In Flask there are two major kinds of interacting subsystems: one, called Security Server, encapsulates the logic of a given security policy and takes decisions in accordance with a given representation of that policy; the other kind, called object manager, enforces the access control policy coded in the Security Server. There is one Security Server and several object managers (one for each subsystem of the kernel).

In traditional TE, a security attribute called domain is bound to each subject, while another, called type, is bound to each object. Then, several equivalence classes for subjects and objects are defined. Interactions between active entities (subjects) and passive entities (objects) are defined by the Domain Definition Table (DDT), while those between subjects (the message exchange, for example), by the Domain Interaction Table (DIT). Entries in both the tables contain the access rights owned by subjects, running within given domains, respectively on objects having given types or on other subjects running within other domains. In SELinux, though the concepts of domain and type are semantically distinct, the TE sub-model does not make distinctions and the security attribute, both for subjects and objects, is called type. In this manner, only one access matrix is necessary, instead of two. A second difference between the traditional TE and the one involved in SELinux is that type interactions are based on a pair of types and an object class. Moreover a given type can be assigned to objects belonging to different classes. Then, thinking about access matrices, the one defined in SELinux rather than two-dimensional, is three-dimensional (subject-type, object-type, object-class).

Subjects and objects are labeled, and the security policy enforced in the system is defined with respect to these labels, called security contexts. Actually, two kinds of access controls, DACs and MACs, are enforced: MACs can be configured by a security administrator using a specific configuration language, while DACs are the basic access controls of traditional UNIX systems.

2.1 The Security Server The Security Server embedded in SELinux, implements an access control model based on three different sub-models, at the same time: Type Enforcement (TE) [2, 12, 3, 4], Role Based Access Control (RBAC) [5, 13] and User Identity (UI). There is one more, optional, model called Multi-Level Security, but it seems not to have been used so far by the community so, here, we are not interested in it. The format of the security contexts consists of three security attributes: a type, denoting, with the TE terminology, a domain for a subject or a type for an object; a role, denoting a function which a subject can perform or a responsibility it can have in the system; a user identity (possibly different from the standard identities in UNIX systems), denoting the identity of the user on behalf the subject acts or the identity of the creator of an object. According to these three security attributes, the authorization mechanism is the one typical of a reference monitor [1] accomplishing a mandatory security policy: whenever a subject wants to access an object in a given mode, it is checked whether that is authorized by the security policy, coded by a high level configuration language, according to the security contexts of the entities (subject and object) involved in the access. A closed world policy is assumed, i.e. permissions not explicitly granted are implicitly denied.

2.4 Role Based Access Control sub-model Traditional RBAC is based on relations between users and roles (user-role assignments) and between permissions and roles (permission-role assignments). A user is granted an access right on a certain object, only if acting in a certain role, which is authorized to the given access right on that object. In SELinux the user-role assignment is maintained, while permission-role assignment is dropped. Instead of permission-role assignment, sets of TE domains are assigned to roles. Roles can be organized into hierarchies and dominance relationships among roles can occur. Roles are used only for subject labeling, and security contexts for objects have the role component generally set to a generic object_r value. The RBAC support in SELinux is simple: for example, there is no chance for a subject to activate more than one role at a time. There is no support for defining constraints as those defined in the literature [8, 11, 17]. The RBAC in SELinux is a user-centered concept for grouping sets of domains, introducing a new abstraction layer to the TE, and it is used also for limiting permissible security context transitions. However, the important part of the access control is in the TE.

The Security Server takes two kinds of decisions: security decisions are yes/no decisions, stating whether a labeled subject is granted a given access to a labeled object; labeling decisions state which security context has to be assigned to an object (typically at its creation time), in accordance to the security contexts of related subjects and objects.

2.5 User Identity sub-model In UNIX systems, a change of the user identity of a process corresponds to a change in the access rights on the objects, according to a DAC model. It is possible to alter the user identities through setuid calls. SELinux keeps a security attribute denoting a user identity, in the security contexts. This attribute can not be altered, unless the policy configuration permits it explicitly. It is separated by the standard UNIX user identity, and is orthogonal to it: in this manner compatibility with standard access control mechanisms (and then with legacy applications) is preserved.

2.2 Object classes Objects are partitioned into classes: for each object class (file, process, socket, …) an access vector is defined, specifying possible access modalities to the objects belonging to that class. In other words, an access vector is a collection of access modes (or access rights) specific for a certain object class. Access modes belonging to different object classes can have the same name (for example the read and write access rights are generally defined for both the file and dir classes). However, with this approach there is no chance to have a name clash between two different access

The association between user identity and type, for a subject, is stated through a role.

137

Looking at the configuration language, we picked out the important sets shown in the following.

2.6 Security context transitions In SELinux it is possible to change a subject or an object security context through appropriate system calls and kernel interfaces, but these changes have to be authorized and are controlled by the policy. There exist three cases in which security contexts can be altered: at the creation of a new object, when a subject transition on execution occurs, and when an existing object is relabeled. In the first two cases, security context transitions occur, according to the Security Server labeling decisions; in the other case security context changes occur. In this paper, we will focus on security context transitions, which let the existing Linux applications run without any change in their code.

The construct attribute permits to declare attributes for types; an attribute is a name assignable to one or more types and it is used as a sort of macro (when it is expanded, it returns all the types to which the attribute is assigned); an attribute is useful because it can be used in each rule whose construct has a field for a type name: the result is that the rule is applied to all the types having the given attribute; the notation 1 we use for rules from this construct is: attribute(a), meaning a is an attribute for some types. In SELAC, A is the set of attributes that can be bound to subject domains or object types. It is possible to construct this set in the following way:

A security context transition for a process can take place every time a subject executes a program (i.e. at the transformation of the process, via an execve call) and it is based on the security context of the subject and the security context of the executable. A security context transition for an object can take place when a new object is created and it is based on the security context of the creating process and on the security context of some other related object (for example the parent directory, for a file). These transitions may occur only if they are authorized by the security policy: this is done through particular access rights granted within the domains of the subjects involved.

1. A ← ∅ 2. for each rule of kind attribute(a) : A ← A ∪ {a} With rules: attribute domain; attribute file_type;

3. SELINUX ACCESS CONTROL (SELAC)

attribute exec_type;

In order to move from an informal description of the configuration language, given mostly by examples in [9, 10, 15], to a more formal one, we have developed a model, called SELinux Access Control (SELAC), which captures the relations occurring among the rules of a certain security policy specification.

attribute sysadmfile; it follows: A = {domain, file_type, exec_type, sysadmfile} The construct type permits to declare names for the domains of the subjects and for the types of the objects. It is also possible to associate one or more attributes to a type. The notation we use for rules of this kind is: type(t,a1,…,an), meaning t is a type with attributes a1,…,an; we also use type(t), when no attributes are assigned to type t. In SELAC, T is the set of the domains for subjects and types for objects. It is possible to construct this set in the following way:

In particular we will show how, using SELAC, it is possible to determine, for example, whether a given subject can access a given object in a given mode – note that, as an arbitrary SELinux configuration is generally complex and large, its effects are hard to be understood and figured out by any not skilled and very experienced person. The SELinux configuration language provides 25 constructs, from which we selected the 11 of them which are relevant to the accessibility problem of subjects to objects.

1. T ← ∅ 2. for each rule of kind type(t) :

A security policy configuration is defined specifying the object classes and their access vectors, configuring the TE, RBAC and UI sub-models and, finally, configuring the constraints. We call configuration rule any instance of a construct of the language.

T ← T ∪ {t} 3. for each rule of kind type(t,a1,…,an), with a1,…,an∈A : T ← T ∪ {t}

SELAC defines a collection of sets, representing the specification of a given configuration of SELinux, implementing a particular security policy. They are constructed from the configuration rules composing a given security policy. A number of sets are relative to some basic items (i.e. user identities, roles, types, object classes, access rights). The notation we use for them in the following is:

For each type t, we define a set A(t) containing the attributes for t . This kind of sets can be constructed in the following way: Given t∈T: 1. A(t) ← ∅

X(y1, ..., yn)

2. For each rule of kind type(t,a1,…,an), with a1,…,an∈A : A(t) ← A(t) ∪ {a1,…,an}

where y1,…,yn are the basic items that set X is related to. The notation can be read also as: a set is represented with an n-ary function, returning the items belonging to the set. For example set A(t), with t belonging to the family of the types defined for subjects and objects, contains all the attributes related to type t. As another example, with P(file) and P(process) we will mean the sets of access rights for the file and process object classes.

1

138

For an easier reading we will use a functional notation for the configuration rules. The provided examples, instead, make use of the actual syntax of the configuration language.

From the previous sets we define a function α:A→2{T}, returning the set of all types with a given attribute:

With rules:

Given a∈A : α(a) = {t∈T | a∈A(t)}

user root roles {user_r, sysadm_r};

With rules:

user giorgio roles user_r;

user system_u roles system_r;

type sshd_t, domain; type sshd_exec_t, sysadmfile;

it follows: file_type,

U = {system_u, root, giorgio}

exec_type,

We call Space of Security Contexts the set O defined as:

type sshd_tmp_t, file_type, sysadmfile; O = {(u,r,t) | u∈U, r∈R, t∈T}

type sshd_var_run_t, file_type, sysadmfile;

O is the Cartesian product U×R×T and it is the set of all the possible security contexts, both for subjects and for objects. As groups of configuration rules enforce some constraints on legal combinations of security context components, we will define later two sub-spaces called Space of Valid Security Contexts (for Subjects and for Objects).

it follows: T = {sshd_t, sshd_exec_t, sshd_tmp_t, sshd_var_run_t} A(sshd_t) = {domain} A(sshd_exec_t) = {file_type, exec_type, sysadmfile}

We define on O three projective functions, #OT: O→T, #OR: O→R, and #OU: O→U, returning the three components of a security context:

A(sshd_tmp_t) = {file_type, sysadmfile} A(sshd_var_run_t) = {file_type, sysadmfile}

α(domain) = {sshd_t}

Given s = (u,r,t), s∈O : #OT (s) = t, #OR (s) = r, #OU (s) = u

α(file_type) = {sshd_exec_t, sshd_tmp_t, sshd_var_run_t}

For simplicity, we do not model role hierarchies (which are partial orders and their support seems to need some changes, as described in [18]) but we assume the construct dominance specifying the names of a senior role and a junior role, i.e. with the notation dominance(s,j) we mean s is a senior role for j (or, equivalently, j is a junior role for s). In this way, we define, for each role r the set ↓D(r) of its dominated roles:

α(exec_type) = {sshd_exec_t} α(sysadmfile) = {sshd_exec_t, sshd_tmp_t, sshd_var_run_t} The construct role permits to declare roles and to define the domains to which those roles are authorized; with the notation role(r,t1,…,tn) we mean role r can enter domains t1,…,tn. In SELAC, R is the set of all the roles. We assume this set containing the item object_r. R can be constructed in the following way:

Given r∈R : 1. ↓D(r) ← ∅

1. R ← {object_r}

2. for each rule of kind dominance(r,j), with j∈R : ↓D(r) ← ↓D(r) ∪ {j}

2. for each rule of kind role(r,t1,…,tn), with t1,…,tn∈T : R ← R ∪ {r}

With rules:

With rules: role system_r types getty_t klog_t};

dominance {role prof_r {role stud_r}} {kernel_t

initrc_t

dominance {role prof_r {role dbg_r}} dominance {role prof_r {role osg_r}}

role user_r types {user_t, user_netscape_t};

it follows:

role sysadm_r types {sysadm_t run_init_t};

↓D(prof_r) = {stud_r, dbg_r, osg_r}

it follows:

Once defined A, U, R, T and the ↓D(s) ’s (for each role s), it is possible to construct the set R(u) (for any user identity u) of those roles which u can activate, and the set T(r) (for any role r) of those types (actually domains) which r can enter, taking into account eventual role dominance relationships and type attributes:

R = {object_r, system_r, user_r, sysadm_r} The construct user permits to define user identities and to specify which roles can be activated by subjects having those identities. user(u,r1,…,rn) means user u can activate roles r1,…,rn. U is the set of user identities recognized by SELinux. The set can be constructed as follows:

Given u∈U : 1. R(u) ← ∅

1. U ← ∅

2. for each rule of kind user(u,r1,…,rn),

2. for each rule of kind user(u,r1,…,rn),

with r1,…,rn∈R\{object_r}: R(u) ← R(u) ∪ {r1,…,rn}

with r1,…,rn∈R : U ← U ∪ {u}

139

1. C ← ∅

3. for each role r’∈R(u): R(u) ← R(u) ∪ ↓D(r’)

2. for each rule of kind class(c) : C ← C ∪ {c}

and

and

Given r∈R :

Given c∈C:

1. T(r) ← ∅

1. P(c) ← ∅

2. for each rule of kind role(r,t1,…,tn),

2. for each rule of kind access_vector(c,p1,…,pn) :

with t1,…,tn∈T : T(r) ← T(r) ∪ {t1,…,tn}

P(c) ← P(c) ∪ {(p1,c),…,(pn,c)}

3. for each rule of kind role(r,a1,…,an),

With rules:

with a1,…,an∈A : T(r) ← T(r) ∪ α(a1) ∪…∪ α(an)

class file

4. for each role r’∈↓D(r) :

class process

T(r) ← T(r) ∪ T(r’)

class dir

With the rules shown above for role and user constructs, we get:

class file { ioctl read write create getattr setattr lock relabelfrom append relabelto relabelto link rename execute swapon mounton execute_no_trans quotaon unlink entrypoint }

R(system_u) = {system_r} R(root) = {user_r, sysadm_r} R(giorgio) = {user_r}

it follows:

T(system_r) = {kernel_t, initrc_t, getty_t, klog_t}

C = {file, process, dir}

T(user_r) = {user_t, user_netscape_t}

P(file) = {(ioctl,file), (read,file), (write,file), (create,file), (getattr,file), (setattr,file), (lock,file), (relabelfrom,file), (relabelto,file), (append,file), (unlink,file), (link,file), (rename, file), (execute,file), (swapon,file), (quotaon,file), (mounton,file), (execute_no_trans,file), (entrypoint,file)}

T(sysadm_r) = {sysadm_t, run_init_t} Now it is possible to define the Space of Valid Security Contexts for Subjects, S, of all the security contexts that can be assigned to subjects in a given system configuration:

It is straightforward to define the set of all possible access rights, P, as:

S = {(u,r,t)∈O | u∈U, r∈R(u), t∈T(r)} Notice that S⊂O (i.e. subjects are a subset of objects, in accordance with the literature on access control models), while in O\S are included all the valid security contexts for objects and all the (not valid) security contexts not bound to any active or passive entity of the system.

P=



c∈C

P(c)

With the term permission with respect to the type (prt) we mean a pair, belonging to the product T×P. A subject running in a domain which has the prt (t,(p,c)), in absence of other restricting rules, is granted the access p on every object having type t and belonging to the class c (obviously, p has to be in the access vector of c).

The construct class permits to declare names for object classes; class(c) means c is a name for a class of objects. Another construct (access_vector2) is used for defining access modalities to the objects belonging to a given class; access_vector(c, p1,…,pn) means p1,...,pn are access modes for object class c. In SELAC, set C includes all the object classes. Access rights are defined with respect to the items in C. Set P(c) includes those access modes provided by the object class c, i.e. the access vector of c. Actually, we denote an access right as a pair: the first component is the access mode, while the second is the object class; in this way there is no chance to have name clashes for access rights belonging to different object classes (as, for example, in the situation of read and write modes with respect to the file and dir object classes):

The construct allow permits to specify the access rights granted in each domain; it defines allowed interactions between subjects and objects; an object is identified by a pair denoting, respectively, its type and its class. With instances of this construct the TE access matrix is defined; the notation is allow(s,t,c,p1,…,pn), meaning a subject with type s can access any object of class c having type t, in p1,…,pn modalities. Fields s and t can be filled with attribute names. In SELAC, the set of all the prt’s of a given domain s, M(s), corresponds to the union of the DDT and DIT matrices of the standard TE and can be constructed as follows: Given s∈T :

2

1. M(s) ← ∅

Actually, in the configuration language, this construct is called class, as the former, and differs for the arguments it takes. However we prefer to call this construct access_vector, for clarity.

2. for each rule of kind allow(s,t,c,p1,…,pn), with t∈T, (p1,c),…,(pn,c)∈P(c) :

140

M(s) ← M(s) ∪ {(t,(p1,c)),…,(t,(pn,c))}

2. for each rule of kind constrain(c,p’,expr),

3. for each rule of kind allow(s,a,c,p1,…,pn),

with c∈C, p’∈P(c) : for each s∈S, o∈O such that ||expr||s,o = true :

with (p1,c),…,(pn,c)∈P(c), a∈A : for each ti∈α(a) :

γ(s,o,p’) = true

M(s) ← M(s) ∪ {(ti,(p1,c)),…, (ti,(pn,c))}

The usage of the construct type_transition is twofold: it permits to define the labeling behavior of the Security Server, when processes are transformed and it permits to define the labeling behavior of the Security Server, when new objects are created; the rule type_transition(s,e,process,t) means that whenever a subject has type s and the executable has type e, then the type component of the security context for the transformed process can be t. Fields s and e can be filled with attribute names, though, for simplicity, in the following we will not consider this feature any longer. On the other hand, the rule type_transition(s,t,c,n) (with c other than process) means that when a subject with type s creates an object of class c, if the related object has type t, then the type component of the security context for the new object can be n. Set Do(s) denotes the labeling decisions taken by the Security Server about newly created objects. It contains triples of kind (t,c,n)∈T×C×T denoting, respectively, the type of the related object, the class of the object to be labeled and the type to be assigned to the newly created object:

4. for each rule of kind allow(a,t,c,p1,…,pn), with t∈T, (p1,c),…,(pn,c)∈P(c), a∈A : if s∈α(a): M(s) ← M(s) ∪ {(t,(p1,c)),…,(t,(pn,c))} 5. for each rule of kind allow(a1,a2,c,p1,…,pn), with (p1,c),…,(pn,c)∈P(c), a1, a2∈A : if s∈α(a1) for each ti∈α(a2): M(s) ← M(s) ∪ {(ti,(p1,c)),…, (ti,(pn,c))} With rules: allow sshd_t sshd_exec_t:file {read execute entrypoint};

Given s∈T :

allow sshd_t sshd_tmp_t:file {create read write getattr setattr link unlink rename};

1. Do(s) ← ∅ 2. for each rule of kind type_transition(s,t,c,n),

allow sshd_t user_t: process transition;

with t,n∈T, c∈C\{process} : Do(s) ← Do(s) ∪ {(t,c,n)}

it follows: M(sshd_t) = {(sshd_exec_t,(read,file)), (sshd_exec_t,(execute, file)), (sshd_exec_t,(entrypoint,file)), (sshd_tmp_t,(create, file)), (sshd_tmp_t,(read,file)), (sshd_tmp_t,(write,file)), (sshd_tmp_t, (getattr,file)), (sshd_tmp_t,(setattr,file)), (sshd_tmp_t,(link, file)), (sshd_tmp_t,(unlink,file)), (sshd_tmp_t,(rename,file)), (user_t,(transition,process)) }

With rules: type_transition sshd_t tmp_t:dir sshd_tmp_t; type_transition sshd_t tmp_t:file sshd_tmp_ t;

Moreover, we define two projective functions, #TxPT: T×P→T and #TxPP: T×P→P, returning the components of a given prt:

it follows:

Given q = (t,p), q∈T×P : #TxPT (q) = t, #TxPP (q) = p

In a similar manner, set Dp(s) denotes labeling decisions taken by the Security Server about transformed processes; its elements are pairs where the first component denotes the type to be assigned to the transformed process and the second component the type of the entrypoint program to be executed for the process transformation:

Do(sshd_t) = {(tmp_t, dir, sshd_tmp_t), (tmp_t, file, sshd_tmp_t)}

A constrain rule imposes that a given access right can be granted only if a given boolean condition is satisfied. Condition permits to compare with respect to the equality the three components of a pair of security contexts. The role components can also be compared with respect to the dominance relation, whenever a role hierarchy is defined. The rule constrain(c,p,expr) means that the p-access provided by object class c can be granted only if boolean expression expr is satisfied. In SELAC, the function γ: S×O×P→{true, false} checks whether there exists a constraint such that subjects with a given security context are prohibited to access objects with another given security context, in a certain mode. With notation ||expr||s,o we mean the truth value of boolean expression expr with respect to the actual values of s and o:

Given s∈T : 1. Dp(s) ← ∅ 2. for each rule of kind type_transition(s,e,process,t), with t,e∈T : Dp(s) ← Dp(s) ∪ {(t,e)} With rules: type_tansition sshd_t;

1. for each s∈S, o∈O, p∈P :

initrc_t

sshd_exec_t:process

it follows:

γ(s,o,p) = false

Dp(initrc_t) = { (sshd_t, sshd_exec_t) }

141

#TxPP (p) = (entrypoint, file)}

We recall that, in order to occur, transitions corresponding to the labeling decisions coded in Dp(s) and Do(s), must be allowed, i.e. it is necessary s having certain prt’s, contained in M(s), as shown in the following.

With rules: allow sshd_t sshd_exec_t:file entrypoint;

The construct role_allow 3 permits to define allowed role transitions for subjects; role_allow(s,r1,…,rn) means that the role component can change from s to any of r1,…,rn during a subject transformation. Finally, we define the set of roles R→(s) which a role s can make a transition to, during a process transformation. We assume s∈R→(s):

it follows : E(sshd_t) = { sshd_exec_t } Allowed transitions from a given type can be represented by pairs whose first component denotes the type to make the transition to, and the second component the type of the entrypoint program to be executed; the set of allowed transitions from a type s is denoted by T→(s):

Given s∈R : 1. R→(s) ← s

Given s∈T :

2. for each rule of kind role_allow(s,r1,…,rn),

T→(s) = {(t,e)∈T×T | ∃p,q∈M(s) |

with r1,…,rn∈R : R→(s) ← R→(s) ∪ {r1,…,rn}

#TxPT (p) = t, #TxPP (p) = (transition, process) ∧

With rules:

#TxPT (q) = e, e∈E(t), #TxPP (q) = (execute, file)}

allow system_r { user_r sysadm_r} ; With rules: allow user_r sysadm_r ; allow sshd_t sshd_exec_t:file execute; it follows:

allow sshd_t sshd_exec_t:file entrypoint;

R→(system_r) = {user_r, sysadm_r}

allow sshd_t user_t:process transition;

R→(user_r) = {sysadm_r}

it follows:

From the sets above, it is possible to derive other sets, interesting from the point of view of a configuration analysis. For example, it is easy to define the inverse of ↓D(s), R(u), T(r), and M(s):

T→(sshd_t) = { (user_t,sshd_exec_t) }

↑D(j) is the set of senior roles for the (junior) role j:

Then, the set T⇒(s) of types to which a given domain s can make an automatic transition is:

Given j∈R : ↑D(j) = {s∈R | j∈↓D(s)}

Given s∈T :

U(r) is the set of user identities which can activate role r:

T⇒(s) = {t∈T | ∃e∈E(t) | (t,e)∈Dp(s) ∩ T→(s)}

Given r∈R : U(r) = {u∈U | r∈R(u)}

With the rules above and the following:

W(t) is the set of roles which can enter the domain t:

type_transition sshd_t sshd_exec_t: process user_t ;

Given t∈T : W(t) = {r∈R | t∈T(r)}

we get:

Y(t,p) is the set of domains having a certain prt:

T⇒(s) = { user_t }

Given t∈T, p∈P :

4. ACCESSIBILITY SPACES

Y(t,p) = {s∈T | (t,p)∈M(s)}

We have already defined the set of valid security contexts for subjects, S. What we do now is, first of all, to define something similar for objects. Actually, it is handy to derive, for each object class c, a subset O(c) of the space of security contexts O, which contains all and only those security contexts suitable for objects of class c. We call O(c) the Space of Valid Security Context for Objects of class c. Imposing O(process) = S, it follows S⊂O, as it is expected.

The following derived sets are particularly important because they concern process transformations: E(t) is the set of entrypoint programs for a given type (actually a domain) t: Given t∈T :

The role component of object security contexts is object_r, therefore O(c)⊂U×object_r×T, for any object class c. What about the user identity and type components? For practical reasons, it is worthwhile not to consider all T, but just those of its elements actually bound to objects via certain configuration rules. So, for every object class c other than process, it seems useful to restrict O(c) to the space:

E(t) = {e∈T | ∃p∈M(t) | #TxPT (p) = e ∧

3

Actually, in the configuration language, this construct is called allow, as the one for the TE sub-model, and differs from it for the arguments provided. However we prefer to call this construct role_allow, for clarity.

O(c) = {o∈O | #OR(o) = object_r ∧ ∃p∈P(c), ∃t∈T |

142

against a class c, Χ(s,c), includes all the permissions related to objects of c, that are denied to subjects with security context s, because of the existence of explicit constraints. In general, this space is quite wide, due to the fact that it is not just a subset of Σ(s,c). Formally:

(#OT(o),p)∈M(t)} In order to fill the O(c)’s, the following algorithm can be used: 1. O(process) ← S 2. for each c∈C\{process}: O(c) ← ∅

Given s∈S, c∈C : Χ(s,c) = {(o,p)∈ Ω(c) | γ(s, o, p) = true}

3. for each rule of kind allow_def(t1,t2,c,p1,…,pn),

From the three accessibility spaces above (shown in Figure 1), we derive four more spaces of relevant interest, whose analysis permits to determine several properties of a given configuration: for example what a subject can access in the system and in which mode.

with c∈C\{process}, (p1,c),…, (pn,c)∈P(c), t1, t2∈T : O(c) ← O(c) ∪ {o∈O | #OT(o) = t2, #OR(o) = object_r} A corresponding restriction on the user identity component seems much harder to be found and needs more investigation, but, actually, as the number of SELinux user identities is not likely to be that big (certainly far less than the number of types) this is not an issue. With the term Permission with respect to the security context, or simply Permission, we mean a pair (o,p)∈O×P. For every class c, we are interested in permissions belonging to O(c)×P(c).

Figure 1. Graphical representation of accessibility spaces; from the left to the right, Universe of class c and Spaces of Specified and Constrained Permissions for a security context s against a class c.

A set of permissions related to a same object class forms what we call an Accessibility Space. The ideas behind the access control spaces defined in [7] are similar to the ones at the base of the following accessibility spaces. However in [7] the access control spaces concept is much more general than what we introduce here, and it is used to validate high-level properties of a configuration (i.e. integrity and safety). The accessibility spaces introduced here, indeed, are SELinux specific and are used to state whether a given subject can access a given object in a given mode. Any other higher level analysis upon these spaces has to be done. Moreover, as in SELinux a closed world policy is assumed, we have not the problem of the unknown sub-space, defined and handled in [7].

The Space of Authorized Permissions for a security context s, against a class c, ∆(s,c), is a set of specified permissions that are not further constrained. They are the only permissions, related to objects of class c, granted to subjects with security context s. Formally:

4.1 Universe

∆(s,c) = {(o,p)∈Ω(c) | (#OT(o),p)∈M(#OT(s)) ∧

4.4 Space of Authorized Permissions

Given s∈S, c∈C : ∆(s,c) = Σ(s,c) \ Χ(s,c) i.e.

The space Universe of a class c, Ω(c), includes all possible permissions related to the class c, i.e. all the pairs where the first component is a valid security context for an object of class c, and the second component is an access mode p defined for c. Formally:

γ(s, o, p) = false}

4.5 Space of Prohibited Permissions: I kind The Space of Prohibited Permissions of the first kind for a security context s against a class c, Π1(s,c), is the set of permissions related to objects of c that are neither specified nor constrained for s. They are those permissions denied by the SELinux authorization scheme because there are not explicit rules in the security policy configuration (closed world policy assumption). Formally:

Given c∈C : Ω(c) = O(c)×P(c) Then, Ω(c) is the union of all the possible accessibility spaces, related to the object class c.

4.2 Space of Specified Permissions

Given s∈S, c∈C : Π1(s,c) = Ω(c) \ (Χ(s,c) ∪ Σ(s,c))

The Space of Specified Permissions for a security context s against a class c, Σ(s,c), includes all the permissions related to objects of c that can be granted to subjects with security context s, in accordance with the configuration of the TE sub-model. Formally:

i.e.

Π1(s,c) = {(o,p)∈Ω(c) | (#OT(o),p)∉M(#OT(s)) ∧ γ(s, o, p) = false}

Given s∈S, c∈C : Σ(s,c) = {(o,p)∈Ω(c) | (#OT(o),p)∈M(#OT(s))}

4.6 Space of Prohibited Permissions: II kind

Notice that not all the specified permissions are also authorized: many of them, in fact, are not allowed due to the constraints configuration and then they are not granted by the authorization scheme.

The Space of Prohibited Permissions of the second kind for a security context s against a class c, Π2(s,c), is the set of those permissions that are both specified and explicitly constrained for s against c. Formally:

4.3 Space of Constrained Permissions

Given s∈S, c∈C : Π2(s,c) = Χ(s,c) ∩ Σ(s,c)

The Space of Constrained Permissions for a security context s

143

i.e.

Π1(s,c) = {(o,p)∈Ω(c) |

(#OT(o),p)∈M(#OT(s))

object class, the spaces of specified and constrained permissions should be augmented, in an incremental manner. As in SELinux a closed world policy is assumed, not all the kinds of spaces are to be generated: for example, the universes of the object classes, as well as the spaces of prohibited permissions of the first kind, can be omitted.

∧ γ(s, o, p) = true}

4.7 Space of Prohibited Permissions: III kind The Space of Prohibited Permissions of the third kind for a security context s against a class c, Π3(s,c), is the set of those permissions that are not specified but that are explicitly constrained for s against c. This space can be seen as a “side effect” due to the fact that, in SELinux, the definition of constraints permits to constrain permissions not specified.

5. THE ACCESSIBILITY ALGORITHM In this section, we give an example of application of SELAC. By the pseudocode in Figure 4, described in a C-like language, it is possible to answer the question “can a given subject x obtain the w-access on a given object y of class c?”. Actually we assume x is not the security context of a process corresponding to a securityaware Linux application, i.e. x is the security context of a program not invoking the extended secure API provided by SELinux.

Formally: Given s∈S, c∈C : Π3(s,c) = Χ(s,c) \ Σ(s,c) i.e.

Through the use of SELAC, answering such a question, and any other similar, is easy, as shown in Figure 4.

Π3(s,c) = {(o,p)∈Ω(c) | (#OT(o),p)∉M(#OT(s)) ∧ γ(s, o, p) = true}

// V is the set of already tested security contexts // AUTHORIZED is a boolean variable containing the // answer // HAS_ACCESS is a boolean function for computing the // answer

Figure 2. Graphical representation of accessibility spaces; from the left to the right: Spaces of Authorized and Prohibited (I kind), Permissions for a security context s against a class c

1. V = ∅; 2. AUTHORIZED = false; 3. HAS_ACCESS(x,c,y,w);

Boolean HAS_ACCESS(S subj,C class,O(c) obj,P(c) mode) { // subj is the security context of the subject // class is the class of the object

Figure 3. Graphical representation of accessibility spaces; from the left to the right: Spaces of Prohibited (II and III kinds), Permissions for a security context s against a class c

// obj is the security context of the object // mode is the access mode to the object V = V ∪ {subj}; if ( (obj,mode) ∈ ∆(subj,class) ) {

The four accessibility spaces above (shown in Figure 2 and Figure 3) permit to extract useful information related to a given configuration. As a matter of fact, the membership of a permission to a Space of Authorized Permissions, points out whether a given subject is authorized to access a given object in any mode. Moreover, if it is not the case, the membership of the permission to one of the three spaces of Prohibited Permissions, states the reason of the denial.

AUTHORIZED = true; exit; } else while(S\V ≠ ∅ && exists t∈S\V such that (#OT(t)∈T⇒(#OT(subj)) && #OR(t)∈R→(#OR(subj))) { HAS_ACCESS(t,class,obj,mode);

The accessibility spaces are useful for testing a given configuration of the system, at least at a low-level (accessibility of subjects to objects), for which, actually, there exist already a few dedicated tools [7, 19, 20]. Indeed, such spaces can be much more useful in building other tools which give help in configuring the system, besides its validation. In fact, the SELAC sets upon which the spaces are defined, as shown above, are built from the configuration rules. Hence, it is not difficult to develop tools able to build the accessibility spaces and to automatically produce the associated configuration rules. In such a way, it is possible to focus on the goals of a security policy, not on the rules to achieve them. To do that, it would be sufficient to state the subjects and the objects of the system. After that, for each subject and for each

{ }

Figure 4. Algorithm for determining if a given subject can access a given object in a given mode.

The function HAS_ACCESS() checks whether subject subj has the ability to access the object obj in the given mode directly, i.e. it checks whether the corresponding permission is in the Space of the Authorized Permissions for subj. If it is not the case, it is checked whether it is possible to access obj by means of a chain

144

of automatic security context transitions, and all the legal transitions are considered. As the number of security contexts for subjects is finite and no security context is considered more than once, the algorithm stops. Moreover the complexity is bounded by the number of the security contexts for subjects multiplied by the cardinality of their spaces of Authorized Permissions (related to the class of obj), but it is expected to be far less.

Haghighat, S. A. 1995. Practical Domain and Type Enforcement for Unix. In Proceedings of the IEEE Symposium on Security and Privacy (Oakland, Calif, May). [4] Badger, L., Sterne, D. F., Sherman, D. L., Walker, K. M. and Haghighat, S. A. 1995. A Domain and Type Enforcement Unix Prototype. In Proceedings of the 5th USENIX UNIX Security Symposium (Salt Lake City, Utah, June).

The possibility of determining what a subject can do through a chain of automatic security context transitions is strongly useful, because it permits to evaluate the risk of an eventual attack moved against a given subject.

[5] Ferraiolo, D. and Kuhn, R. 1992. Role-based access controls. In 15th NIST-NCSC National Computer Security Conference, Baltimore, MD, Oct 13-16, pp 554-563 [6] Jaeger, T., Sailer, R., and Zhang, X. 2003. Analyzing Integrity Protection in the SELinux Example Policy. In Proceedings of the 12th Usenix Security Symposium (Washington, August ).

Developing verification algorithms using SELAC is useful according to at least two points of view. On one hand, it is possible to evaluate the harmfulness of scenarios in which an attacker is able to compromise a given subject. On the other hand, it is possible to use SELAC in configuring an access control policy in an incremental manner. For this purpose, as an example, it is possible to modify the algorithm in figure 4 in order to make it return also the reason for a negative answer.

[7] Jaeger, T., Zhang, X. and Edwards, A. 2003. Policy management using access control spaces. In ACM Transactions on Information and System Security (TISSEC), Volume 6, Issue 3 (August), pp. 327-364 [8] Kuhn, D. R. 1997. Mutual exclusion of roles as a means of implementing separation of duty in role-based access control systems. In Proceedings of the 2nd ACM Role-Based Access Control Workshop. Fairfax, Virginia (USA), November 06-07, 1997, p. 23-30

6. CONCLUSIONS This paper proposed a formalism, called SELAC, for the configuration language of the SELinux system. As far as we know, it is the first attempt to formalize the complex access control enforced in SELinux. The model is based on a number of high level concepts and does not rely on any internal mechanism of the SELinux system, but only on its configuration language. We are confident that such a model is useful for understanding the configuration issues and the relationships occurring among a set of configuration rules. With SELAC it is possible to state, given a set of configuration rules, how those rules affect the access controls of the system, i.e. which permissions are granted to the subjects, which are not and in the latter case, what is the reason of the denial. Therefore, SELAC can be used as a starting point for the analysis of arbitrary access control policies enforced in the system.

[9] Loscocco, P. A. and Smalley, S. D. 2001. Integrating flexible support for security policies into the Linux operating system. NSA Technical Report, Feb. [10] Loscocco, P. A. and Smalley, S. D. 2001. Meeting critical security objectives with Security-Enhanced Linux. In Proceedings of the 2001 Ottawa Linux Symposium, July [11] Nyanchama, M. and Osborn, S. 1999. The role graph model and conflict of interest. ACM Trans Inf. Syst. Sec. 2, 1 (Feb.) [12] O’Brien, R. and Rogers, C. 1991. Developing Applications on LOCK. In Proceedings of the 14th National Computer Security Conference, Washinghton DC, Oct., pp 147-156

By using the SELAC formalism, it is possible to write algorithms for checking properties of given configurations. As an example, we implemented one for stating whether a given subject can access a given object in a certain mode.

[13] Sandhu, R. 1998. Role-Based Access Control. Advances in Computer Science, vol 46, Academic Press.

Finally, a benefit of SELAC is that it can be used to build automatic tools for the configuration analysis and development. We developed a tool which implements the SELAC model and we are planning to further extend the model and the tool functionalities, in order to support the analysis of higher level security goals, such as the data confidentiality and integrity.

[14] National Security Agency. Security-Enhanced Linux (SELinux). http://www.nsa.gov/selinux. [15] Smalley, S. D. 2002. Configuring the SELinux Policy. Nai Labs Report #02-007, June [16] Spencer, R., Smalley, S. D., Loscocco, P., Hibler, M., Andersen, D. and Lepreau, J. 1999. The Flask Security Architecture: System support for diverse security policies. In Proceedings of the 8th USENIX Security Symposium, Aug, pp 123139

7. ACKNOLEDGMENTS This work is funded by the Italian MIUR under the FIRB WEBMINDS project, and the PRIN 2003 project: “WEB-based management and representation of spatial and geographic data”.

[17] Simon, R. and Zurko, M. E. 1997. Mutual exclusion of roles as a means of implementing separation of duty in role-based access control systems. In Proceedings of the10th IEEE Computer Security Foundations Workshop (June). Rockport, Massachusetts.

8. REFERENCES [1] Anderson, J.P. 1972. Computer Security Technology Planning Study. ESD-TR-73-51, Vol 1, Hanscom AFB, Mass.

[18] http://www.nsa.gov/selinux/list-archive/0302/3864.cfm

[2] Boebert, W. E. and Kain, R. Y. 1985. A practical alternative to hierarchical integrity policies. In Proceedings of the 8th National Computer Security Conference (Gaithersburg, Md.).

[19] http://www.tresys.com/selinux/selinux_policy_tools.html [20] http://www.nsa.gov/selinux/list-archive/0312/6084.cfm

[3] Badger, L., Sterne, D. F., Sherman, D. L., Walker, K. M. and

145