Policy Generation User Manual


Next: 

Copyright © 2004 The MITRE Corporation.

Permission to copy without fee all or part of this material is granted provided that the copies are not made or distributed for direct commercial advantage, this copyright notice and the title of the publication and its date appear, and notice in given that copying is by permission of The MITRE Corporation.

Contents


Next: , Previous: Top, Up: Top

1 Introduction

In January of 2001, the National Security Agency released a prototype version of a security-enhanced Linux system. They implemented Mandatory Access Control (MAC) security mechanisms, providing flexible support for a wide range of security policies. Both type enforcement and role-based access control components were incorporated into the access controls.

This document describes how to use MITRE's SELinux policy generation tools, collectively called polgen, which provide a systematic way to generate policy for programs on an SELinux system. Specifically, polgen attempts to generate policy for a program based on patterns in the program's behavior. This process is predictable and repeatable, but interactive. The user, presented with a suggested policy description, can modify that description before actual policy is produced. Also, polgen supports optional policy analysis to ensure that the newly generated policy does not adversely affect existing (enforced) security goals.

The basic steps of polgen usage are:

This manual assumes some knowledge of the SELinux system. In particular, we assume the reader is familiar with the following SELinux concepts: basic SELinux enforcement mechanism, policy file format, security contexts, and class-permission pairs. If you are unfamiliar with the basics of these concepts, please refer to “Configuring the SELinux Policy”, which is included in the SELinux distribution. The section titled “Flask Concepts” is particularly important.

This manual begins with a quick overview (without explanation or discussion) of polgen usage in Quick Start. We present more detail about each of the components in subsequent sections. In Type Generation, we discuss the use of typegen to set up initial types for candidate programs (this is very helpful for deciphering later polgen output). In Capturing Program Behavior, we describe the use of software architecture modeling and of dynamic trace analysis to capture system call-level program behavior and SELinux information. In Recognizing Patterns, we provide an overview of our behavior analysis approach and cover the use of the spar pattern recognizer. In Generating Policy, we describe the generated files. In Batch-Processing Script, we provide the user with a modifiable script that will run all post-behavior capture polgen components. Finally, we provide a guide to the worked example included in this distribution in the Complete Example section.

In all sections of this manual, we will use pol_source_directory to denote the location of the SELinux policy source. Under FC2, this will be /etc/security/selinux/src/policy. Under Debian GNU/Linux, this will be /etc/selinux/src. Under FC3, this will either be /etc/selinux/targeted/src/policy (by default) or /etc/selinux/strict/src/policy (if you have switched to the optional strict policy).


Next: , Previous: Introduction, Up: Top

2 Quick Start

We start this section with a short list of commands run in the most typical use of polgen. In the remainder of this Quick Start section, we provide a small amount of detail on what the various commands mean. Much more information is available in the subsequent sections of this document.

2.1 Command List

The commands shown in this example use an enhanced version of strace and associated filtering scripts for capturing system behavior. Substitute the program you wish to analyze for program_name, and the directory into which you want to install the software for $HOME/polgen.

     $ ./configure --prefix=$HOME/polgen
     $ make
     $ make install
     $ export PATH=$HOME/polgen/bin:$PATH
     
     $ cd workdir
     $ cp $HOME/polgen/share/polgen/typegen.conf .
     $ : edit typegen.conf to reflect your application
     $ emacs typegen.conf
     $ typegen
     $ a=pol_source_directory
     $ cp polgen_temp.te $a/domains/program
     $ cp polgen_temp.fc $a/file_contexts/program
     $ cp $HOME/polgen/share/polgen/polgen_macros.te $a/macros
     $ pushd $a
     $ make clean
     $ make load
     $ /usr/sbin/setfiles file_contexts/file_contexts workdir
     
     $ pushd
     $ stracesc -fX -o trace_path program_name command_line_args
     $ trackall -o track_data_dir trace_path
     $ mozilla &
     $ spar -n program_name -d track_data_dir -o results_data_dir
     $ cp results_data_dir/program_name.te $a/domains/program
     $ cp results_data_dir/program_name.fc $a/file_contexts/program
     $ pushd $a
     $ rm domains/program/polgen_temp.te
     $ rm file_contexts/program/polgen_temp.fc
     $ make clean
     $ make load
     $ /usr/sbin/setfiles file_contexts/file_contexts workdir

2.2 Installation

These tools are packaged according to GNU standards. For complete information, see the INSTALL file included with this distribution. However, the distribution can be easily compiled and installed in the following way:

  1. Change to the directory containing the package's source code. Run the command ./configure. This software will be installed into /usr by default. If you would like to install the software in location $HOME/polgen, run the command ./configure --prefix=$HOME/polgen. Be sure to add $HOME/polgen/bin to your path.
  2. Type make to compile the package.
  3. Type make install to install the programs, data files, and documentation.

The generation process can be performed entirely on an SELinux machine, or it can be split between an SELinux machine and another machine. The type generation, stracesc, and stracesc filtering components must be run on an SELinux system. Pattern recognition and policy generation can be performed elsewhere if desired; use the --with-stracesc=no option when installing polgen on the secondary system.

Once installation is complete, there are four distinct phases when generating policy with polgen.

  1. Generate basic initial types for the program(s), and place the program(s) in those types.
  2. Capture traces of the program's behavior, and the behavior of other relevant programs. Process those traces to highlight relevant program actions.
  3. Run pattern recognition software on the traces and examine, modify output.
  4. Generate .te files.

2.3 Generating initial types

The typegen script generates a basic set of .te and .fc files for a given set of executables, directories, and files. typegen determines which new types to incorporate based on its configuration file, which can optionally be specified with the -i command line flag. If no command line options are specified, typegen will look for the file typegen.conf in the current working directory.

Details of the configuration file can be found in the Type Generation section and a sample configuration is included in this distribution under prefix/share/polgen. The following commands, given an appropriate configuration file, will generate and install new types and relabel the relevant portions of the file system. We assume for this example that the candidate program and all of its relevant files are in the directory workdir.

     $ typegen
     $ a=pol_source_directory
     $ cp polgen_temp.te $a/domains/program
     $ cp polgen_temp.fc $a/file_contexts/program
     $ pushd $a
     $ make clean
     $ make load
     $ /usr/sbin/setfiles file_contexts/file_contexts workdir

2.4 Capturing Traces of Behavior

Input can be in the form of an architecture model of the application or in the form of traces from a running program. We recommend using both approaches, if possible.

Dynamic Analysis: To conduct a dynamic trace, on the target SELinux system, run the strace program (located in the bin directory) on the target program and any related programs:

     $ stracesc -fX -o trace_path program_name command_line_args
     $ trackall -o track_data_dir trace_path

While the program is running, exercise it in as many different ways as possible. The trackall program will run filters on the stracesc output, and produce digested trace files containing system call information useful for pattern recognition. With the optional -o, trackall will store its output in the given directory. The naming convention for these files is they all begin with program_name.tracked, and they can be moved to the system or location where you will generate policy.

Architecture Model: Application designers and developers may wish to initiate the analysis by entering a description of the software in terms of its components and connectors. To do this they generate a .psl file and place it in the track_data_dir.

2.5 Recognizing Patterns

The program spar, the Security-enhanced linux PAttern Recognizer, searches .tracked and/or .psl files for particular behavior patterns and presents them to the user through a graphical interface and a collection of web pages.

The eventual use-case for this generation software is for large patterns to be recognized and communicated to the user, e.g. "This program is a web server", based on a particular collection of modular sub-patterns found in the program's behavior (e.g., "This program is a network daemon listening on port 80 that uses configuration files, log files, and interacts with user files while running."). Currently, spar recognizes some higher-level security patterns and some modular pattern "building blocks". The complete list of patterns is listed in the full section Recognizing Patterns.

The spar program provides you with the freedom to locate your trace results (spar input) and results (spar output) in directories of your choosing. In the commands that follow, we refer to these two directories as track_data_dir, and results_data_dir, respectively.

If you ran trackall with the -o option, track_data_dir will be the output directory you specified in the previous step. Run spar as follows:

     $ spar -n program_name -d track_data_dir -o results_data_dir

You may then examine the patterns and policy suggested in home.html, in results_data_dir.

2.6 Generating the policy files

After completing its automated analysis of tracked files, spar provides a policy author with an opportunity to fine tune types prior to automated policy generation. Using a graphical interface, you can modify the specifications for .te and .fc files. In addition spar allows users to modify type assignment strategies in several ways. Users can declare that spar should minimize the number of new types created or that spar should never change a type of any non-polgen_temp types. If these options are not selected users will be able to enforce the constraints but on a case-by-case basis. Finally, the user can specify an alternate type to be used to replace all “unconfined_t” occurences.

  1. You can accept or reject spar assertions about patterns of interactions. In some cases, Spar creates new types to enforce constraints associated with patterns.
  2. You can also set up and provide your own name for groups of processes. The notion is that you may want to establish new types for all files read or modified by processes in a group. For both steps 1 and 2, you will find help through spar-generated HTML pages. For this support click on the help button and go to the Pattern Instances or Resource pages.
  3. The next step will be for you to confirm spar's type assignments based on your step 1 and 2 input. You will be able to select a group and pattern designation for a type or return to an original type. The default is to apply pattern and group constraints for typegen-created types and to use an original type for others. If you override one of these original types, spar will ask for confirmation.
  4. The final step is to set the directory level for all files with a new type. This information shows up in the .fc file and conforms to the regular expression protocols for .fc files.

Spar will clean up the remaining polgen_temp types, and replace them with an application-specific name. Before you install the generated .te and .fc files, be sure to remove polgen_temp.te and polgen_temp.fc.


Next: , Previous: Quick Start, Up: Top

3 Typegen: Type Generation

The typegen script generates a basic set of .te and .fc files for a given set of executables, directories, and files. typegen determines which new types to incorporate based on its configuration file, which can optionally be specified with the -i command line flag. If no command line options are specified, typegen will look for the file typegen.conf in the current working directory.

typegen currently supports the following optional command line flags:

3.1 Configuration File Format

The configuration file, typegen.conf, requires four types of statement and supports an additional three.

     name program_name

This is a required statement. The name keyword allows the user to specify a program-wide abstraction that will tie all types related to this program together. All types that typegen creates and assigns will be prepended with program_name.

     role desiredrole_r types desiredtype_1 desiredtype_2 ... desiredtype_n

At least one role statement is required, but typegen supports multiple statements. This statement specifies a role and set of types allowed to run the program. (To determine your own role, run 'getcon'.

     tedir output_directory_name

This is a required statement. The tedir keyword specifies the path to the output directory for the .te file generated by typegen.

     fcdir output_directory_name

This is a required statement. The fcdir keyword specifies the path to the output directory for the .fc file generated by typegen.

     exec process_name path_to_executable

This is an optional statement, and you may have as many exec declarations as you would like. This statement assigns a user-specified name to an executable for type generation purposes. For example, given the commands specified here the executable file would be given the type program_name_polgen_temp_process_name_exec_t. The path must be fully specified.

     dir dir_name path_to_dir

This is an optional statement, and you may have as many dir declarations as you would like. This statement assigns a user-specified name to a directory or set of directories for type declaration purposes. The path listed may be a regular expression. The name will be used in the creation of types for the directories.

     file file_name path_to_file

This is an optional statement, and you may have as many file declarations as you would like. This statement assigns a user-specified name to a file for type declaration purposes. The name will be used in the creation of types for the file.

3.2 typegen Output

Into the directories specified in the configuration file, typegen will produce two files: polgen_temp.te and polgen_temp.fc. These files should be removed after policy generation has been completed.

The .te file will contain the following policy declarations:

The .fc file will contain one line for each assignment of types to the files, directories, and executables declared in the configuration file.

3.3 Installing typegen Output

Once typegen has produced .te and .fc files, they must be incorporated into the running policy before appropriate traces can be captured. The following steps will accomplish this:

Your processes, directories, and files should now all be labeled with new types. (You can check this by using the -Z option to ls.) These new types will be used for the generation of program-specific policy by the rest of the polgen tools.


Next: , Previous: Type Generation, Up: Top

4 Capturing Program Behavior

We describe the two ways that polgen captures program behavior.

4.1 Trackall

The dynamic analysis should be captured on an SELinux machine. All examples run so far have been on a system in permissive mode; no special policy has been written to allow stracesc to function properly in enforcing mode (though this is planned for future releases of polgen).

When you run the target program under stracesc, exercise it as fully as possible. As with all dynamic analysis approaches, the completeness of the traces will dictate the robustness of the policy.

     $ stracesc -fX -o program program
     $ trackall -o output_directory program

These commands will produce trace files containing system call information useful for pattern recognition. When trackall is called with the -o option, the script will place output files in output_directory. The naming convention for these files is program.tracked, and it can be moved to the system or location where you will generate policy.

4.2 How trackall Works

The trackall program converts stracesc output into a format that is easy to analyze, and then invokes the trackfd program. The trackfd program performs the data reduction for the spar program. This script can also be useful outside of the policy generation context, to make sense of trace files and offer insight into a program's behavior.

An essential part of the data reduction is the summarization of the life cycle of a file descriptor. For each file descriptor created by a program, the trackfd program creates a data structure. The data structure is updated whenever a system call is found that applies to the file descriptor. Finally, when a file descriptor is closed, a summary of the activity associated with the file descriptor is written to the output.

4.3 Polgen Specification Language (.psl) files

.psl files contain an architecture description of the application. These descriptions segment the application into a hierarchy of components. Components can be code modules that follow the organizational structure of the application code or, importantly for polgen analysis, they can be processes that realize information flow through the code modules that they use. The following example is an abridged psl description of Mailman. The authors of this manual conducted a code inspection of Mailman and created a .psl file that reflects our best understanding of Mailman components. The example illustrates the features of PSL.

     
     
     component Mailman {
         type application
         requires {python_module, apache, Exim, Postfix }
         }
     
     component bin {
         type code_module
         parent Mailman
         }
     
     component mailmanctl {
           type daemon
           parent bin
           requires {Locks}
           execs {master_qrunner, ArchRunner, BounceRunner, CommandRunner,
                 IncomingRunner, NewsRunner, OutgoingRunner, VirginRunner}
           }
     
     component Locks {
         type code_module
         parent Mailman
         reads {$var_prefix/locks}
         writes $var_prefix/locks, $var_prefix/locks/pending.lock}
         }
     

Mailman is the "application". All .psl files must contain a component that is labelled as the application. bin and Locks are "code_modules" that are part-of the Mailman application. These components may read or write to files or make socket connections. Note that in the example, $prefix is used indicating that at the time the application is written the location in the file structure will probably be set at configuration time and hence not known to developers. Polgen will resolve these unknown directories when it merges .psl and .tracked data. mailmanctl is a "daemon" since it executes a setsid command. Other processes are labelled simply as of type "process". Note that mailmanctl requires Locks. This indicates that a running mailmanctl may read from or write to any of the files indicated in the Locks module.


Next: , Previous: Capturing Program Behavior, Up: Top

5 Spar: Recognizing Patterns

These tools were designed to help SELinux administrators generate modular, predictable policy for individual programs. Our approach is based upon the identification of interaction patterns in program behavior, eventually at multiple abstraction levels. As patterns are recognized in program behavior (and perhaps modified by the user), policy targeted to those specific interactions can be generated. This approach will produce policy that is specifically tied to an individual program, and can support least-privilege in a predictable and repeatable way.

Currently, our tools look for low-level process interaction patterns in the behavior of the target program (such as the use of temporary files). For each of these individual patterns, our tools suggest policy descriptions to the end user, who can interactively determine the policy descriptions before actual .te and .fc files are generated.

The eventual use-case for this generation software is for large patterns to be recognized and communicated to the user, (e.g., "This program is a web server") based on a particular collection of modular sub-patterns found in the program's behavior (e.g., "This program is a network daemon listening on port 80 that uses configuration files, log files, and interacts with user files while running.").

5.1 Patterns Recognized by spar

Currently, spar recognizes some higher-level security patterns and some modular pattern "building blocks". The complete list of patterns recognized in program behavior follows. In some cases, there are multiple recognizer modules for each pattern. Future versions of these tools will recognize more patterns, and may also include more sophisticated recognizers for existing patterns.

spar also recognizes near-matches for patterns, and allows the user to confirm, deny, and/or modify policy for those near-patterns.

5.2 Running spar

The spar program provides you with the freedom to locate your tracking results (spar input), and results (spar output) in directories of your choosing. In what follows, we refer to these two directories as track_data_dir, and results_data_dir, respectively.

If you ran trackall with the -o option, track_data_dir will be the output directory you specified in the previous step.

The spar program is run from a Unix shell. The command line arguments for running spar are as follows.

This command is used to analyze data from the track_data_dir directory. The output is placed in the results_data_dir directory and the analyzed program name is myprog.

     $ spar -n myprog -d track_data_dir -o results_data_dir

When you run spar, you will see running commentary as spar reads tracked files generated from stracesc, identifies pattern use, and writes out results in XML and HTML formats. When the initial analysis is completed, spar prompts the user for refinements prior to generating .te and .fc files.

5.3 spar Output

Human intervention in the spar output files is almost certain to be needed before generating final policy. However, spar helps focus the human interaction by highlighting decision points and likely conflicts. It presents both complete sets of patterns to the user, and also identifies incomplete patterns, and incomplete groups of patterns (e.g., a program might be classified as a web server if only it used configuration files). There are three types of reports in spar's output directory.

5.4 Advanced Investigation Techniques

Most users will use spar in "batch" mode as described in these instructions thus far. However, if you are interested in examining spar capabilities in more detail, doing interactive explorations of a program's structure, or actually extending spar itself, this section provides information on the recognition process.

     class RecogPipeline (SpecObj):
         pattern = Pipeline
         detection = "correct"
     

Recognizers are written in a semi-declarative fashion. What appears above is a Python class which defines a recognizer for Pipeline. The class has several attributes including "pattern" (i.e., the name of the pattern that is recognized), "collections" (descriptions of how to locate the constituent parts of the pattern), and "focus_name" (the name of the resource at the top of the chain). spar will compile this semi-declarative description into procedural Python code and place it in the current directory. This procedural code walks through all the resources identifying each one as the focus_name participant and then follows information and execution flow to other resources looking for matches to the constraints embedded in the collections. For example,

     
     class RecogPipeline(SpecObj):
         pattern = Pipeline
         detection = Correct
         collections =
            [Recog("r1 in [f for f in obj.out_to('write')\
               if not config_namep(f.name)\
               and singleton(f.in_edges)]",
                  [Recog("middle in \
                       [m for m in r1.out_to('read') if m  != obj \
                        and m not in obj.receiving_from]", \
                         [Recog("r2 in \
                            [f for f in middle.out_to('write')
                             if not config_namep(f.name) \
                             and f != r1 and singleton(f.in_edges)]", \
                               [Recog("end = \
                                 [e for e in r2.out_to('read') if \
                                    e not in [obj, middle] +\
                                    obj.receiving_from +\
                                    middle.receiving_from]")])])])]
         focus_name = "begin"
     

In the example, an expression such as "r1_in [f for f in obj.out_to('write')]" indicates that the r1 participant in a pattern instance satisfies a constrain on its relationship to a process named "obj" - a local variable bound to the begin resource at top level. The format for Recog arguments is as follows. The first argument is a string of the form "participant-name = arbitrary Python code returning a list". The second optional argument is a list of additional recognition descriptions using the obj and any above participant names as local variables.

Running the procedural code stores solution trees in internal memory. A global class in the util module called PRGM holds all of the instances extracted. Each instance is a tree with root set to the "focus_name" participant and subtrees generated for collections of other participants. This information is stored as a dictionary with keys set to the names of the recognizers. Hence Util.PRGM.pattern_instances['RecogPipeline'] will return a collection of trees.

Items on these trees can then be explored in an interactive session using the Python interpreter.


Next: , Previous: Recognizing Patterns, Up: Top

6 Generating Policy

After spar is finished, there will be three types of file in the spar_output directory, HTML files, policy files, and an XML file that can be used for visualizations. The HTML files are meant to aid human understanding, and provide a hyper-linked way to browse the suggested policy (as described above in Recognizing Patterns).

The policy files contain both comments (lines beginning with '#') and uncommented lines that are the policy statements. The policy author can make appropriate modifications to this file by deleting or replacing uncommented lines, however, most changes are expected to be made using the graphical user interface. The generated policy statements include polgen specific macros, such as polgen_pipeline.


Next: , Previous: Generating Policy, Up: Top

7 Batch-Processing Script

The enclosed script runs the two programs that analyze stracesc output. Before use, it should be adjusted to fit your needs.

#! /bin/sh
# Run polgen post stracesc programs.
# Change the following settings to your tastes.

# Set this to polgen's bin directory if it is not on your path.
bindir=

# Derive the name of the system being analyzed
# from the current directory name.
name=$(basename $(pwd))

# Directory containing the stracesc output.
traces=traces

# Directory for file descriptor tracking output.
tracked=tracked

# Directory for spar output.
results=results

if [ ! -d "${tracked}" ]
then
  mkdir "${tracked}"
fi

"${bindir}trackall" -o "${tracked}" "${traces}"/*

if [ ! -d "${results}" ]
then
  mkdir "${results}"
fi

"${bindir}spar" -g -n "${name}" -d "${tracked}" -o "${results}"


Next: , Previous: Batch-Processing Script, Up: Top

8 Complete Example

8.1 Overview

This section describes an example of how to use our policy generation software. We have included instructions for the reader to run this example. Output from each step has been included. Each output file has the same name as the corresponding part of the example.

8.2 The E-Commerce Suite

For our example, we use a set of simple scripts designed to imitate an e-commerce software suite. There are three scripts, each representing a program we would want to design policy for: a server which receives orders over the network, an accounts receivable program which confirms that the order was legitimately paid for, and a shipping program which takes paid orders to be shipped. In addition, we have a client script which places an order. We will walk through the pattern analysis process using these simple programs.

The server is esales.py. Accounts receivable is acct_rcv.py. Shipping is shipping.py. The client is salesclient.py.

8.3 Installation

Requirements: Python 2.2.3 or higher. These instructions assume you will be performing the installation on an SELinux machine. As described above, you may perform analysis of the traces on another machine if you wish.

8.4 Package Installation

The polgen tarball includes the SPAR pattern recognition program, the SPAR pre-processor, a SELinux-aware version of strace, and typegen, which facilitates the generation of new types. In addition, we include our example E-Commerce suite.

For this example, we assume that you are installing polgen in your home directory.

     $ tar -xzf polgen-1.3.tar.gz
     $ cd polgen-1.3
     $ ./configure --prefix=$HOME/polgen
     $ make
     $ make install
     $ export PATH=$HOME/polgen/bin:$PATH

Now, we confirm that the programs were installed properly. This commands are optional, but we have included the expected output below for comparison. In particular, we are checking that the machine now has the SELinux-aware strace as well as the version originally installed on the machine.

     $ type -all stracesc
     stracesc is /home/LOGNAME/polgen/bin/stracesc

8.5 E-Commerce Suite installation:

The E-Commerce suite requires a directory which it can freely change. The ecomm-config script, which we added to your path, will copy all of the E-Commerce files into the current directory and configure them for your machine. NOTE: Do not perform these options in your home directory, or the file relabeling will not happen appropriately. (The /usr/share directory is a reasonable alternative.)

     $ su
     # cd /usr/share
     # mkdir ecomm
     # cd ecomm
     # ecomm-config

Next, we need to generate the file context and type files for the E-Commerce suite using typegen, which creates minimal policy additions for our new program. ecomm-config has installed a typegen.conf file in the ecomm directory, which we will use to generate our starting policy. The -i option allows us to specify the configuration file.

typegen.conf generates allow permissions for several normal security contexts (run getcon to find out) to transition to the example executable contexts. If you do not plan to run the example as user_r:user_t, sysadm_r:sysadm:t, or staff_r:staff_t, you will need to edit the typegen file.

     # typegen -i typegen.conf

Now, we can check to make sure that the installation was successful.

     # cat polgen_temp.fc
     /usr/share/ecomm/esales.py system_u:object_r:ecomm_polgen_temp_esales_exec_t
     /usr/share/ecomm/shipping.py system_u:object_r:ecomm_polgen_temp_shipping_exec_t
     /usr/share/ecomm/acct_rcv.py system_u:object_r:ecomm_polgen_temp_acct_rcv_exec_t
     /usr/share/ecomm/orders(/.*)? system_u:object_r:ecomm_polgen_temp_new_orders_dir_t
     /usr/share/ecomm/paid(/.*)? system_u:object_r:ecomm_polgen_temp_paid_orders_dir_t
     
     # ls *.py
     acct_rcv.py esales.py salesclient.py shipping.py

Last, we need to incorporate polgen_temp.te and polgen_temp.fc in the running policy. On FC3, we can use the following commands, replacing $HOME/polgen with wherever you installed polgen:

     # a=pol_source_directory
     # cp polgen_temp.te $a/domains/program
     # cp polgen_temp.fc $a/file_contexts/program
     # cp $HOME/polgen/share/polgen/polgen_macros.te $a/macros
     # pushd $a
     # make clean
     # make load
     # /usr/sbin/setfiles file_contexts/file_contexts /usr/share/ecomm

8.6 Dynamic Analysis of E-Commerce

We need to perform an analysis of the programs' behavior. As part of the pre-processing script, we use the stracesc program to tell us all of the system calls the program makes during its run. stracesc only tracks the program's behavior during a particular run, rather than its potential behavior, so for complex programs we need to run through a range of typical activities while tracing the program. For example, when tracing a web browser we would want to not only visit a few websites, but also make sure to change the browser's configuration and use standard plugins. Formally, stracesc performs dynamic, not static, analysis, so we need to execute all code paths. However, for this simple example, we don't need to worry about thorough testing.

For the example, we will need to run stracesc on each important segment of the E-Commerce suite: the e-sales server, accounts receivable, and shipping. We ignore the client, because we expect it to normally run on a different machine than the servers and are not trying to create the client machine policy.

     # pushd
     # mkdir traces
     # stracesc -fX -o traces/esales.py ./esales.py &

Running the client will give us a sample order.

     $ ./salesclient.py

Now, we kill the esales process. Normally, a server would run indefinitely, but we don't need the server any longer, now that we have an order. Next, trace accounts receivable and shipping. In normal operation, these might be executed with a cron job.

     $ fg; C-c
     $ stracesc -fX -o traces/acct_rcv.py ./acct_rcv.py
     $ stracesc -fX -o traces/shipping.py ./shipping.py

The trackall program is used to reduce the stracesc output into a form that can be used by the spar pattern recognizer.

     $ mkdir data
     $ trackall -o data traces/*

The .tracked files in data contain lists of system resources along with information about the permissions requested and relevant security contexts. These will be our input to the pattern detector. Sample .tracked files are included.

8.7 Looking for Patterns

The spar pattern detector identifies patterns in the system calls of a program or set of programs. These patterns demonstrate relations between programs, and describe interactions between programs and system resources. Many patterns will have security policy implications, which will help the user generate a secure policy for the program.

When running spar, you will need an input directory which contains all of your .tracked files, but nothing else. In our example, we will use the existing /usr/share/ecomm/data directory. The -n option specifies the program or suite name to be used for some output files.

     # mkdir results
     # spar -n ecommerce -d data -o results

After automation and interaction with the user, results will contain output files showing any patterns spar has found in the input along with the generated .te and .fc files. These files describe spar's findings for the user. Finally, there will be an xml file, ecommerce.xml, which can be used as input to an optional viewer.

Before you install the generated .te and .fc files, be sure to remove polgen_temp.te and polgen_temp.fc.

8.8 Interpreting Spar Results

spar produces HTML output files, each containing a different view on spar's findings.

PolicyHelp.html lists all resources used by the program, with annotations describing which patterns the resource matches, and what role the resource plays within a given pattern. Resources which did not match any pattern are also listed. A resource described as [security context]_INSTANCE indicates that spar-preprocess detected that some process with context [security context] but no traced execution attempted to access some other resource.

PatternInstances.html lists all patterns spar detected. The resources which matched each pattern are listed, along with their roles within the pattern. The listings are grouped by category; for example, several different configuration file recognition patterns are grouped under Config File.

SecurityContexts.html lists each security context which shows up in the spar-preprocess output, along with the resources which were observed to have that context.

9 Using polgen on non-Fedora systems

9.1 Using polgen on Debian GNU/Linux

The current version of polgen should work just fine on a Debian/Sid system. Only the pol_source_directory needs to change


Previous: Complete Example, Up: Top

Index