6.3 SELinux Policy Syntax
The railroad diagram in Figure 6-9 represents an
overview of the syntax of an
SELinux policy.
Figure 6-9. The SELinux Policy

As the figure shows, an SELinux policy consists of 11
elements, several of which are optional:
classes
Defines the security object classes
recognized by SELinux.
initial_sids
Defines initial SIDs for important
security objects.
access_vectors
Defines access vectors associated with
each security object class.
mls
Defines
MLS configuration (optional).

MLS is not currently implemented in sample SELinux policies and is
not covered in this book.
te_rbac
Defines type enforcement and role-based
access control configuration.
users
Defines
the user configuration.
constraints
Defines constraints that the security
policy must observe (optional).
initial_sid_contexts
Defines the security contexts of
important security objects.
fs_use
Defines the method of labeling of
filesystem inodes.
genfs_contexts
Defines security contexts for
filesystems lacking persistent labels (optional).
net_contexts
Defines security contexts for network
objects.
The policy elements must appear in the order indicated by the
railroad diagram. However, you generally don''''t have
to concern yourself with the order of policy statements, because each
type of statement resides in a designated file or directory. As
explained in Chapter 4, the SELinux policy
Makefile assembles these files into a single
file before compiling the policy source statements. The
Makefile ensures that policy statements are
presented to the policy compiler in the proper order. Table 6-1 shows the correspondence between the
policy elements and files in the
src/policy SELinux source tree.
Table 6-1. Policy elements and associated files
Element
File or directory (relative to src/policy)
classes
flask/security_classes
initial_sids
initial_sid_contexts
access_vectors
flask/acess_vectors
opt_mls
mls
te_rbac
rbac
*.te
domains/*.te
domains/misc/*.te
domains/programs/*.te
macros/*.te
macros/program/*.te
types/*.te
users
users
serviceusers (Fedora Core)
opt_constraints
constraints
initial_sid_contexts
flask/initial_sids
fs_uses
fs_use
opt_genfs_contexts
genfs_contexts
net_contexts
net_contexts

Table 6-1 shows files and directories used in the
Fedora Core 2 SELinux
implementation. The files may have different contents or locations
under other implementations of SELinux.
One of the most important policy elements,
te_rbac
, contains type enforcement and role-based
access control declarations. Along with the file context
configuration, the TE and RBAC configuration is the part of an
SELinux policy that is most often modified. Syntactically, the
te_rbac
element consists of a series
that freely intermingles two
subelementste_decl
and
rbac_decl
as shown in Figure 6-10.
Figure 6-10. TE and RBAC declarations (te_rbac)

6.3.1 Basic Policy Elements
Before presenting the syntax of the SELinux user
and role-based access control declarations, let''''s
look at a few subelements that appear in a variety of SELinux policy
elements and at a few principles that govern their use. Figure 6-11 shows the syntax of a subelement known as
identifier_list
.
As its name suggests, the subelement represents a list of
identifiers. An example of such a list appears in the following
declaration from the ping.te file:
allow ping_t self:rawip_socket { create ioctl read write bind
getopt setopt };
The curly braces enclose an identifier list specifying the
permissions related to a raw IP socket: create
,
ioctl
, read
,
write
, bind
,
getopt
, and setopt
.
Figure 6-11. The identifier_list subelement

Notice that the identifiers are separated from one another by white
space. Another subelement, id_comma_list
,
specifies a comma-separated list of identifiers. A railroad diagram
for this subelement appears as Figure 6-12.
Figure 6-12. The id_comma_list subelement

Another statement of the ping.te file provides
an example of this subelement:
type ping_exec_t, file_type, sysadmfile, exec_type;
In this statement, the identifiers ping_exec_t
,
file_type
, sysadmfile
, and
exec_type
appear as an
id_comma_list
.
Let''''s now consider some fine points of
railroad diagrams. Literals do not need
railroad diagrams to explain them, because they are labeled with the
values they match. Though literals sometimes appear in railroad
diagrams in uppercase form, the strings they represent can appear in
the SELinux policy in either uppercase or lowercase. So, with
reference to Figure 6-11, you can anticipate that
most
identifiers will appear in lowercase
rather than uppercase. That is, you should expect the following:
create, ioctl, read, write, bind, getopt, setopt
rather than:
CREATE, IOCTL, READ, WRITE, BIND, GETOPT, SETOPT
However, it''''s entirely permissible to specify
uppercase identifiers. It''''s just that SELinux policy
developers generally prefer not to do so. What matters is
consistency. The identifiers create
and
CREATE
are both legal but also entirely distinct,
because one uses lowercase letters whereas the other uses uppercase
letters.
Let''''s consider one more common policy subelement,
known as names
, which appears in Figure 6-13. This element can represent such strings as:
A single identifier
A list of identifiers separated from one another by white space,
enclosed within curly braces
An asterisk (*)
An identifier preceded by a tilde (~)
A list of identifiers separated from one another by white space and
enclosed within curly braces, and preceded by a tilde (~)
Two identifiers separated by a hyphen (-)
Figure 6-13. The names subelement and related subelements

Some rather bizarre extensions are also permissible. For instance,
the following is a valid
nested_id_set
subelement:
{ x -y { a b c } }
You may be curious about the meaning or use of this subelement. But,
for the moment, please focus merely on the syntax, not the meaning.
The meaning of the subelement emerges from the context in which it is
used. So rather than continue to examine subelementsa process
that could be continued indefinitelylet''''s
start looking at concrete examples by considering the
users
element, which is used to describe user
declarations.