Macros in SELinux are discussed in Section 2.9 Policy Macros. This section covers macros that
are used extensively throughout the targeted policy. These were chosen by
frequency, the list comprising mainly macros used nine or more times in
the various policy files. A large number of macro files are present in
the policy, but are not necessarily called by any of the TE files. There
are macro files for many, but not all, of the targeted daemons.
daemon_domain,
daemon_base_domain, and
daemon_core_rules
The macro daemon_domain is in
$SELINUX_SRC/macros/global_macros.te, and is common
to all of the targeted daemons. The purpose of
daemon_domain is to group together
permission needs common to all daemons. These needs include
creating a process ID (PID) file and running
df to check disk usage. In addition, two macros
are called, daemon_base_domain and
read_locale.
The base common set of type declarations and permissions is defined
in daemon_base_domain, and include
allowing you to define a tunable that can disable the domain
transition. You evoke one of these tunables when you set the
Boolean value to disable the transition to one of the targeted
domains, removing SELinux protection from that single daemon. Finally,
daemon_core_rules is called.
This central macro is where the daemon's top-level domains and
roles are declared:
define(`daemon_core_rules', `
type $1_t, domain, privlog $2;
type $1_exec_t, file_type, sysadmfile, exec_type;
daemon_core_rules gives a daemon
the right to inherit and use descriptors from init, calls the
uses_shlib() macro for the domain
to use shared libraries, allows for common self signaling, and so
forth.
can_network
Providing a top-level entry point for common networking policy,
this macro appears in
$SELINUX_SRC/macros/global_macros.te. One primary
allow rule gives the domain access to TCP and UDP sockets to create,
send and receive on a network interface from any node on any port.
Read permission is granted for network files, which are
configuration files in /etc/ that network
daemons need, mainly /etc/resolv.conf:
The limitations on which nodes and ports are allowed by domain are
defined in separate rules. Recall that by default, everything is
denied in SELinux. The allow rules
here grant only the permission to, for example, make a
bind(2) call to the socket, but the specific port
binding requires another authorization. The permission
name_bind to bind to the port is
still limited by the domain, so that, for example, named may be
allowed by standard Linux permissions to bind to port 22, but SELinux
blocks access and generates an avc:
denied message in $AUDIT_LOG. This is because
named_t is not allowed to bind to a
port of type ssh_port_t, which is
the type for the SSH port.
can_unix_connect
This popular macro from core_macros.te
provides permissions for establishing a UNIX stream connection:
The can_unix_connect macro handles the control
between the two domains. In addition, the socket needs write
permission to the file associated with the socket. For this reason
the can_unix_connect macro is
paired with other allow rules in
the policy:
# From $SELINUX_SRC/domains/program/syslogd.te
allow privlog devlog_t:sock_file rw_file_perms;
...
can_unix_connect(privlog, syslogd_t)
create_dir_file
Common permissions for creating directories, regular files, and
symlinks are grouped into this macro from
core_macros.te:
This is a single line macro from
core_macros.te that expands into a list of
permissions needed to create and manage sockets. This macro is
inserted directly into a rule, and gives a single location to define
this common permissions set. This is the macro followed by an
example rule evoking the macro:
When you want a particular transition to be the default
transition behavior for a domain, use
domain_auto_trans, from
core_macros.te. It calls
domain_trans() to do the actual
work. If you just want to allow a transition to take place and
handle the context with setexeccon(), you
can use just a domain_trans():
The domain_trans macro allows the
parent process a typical set of permissions to transition to the new
domain. It sets a few dontaudit
rules, allows the parent process to execute the program, allows the
child to reap the new domain and exchange and use file descriptions
with the parent process, as well as write back to the old domain via
a named pipe (FIFO). Finally, the new domain is given permission to
read and execute the program, making the program the entry point for
the domain.
Because only one transition can be the default for a given pair of
types, you can have one
domain_auto_trans rule followed by
multiple domain_trans rules that
allow other options. These can be used by a security-aware
application.
file_type_auto_trans and
file_type_trans
From core_macros.te,
file_type_trans allows the
permissions for the given domain to create files in the given parent
directory that have the given file type. These givens are inserted
as the variables $1 and so forth.
To make a particular transition the default behavior, use
file_type_auto_trans().
This macro has a built-in conditional that it can take three or four
parameters in defining the output
type_transition rule:
# file_type_auto_trans(creator_domain, parent_directory_type, \
file_type, object_class)
#
# the object class will default to notdevfile_class_set if not
# specified as the fourth parameter
define(`file_type_auto_trans',`
ifelse(`$4', `', `
file_type_trans($1,$2,$3)
type_transition $1 $2:dir $3;
type_transition $1 $2:notdevfile_class_set $3;
', `
file_type_trans($1,$2,$3,$4)
type_transition $1 $2:$4 $3;
')dnl end ifelse
')
The file_type_trans allows the
process to modify the directory and create the file, all with the
proper labeling. As with
domain_auto_trans, you can specify
additional allowed options for use by security-aware applications
that can call setexeccon().
The optional fourth parameter, $4,
lets you specify a particular file object class. The default is
non-device files, notdevfile_class_set().
r_dir_perms,
r_file_perms,
rw_file_perms, and
ra_file_perms
These single line macros from
core_macros.te are used directly in TE rules to
group common permission sets depending on the need to read, write,
append, and execute files and directories:
# Permissions for reading directories and their attributes.
#
define(`r_dir_perms', `{ read getattr lock search ioctl }')
#
# Permissions for reading files and their attributes.
#
define(`r_file_perms', `{ read getattr lock ioctl }')
#
# Permissions for reading and writing files and their
# attributes.
#
define(`rw_file_perms', `{ ioctl read getattr lock write \
append }')
#
# Permissions for reading and appending to files.
#
define(`ra_file_perms', `{ ioctl read getattr lock append }')
tmp_domain
This macro identifies the domain as needing to be able to create
temporary files in /tmp/. A file transition is
setup for temporary files created by the domain. A separate
temporary type, $1_tmp_t, is
declared. This type is used to label temporary files created by the
domain so that each domain may only read and write its own temporary
files. Additional rules may be written that allow permissions for
domains to control temporary files of other domains, such as
allowing tmpwatch to clean up
/tmp/. Most of the targeted daemons use this
macro: