
A Functional Specification for an Automated SELinux Policy Generator

			Version 0.01.20030220
			    Clem Skorupka
			     Mark Heroux
				   
Overview
--------

This document is a functional specification for software that will
automate many of the steps required to generate an SELinux policy for
an individual program or package.


Goals
-----

In this version, capture and simplify the process of creating
policies.

Ultimately, generation of policy statements that implement a
consistent set of higher-level policy goals.


Non-goals
---------

This software is not intended to enforce a particular policy or
security objective.


Assumptions
-----------

 1. An existing base policy; typically, the original sample policy
    contained in the SELinux distribution.   
 2. The scripts/newrules.pl utility behavior does not change.  
 3. SELinux running in "permissive mode".  
 4. User with sufficient privileges to run newrole and to transition
    to other roles as required. 


Approach
--------

This version takes an approach to policy generation that mimics
straightforward, common manual practices.  For the intitial version,
basically a "seed policy" is generated that consists of: 

  - Domain and executable types derived from the program or package
    name, 
  - Type transition rules to account for initial launching of the
    program, and
  - File contexts to assign to program components.

This seed policy is incorporated into the existing policy, and the
program is launched (and later versions will approach other program
exercising).  Deny messages (which refer to the seed types) are
collected and converted to "allow" statements using the newrules.pl
utility.


Functional Requirements
-----------------------

The program must generate syntactically correct SELinux policy
statements that allow an arbitrary program to run on an SELinux system
in "enforcing mode".  The program must not inadvertently overwrite
existing .fc or .te data due to namespace collisions.  There must be
an ability to "back out" changes made to SELinux policy and policy
tree: original policy.conf, entire contents of original
.../selinux/policy/*. 


User Inputs (in configuration file polgen.conf) 
-----------------------------------------------

 - Name of a program or package
 - Names and locations of additional components such as pathnames to
   executables, log files, configuration files, libraries (static and
   shared).  Regular expressions permissible
   (e.g. /usr/local/<progname>/* ) 
 - Base directory of SELinux distribution; typically,
   /usr/local/selinux. 
 - Initial type that will launch the program or executable (for
   example user_t, or sysadm_t )
 - Initial role of launcher (for example user_r, or sysadm_r )

See Appendix A for sample configuration file.


Static Inputs
-------------

For collision avoidance, inspect files of this form/location
.../policy/domains/program/*.te
.../policy/domains/*.te
.../policy/types/*.te
.../policy/macros/*.te
.../policy/file_contexts/*.fc

.../selinux/scripts/newrules.pl newrules.pl is a selinux utility that
converts "avc deny" messages to "allow" statements.


Outputs
-------

 1. "collision avoidance report" that lists possible namespace
    collisions between user inputs and static inputs.  
 2. "Seed Types" report, where seed types are the new types, type
    transitions, and process transition rules generated before "avc
    deny" messages are harvested.
 3. <program name>.fc
 4. <program name>.te


Functional Flow
---------------

 1. Back up original policy.conf, entire contents of original
    .../selinux/policy/*; If backup fails, exit with error message. 

 2. Read user configuration file; if file read fails, exit with error
    message. 

 3. Grep for <progname> in static inputs as documented above to detect
    collisions; exit on collision detection with "collision avoidance
    report". 

 4. Generate "seed policy" statements:
     - type <progname>_t, domain;
     - type <progname>_exec_t, file_type, exec_type;
     - type_transition <launch_type> <progname>_exec_t: process
       <progname>_t; 
     - allow <launch_type> <progname>_t: process transition; 

    where <launch_type> is typically one of:
     - user_t
     - sysadm_t
     - system_t

 5. Write to <progname>.te:

     <progpath> system_u:object_r:<progname>_exec_t

 6. Write to <progname>.fc

 7. Invoke "make relabel" command.

 8. Rebuild policy.conf with "make reload" in .../selinux/policy

 9. Invoke "dmesg -c"

 10. Invoke "newrole -t <launch_type>

 11. Invoke "newrole -r <launch_role> (derive from <launch type>,
     e.g. <launch>_t, <launch>_r) 

 12. Open  /var/log/messages; advance file pointer to EOF; tail -f 

 13. Launch <progpath>; allow to run for max of 30 seconds then kill
     if necessary. 

 14. Capture pertinent "deny" messages from /var/log/messages; write
     to <file> 

 15. Invoke "newrules.pl -i <file> -v >> <progname>.te"

 16. Exit


========

Appendix A - Sample Configuration File
--------------------------------------

# Sample polgen.conf

name <name of program or package>

path <pathname to executable or other object; may be a regular expression>

# Note: need to create means to cope with programs or packages with
# multiple components

base <base directory of SELinux distribution; typically, /usr/local/selinux>

type <initial type at program launch; for example user_t, or sysadm_t>

role <role of launcher; for example user_r, or sysadm_r>

# Note: need to create means to specify multiple initial roles and
# types for launcher

	

Appendix B - Future Steps
-------------------------

 - Device handling
 - Other special file handling ( named pipes, for example...) Automate
   namespace collision resolution (e.g. rename a proposed type
   "myprog_t" to "myprog2_t" ..
 - Multi-component programs/packages
 - Additional type transitions associated with typical server behavior
