Section 3.3. SELinux Policy Language


3.3. SELinux Policy Language

Chapter 2, "Concepts," presented an overview of the SELinux security concepts and introduced some of the policy language concepts. In the previous section, you saw how the policy is used in the SELinux architecture. For kernel resources, the policy is loaded into the SELinux LSM module security server and used to make access control decisions. One strength of SELinux is that its policy rules are not static. Rather, someone (or many ones) must write the policy and ensure that it reflects the desired security goals. Fundamentally, this book is all about how to write SELinux policies (and how to make sure they are good policies). Using and applying SELinux is all about writing and understanding policies.

In Part II of this book, we take you through each major portion of the policy and discuss the policy language syntax and semantics in detail. In this section, we provide an overview of how a policy is constructed and compiled and show you how to build a policy from the strict policy we use as an example throughout this book.

3.3.1. The Native SELinux Policy Language Compiler

The primary way to construct a policy file for the kernel is to compile it from a source policy file using the checkpolicy program. This source file, which itself is constructed in several steps, is typically named policy.conf. Checkpolicy checks the source policy file for syntax and semantic correctness and writes the results in a form (called a binary policy file) that is readable by the kernel policy loader (load_policy). The language syntax supported by checkpolicy is the native, primitive language supported by SELinux. You can think of the checkpolicy language as analogous to assembly language. Higher-level languages and other more abstract ways to create policies are being developed, and some of these are discussed later in this book. For now, we focus on the native policy language and construction of policy for enforcement by the kernel.

Figure 3-5 illustrates the primary sections of a policy source file expected by checkpolicy.

Figure 3-5. Organization of policy source file (policy.conf)


The first section of a policy source file defines the object classes to the security server. This section also defines the permissions for each object class. For the kernel, these classes are directly related to kernel source files. In general, as an SELinux policy writer you would never change or modify the object class and permission definitions. We discuss the specific object classes and their associated permissions in Chapter 4.

The next section contains the type enforcement statements, which is by far the largest portion of an SELinux policy. This is the section that policy writers spend most of their time writing. It contains all the type declarations and all the TE rules (including all allow, type_transition, and other TE rules). We discuss types and the core TE rules in detail in Chapter 5, "Type Enforcement." The TE section often contains thousands of type declarations and tens of thousands of TE rules. This section also contains rules and declarations for roles and users in the policy. Roles and users, which are supporting concepts to type enforcement, are discussed further in Chapter 6, "Roles and Users." Some recent enhancements to the TE policy section, specifically conditional policies, are discussed in Chapter 9. "Conditional Policies."

The next section of a policy source file contains the constraints. Constraints provide a means of further limiting the TE policy beyond what the TE rules permit. The multilevel security (MLS) policy, for example, is implemented as a set of constraints. We discuss constraints in Chapter 7, "Constraints," and MLS in Chapter 8, "Multilevel Security."

The last section of a policy file contains labeling specifications. All objects must be labeled with a security context for SELinux to enforce access control. This section tells SELinux how to treat filesystems for the purpose of labeling and contains the rules for labeling transient objects that are created at runtime. A separate related mechanism, called a file contexts file, is used to initialize the security context labeling of files, directories, and other objects on permanent filesystems. These and other topics relating to object labeling are discussed in Chapter 10, "Object Labeling."

Examining the policy.conf File

As with the binary policy file created by checkpolicy (policy.[ver]), you can use the Tresys apol tool to view, search, and analyze the contents of the policy.conf file. The policy.conf file is more abstract than the binary file format, which often makes it an easier target for policy analysis and debugging. Also, the policy.conf file is closest in form to the original source modules and therefore the best form for tracking back bugs to the original source file. In any case, both are equivalent and should reflect the same security policy.


3.3.2. Source Policy Modules in a Monolithic Policy

A common type of SELinux policy today is a monolithic policy. This is a policy that is constructed as a single binary policy file by checkpolicy that is directly loaded into the kernel. Because SELinux policies are usually quite large and complex, like software, they are constructed in terms of smaller units called modules. There are a couple of different means to make a policy modular. The original and still widely used method, called source modules, supports the development of a monolithic policy. Source modules are combined as text files through a combination of shell scripts, m4 macros, and Makefiles that together create a crude higher-level language. The policy modules are essentially concatenated together into a single large source file (that is, policy.conf) that is then compiled by checkpolicy into a binary file readable by the kernel.

3.3.3. Loadable Policy Modules

A new method for creating a modular policy is called loadable modules, which uses recent extensions to checkpolicy and a module compiler (checkmodule) to construct loadable policy modules compiled independently of each other. Loadable modules are also the basis for the policy server discussed earlier in this chapter. In the loadable module case, there is no longer a monolithic binary policy constructed; instead, a (expectedly smaller) core subset of the policy is constructed called the base module. You create the base module much like you create the monolithic policy. With loadable modules, however, you can streamline the base module, including only rules relating to the core operating system. The rest of the policy is created as separate loadable modules. You can add all other policy rules in a modular fashion when you install their associated software package.

Loadable modules introduce policy syntax changes that are designed to ease the division of the policy into separate, individually distributable policy modules. These changes differ for base and nonbase modules. The base module uses the same policy language as monolithic policies with minor additions. Nonbase (that is, loadable) modules use a subset of the standard policy language with several additional language features. The subset of the policy language includes most of the type enforcement, role, and user statements. The additional language features are used to manage dependencies between modules. We discuss the languages changes resulting form loadable modules in detail using sidebars throughout Part II.

Fedora Core 5 (FC5) has adopted the loadable module infrastructure for future versions. In this book, we primarily discuss the monolithic policy approach and language, but we do use sidebars to discuss the newer loadable modules features.

3.3.4. Building and Installing Monolithic Policies

As you read through the remainder of this book, you will likely want to experiment with SELinux policy writing. You will need to compile your modifications into a complete policy file and experiment with your modifications by loading the new policy into the kernel and experiencing the resulting changes in the kernel's access control enforcement. Before you can complete these actions, we must introduce the basic means of building and installing kernel security policies.

Tip

Remember that if you install your policy, the kernel will immediately begin to enforce access based on the rules in the policy. While you are learning about SELinux and experimenting with the language, you may end up causing programs to crash due to lack of access. We suggest you experiment with policy writing with the system in permissive mode (setenforce 0) until you become more familiar with the policy language and its ramifications. Of course, you should always run production systems in enforcing mode (setenforce 1).


The example policy build method (see Chapter 11, "Original Example Policy") is a typical way that a policy is constructed. Figure 3-6 shows this type of construction.

Figure 3-6. Build and load process for SELinux policy using source modules


Starting from the left side of this figure, you have the source files for the policy broken down into many tens of individual source modules. Later in the book, we talk about various conventions for organizing these modules in the example policy. For now, just understand that these files are combined through a combination of scripts and macro processors into the single policy.conf file, which is a complete and syntactically correct statement of a SELinux source policy. You then compile the source policy using checkpolicy into a binary policy file (assuming no errors!) appropriate for the kernel. The load_policy program is then used to load the binary policy file into the kernel, which then enforces access control based on the policy rules.

At this point in this book, you might find this process overwhelming and confusing, especially in light of our discussion of means to construct a policy other than source modules to build policy. Don't panic; we just want you to get a sense of the overall process. Policy source directories usually have a Makefile that automates this process for you. In the policy we use in Part II, which if installed correctly should be in /etc/selinux/strict/src/policy/, the interesting make targets are as follows:

policy

Make policy.conf and policy.[ver] locally to test the compilation and check for error.

install

Do everything that make policy does plus install the binary policy file such that it will be loaded into the kernel at boot time and the policy configuration files.

load

Do everything that make policy does plus immediately load the binary policy file into the kernel as the active access control policy and install the file_contexts file.


So, for example, make policy will perform all the steps in Figure 3-6 except the last step (install the binary policy and load it into the kernel).

Feel free to experiment with the various make targets in our example policy; just be careful about doing a make install or make load because this will change the access control enforcement on your system.




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