|
Chris PeBenito |
3d76be |
Getting Started
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
26eac6 |
This guide will walk you through the basics of creating a new reference policy
|
|
Chris PeBenito |
26eac6 |
module. This will also serve as an introduction to the basics concepts and
|
|
Chris PeBenito |
26eac6 |
philosophy of refpolicy.
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
3d76be |
Creating A Module
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
26eac6 |
Modules are the principal organizing component in refpolicy. A module contains
|
|
Chris PeBenito |
26eac6 |
the policy for an application or related group of applications, private and shared
|
|
Chris PeBenito |
26eac6 |
resources, labeling information, and interfaces that allow other modules access
|
|
Chris PeBenito |
26eac6 |
to the modules resources. The majority of the global policy has been eliminated
|
|
Chris PeBenito |
26eac6 |
in refpolicy. Certain policy components, like users and object classes, are
|
|
Chris PeBenito |
26eac6 |
still global in refpolicy, but almost all TE policy is now contained within a
|
|
Chris PeBenito |
26eac6 |
module.
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
26eac6 |
Let's create a new module called myapp. This is done by creating three files:
|
|
Chris PeBenito |
26eac6 |
myapp.te, mayapp.fc, and myapp.if. The file myapp.te file will contain all of
|
|
Chris PeBenito |
26eac6 |
the policy private to this module, including any types or attributes. The file
|
|
Chris PeBenito |
26eac6 |
myapp.fc file will contain the file context labeling statement for this module.
|
|
Chris PeBenito |
26eac6 |
Finally, the file myapp.if will contain the interfaces for this module (interfaces
|
|
Chris PeBenito |
26eac6 |
will be explained below).
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
3d76be |
Module TE Policy
|
|
Chris PeBenito |
3d76be |
|
|
Karl MacMillan |
5ba9f0 |
First create myapp.te and add the following:
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
26eac6 |
policy_module(myapp,1.0)
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
3d76be |
# Private type declarations
|
|
Chris PeBenito |
3d76be |
type myapp_t;
|
|
Chris PeBenito |
3d76be |
type myapp_exec_t;
|
|
Chris PeBenito |
3d76be |
type myapp_log_t;
|
|
Chris PeBenito |
3d76be |
type myapp_tmp_t;
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
3d76be |
domain_type(myapp_t)
|
|
Chris PeBenito |
3d76be |
domain_entry_file(myapp_t, myapp_exec_t)
|
|
Chris PeBenito |
3d76be |
logging_log_file(myapp_log_t)
|
|
Chris PeBenito |
3d76be |
files_tmp_file(myapp_tmp_t)
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
26eac6 |
This creates all of the types needed for this module, including a type for the
|
|
Chris PeBenito |
26eac6 |
process, executables, log files, and temporary files. The first thing to notice
|
|
Chris PeBenito |
26eac6 |
is that there are no attributes applied to any of these types. In refpolicy all
|
|
Chris PeBenito |
26eac6 |
types and attributes can only be referred to in the module that declares them.
|
|
Chris PeBenito |
26eac6 |
This means that it is not possible, for example, to directly refer to the domain
|
|
Chris PeBenito |
26eac6 |
attribute. Instead, macros in other modules are used to declare that a type will
|
|
Chris PeBenito |
26eac6 |
be used for a certain purpose. These macros will likely use attributes (but not
|
|
Chris PeBenito |
26eac6 |
necessarily), but it allows the module that declared the attribute to strictly
|
|
Chris PeBenito |
26eac6 |
control how it can be used. In this example interfaces are used to transform the
|
|
Chris PeBenito |
26eac6 |
types into a domain, entry file, log file, and temporary file.
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
26eac6 |
Let's expand this example further by allowing some access for these types. My
|
|
Chris PeBenito |
26eac6 |
application needs access between it's own types and access to read random numbers.
|
|
Chris PeBenito |
26eac6 |
The access between private types is written exactly the same way current policy
|
|
Chris PeBenito |
26eac6 |
rules are written, i.e.:
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
347f40 |
allow myapp_t myapp_log_t:file ra_file_perms;
|
|
Chris PeBenito |
347f40 |
allow myapp_t myapp_tmp_t:file create_file_perms;
|
|
Chris PeBenito |
3d76be |
|
|
Chris PeBenito |
3d76be |
|
|
Karl MacMillan |
5ba9f0 |
This allows myapp_t to write to it's private types, but it needs to be able to
|
|
Karl MacMillan |
5ba9f0 |
create its temporary files in /tmp. This requires a call to the files module.
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
26eac6 |
files_tmp_filetrans(myapp_t,myapp_tmp_t,file)
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
347f40 |
|
|
Karl MacMillan |
5ba9f0 |
|
|
Chris PeBenito |
347f40 |
This call to the files module allows myapp_t to create myapp_tmp_t files in
|
|
Chris PeBenito |
347f40 |
the /tmp directory.
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
26eac6 |
Module FC Policy
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
The file contexts file lists files and the labels they should have. Create
|
|
Chris PeBenito |
26eac6 |
myapp.fc and add the following:
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
/usr/bin/myapp -- gen_context(system_u:object_r:myapp_exec_t,s0)
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
The gen_context() macro has three parameters, the base SELinux label,
|
|
Chris PeBenito |
26eac6 |
the MLS sensitivity, and the MCS category set (optional). When compiling a
|
|
Chris PeBenito |
26eac6 |
module, the macro will add the appropriate MLS/MCS part to the label when needed.
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
347f40 |
Module IF Policy
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
16e8e2 |
The interface file creates the macros that other modules will use to gain access
|
|
Chris PeBenito |
16e8e2 |
to my resources. This allows the module that created the type or attribute to
|
|
Chris PeBenito |
16e8e2 |
define appropriate uses. Additionally, it provides a single point for
|
|
Chris PeBenito |
16e8e2 |
documentation. Create myapp.if and add the following:
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
347f40 |
## <summary>Myapp example policy</summary>
|
|
Chris PeBenito |
16e8e2 |
## <desc>
|
|
Chris PeBenito |
16e8e2 |
## <p>
|
|
Chris PeBenito |
16e8e2 |
## More descriptive text about myapp. The <desc>
|
|
Chris PeBenito |
16e8e2 |
## tag can also use <p>, <ul>, and <ol>
|
|
Chris PeBenito |
16e8e2 |
## html tags for formatting.
|
|
Chris PeBenito |
16e8e2 |
## </p>
|
|
Chris PeBenito |
16e8e2 |
## <p>
|
|
Chris PeBenito |
16e8e2 |
## This policy supports the following myapp features:
|
|
Chris PeBenito |
16e8e2 |
## <ul>
|
|
Chris PeBenito |
16e8e2 |
## <li>Feature A</li>
|
|
Chris PeBenito |
16e8e2 |
## <li>Feature B</li>
|
|
Chris PeBenito |
16e8e2 |
## <li>Feature C</li>
|
|
Chris PeBenito |
16e8e2 |
## </ul>
|
|
Chris PeBenito |
16e8e2 |
## </p>
|
|
Chris PeBenito |
16e8e2 |
## </desc>
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
26eac6 |
########################################
|
|
Chris PeBenito |
347f40 |
## <summary>
|
|
Chris PeBenito |
347f40 |
## Execute a domain transition to run myapp.
|
|
Chris PeBenito |
347f40 |
## </summary>
|
|
Chris PeBenito |
16e8e2 |
## <param name="domain">
|
|
Chris PeBenito |
2b10a6 |
## <summary>
|
|
Chris PeBenito |
347f40 |
## Domain allowed to transition.
|
|
Chris PeBenito |
2b10a6 |
## </summary>
|
|
Chris PeBenito |
16e8e2 |
## </param>
|
|
Chris PeBenito |
16e8e2 |
interface(`myapp_domtrans',`
|
|
Chris PeBenito |
347f40 |
gen_requires(`
|
|
Chris PeBenito |
347f40 |
type myapp_t, myapp_exec_t;
|
|
Chris PeBenito |
347f40 |
')
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
347f40 |
domain_auto_trans($1,myapp_exec_t,myapp_t)
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
347f40 |
allow $1 myapp_t:fd use;
|
|
Chris PeBenito |
347f40 |
allow $1 myapp_t:fifo_file rw_file_perms;
|
|
Chris PeBenito |
347f40 |
allow $1 myapp_t:process sigchld;
|
|
Chris PeBenito |
347f40 |
')
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
26eac6 |
########################################
|
|
Chris PeBenito |
347f40 |
## <summary>
|
|
Chris PeBenito |
347f40 |
## Read myapp log files.
|
|
Chris PeBenito |
347f40 |
## </summary>
|
|
Chris PeBenito |
16e8e2 |
## <param name="domain">
|
|
Chris PeBenito |
2b10a6 |
## <summary>
|
|
Chris PeBenito |
347f40 |
## Domain allowed to read the log files.
|
|
Chris PeBenito |
2b10a6 |
## </summary>
|
|
Chris PeBenito |
16e8e2 |
## </param>
|
|
Chris PeBenito |
16e8e2 |
interface(`myapp_read_log',`
|
|
Chris PeBenito |
347f40 |
gen_requires(`
|
|
Chris PeBenito |
347f40 |
type myapp_log_t;
|
|
Chris PeBenito |
347f40 |
')
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
347f40 |
logging_search_logs($1)
|
|
Chris PeBenito |
347f40 |
allow $1 myapp_log_t:file r_file_perms;
|
|
Chris PeBenito |
347f40 |
')
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
347f40 |
|
|
Karl MacMillan |
5ba9f0 |
|
|
Chris PeBenito |
347f40 |
The first interface allows other domains to do a domain
|
|
Chris PeBenito |
347f40 |
transition to myapp_t, by executing a program labeled myapp_exec_t.
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
347f40 |
The second interface allows other domains to read myapp's log files. Myapp's
|
|
Chris PeBenito |
347f40 |
log files are in the /var/log directory, so the access to search the /var/log
|
|
Chris PeBenito |
347f40 |
directory is also given by the interface. The gen_requires() macro is used to
|
|
Chris PeBenito |
1d85c7 |
support loadable policy modules, and must explicitly list the type and attributes
|
|
Chris PeBenito |
1d85c7 |
used by this interface. If object classes of a userland object manager are used,
|
|
Chris PeBenito |
1d85c7 |
the class and the permissions used by the interface must also be listed.
|
|
Chris PeBenito |
347f40 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
Compiling Modules
|
|
Chris PeBenito |
2b10a6 |
|
|
Chris PeBenito |
2b10a6 |
Two methods of building modules are supported, headers and complete source.
|
|
Chris PeBenito |
26eac6 |
Current systems, such as Fedora Core 5, which support loadable policy modules
|
|
Chris PeBenito |
26eac6 |
should compile modules using headers. Using the complete source for building
|
|
Chris PeBenito |
26eac6 |
modules is only needed if loadable modules are not supported on the system or
|
|
Chris PeBenito |
26eac6 |
if when doing other modifications to the base policy. Genereally this is only
|
|
Chris PeBenito |
26eac6 |
suggested for experts.
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
Building Using Policy Headers
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
When building a loadable policy module, the three module source files need not
|
|
Chris PeBenito |
26eac6 |
be in a specific directory. A development directory in the user's home directory
|
|
Chris PeBenito |
26eac6 |
would be sufficient. In this example, lets place it in the policy directory
|
|
Chris PeBenito |
26eac6 |
in the home directory. The example Makefile should be copied to this directory.
|
|
Chris PeBenito |
26eac6 |
It is usually located in the /usr/share/doc/PKGNAME directory, where PKGNAME
|
|
Chris PeBenito |
26eac6 |
is the name of the policy package that has the policy headers.
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
$ cp /usr/share/doc/refpolicy-20060307/Makefile.example ~/policy/Makefile
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
Alternatively, this can be copied from the Reference Policy source, from the doc
|
|
Chris PeBenito |
26eac6 |
directory. The Makefile is not required, but will simplify the process.
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
Now the policy directory should have the three module source files and Makefile.
|
|
Chris PeBenito |
df1c28 |
All that needs to be done is to run make, and the policy will be compiled.
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
$ make
|
|
Chris PeBenito |
26eac6 |
Compiling targeted myapp module
|
|
Chris PeBenito |
26eac6 |
/usr/bin/checkmodule: loading policy configuration from tmp/myapp.tmp
|
|
Chris PeBenito |
26eac6 |
/usr/bin/checkmodule: policy configuration loaded
|
|
Chris PeBenito |
26eac6 |
/usr/bin/checkmodule: writing binary representation (version 5) to tmp/myapp.mod
|
|
Chris PeBenito |
26eac6 |
Creating targeted myapp.pp policy package
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
If you do not have the example Makefile, you must tell make where to find the
|
|
Chris PeBenito |
26eac6 |
policy header's Makefile, by using the -f option. The Makefile for the base
|
|
Chris PeBenito |
26eac6 |
policy provided by the Linux distribution should be found in the
|
|
Chris PeBenito |
26eac6 |
/usr/share/selinux/NAME/include directory, where NAME is the name
|
|
Chris PeBenito |
26eac6 |
of the policy, for example, strict or targeted.
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
$ make -f /usr/share/selinux/targeted/include/Makefile
|
|
Chris PeBenito |
26eac6 |
Compiling targeted myapp module
|
|
Chris PeBenito |
26eac6 |
/usr/bin/checkmodule: loading policy configuration from tmp/myapp.tmp
|
|
Chris PeBenito |
26eac6 |
/usr/bin/checkmodule: policy configuration loaded
|
|
Chris PeBenito |
26eac6 |
/usr/bin/checkmodule: writing binary representation (version 5) to tmp/myapp.mod
|
|
Chris PeBenito |
26eac6 |
Creating targeted myapp.pp policy package
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
When this succeeds, there will be a myapp.pp policy package that can be inserted
|
|
Chris PeBenito |
26eac6 |
into the running policy To load the module, you must be running as root, in a
|
|
Chris PeBenito |
26eac6 |
role allowed to run semodule. Then run semodule -i to insert the module into
|
|
Chris PeBenito |
26eac6 |
the running policy.
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
# semodule -i myapp.pp
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
The semodule command will only have messages if there is an error inserting the
|
|
Chris PeBenito |
26eac6 |
module. If it succeeds, semodule -l should list the myapp module, and the version.
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
# semodule -l
|
|
Chris PeBenito |
26eac6 |
myapp 1.0
|
|
Chris PeBenito |
26eac6 |
|
|
Chris PeBenito |
26eac6 |
|