|
|
|
|
NOTE: CentOS Enterprise Linux is built from the Red Hat Enterprise Linux source code. Other than logo and name changes CentOS Enterprise Linux is compatible with the equivalent Red Hat version. This document applies equally to both Red Hat and CentOS Enterprise Linux.
This section discusses the types associated with the dhcpd policy.
|
Note |
|
SELinux policy uses a number of macros written in the m4 macro
language to make policy writing easier. In a type enforcement file
such as dhcpd.te, macros are used
extensively to call common capabilities for subjects and targets.
These are discussed in Section 2.9 Policy Macros
and Section 3.4 Common
Macros in the Targeted Policy.
For the purposes of dissecting the dhcpd policy, this section is based on what is found
in the policy.conf file. Since this file
is created by the build process, the macros have been expanded
entirely. It takes some practice, but soon you can find and
understand the macros and the associated rulesets in the TE files
from $SELINUX_SRC/domain/programs/.
|
- dhcpd_t
-
This is the main, top-level domain for the dhcpd daemon. Nearly every rule in $SELINUX_SRC/domain/programs/dhcpd.te deals with
this type, most notably the macros that expand into numerous rules.
A complete list can be obtained using the apol tool. This is discussed further in Chapter 6 Tools for Manipulating
and Analyzing SELinux. Some highlighted rules are:
-
Various specific manipulations of the dhcpd_*_t domains, as explained below in
further examples under each context..
-
Network rules necessary for dhcpd to do
its work, such as tcp_recv,
udp_recv, and rawip_recv to network interfaces. Some
examples are:
allow dhcpd_t netif_type : netif { tcp_send udp_send
rawip_send };
allow dhcpd_t node_type : node { tcp_recv udp_recv \
rawip_recv };
|
-
Socket rules needed by dhcpd to create,
listen, connect, accept, bind, read, write, control input and
output (ioctl), get
(getattr) and set (setattr) attributes, send (send_msg) and receive (recv_msg) messages, get (getopt) and set (setopt) command options, and so forth.
Socket objects controlled are tcp_socket, udp_socket, netlink_route_socket, rawip_socket, unix_dgram_socket, unix_stream_socket, and reserved_port_socket. These are all object
classes that SELinux controls the access to. Some examples are:
allow dhcpd_t node_type : { tcp_socket udp_socket } \
node_bind ;
allow dhcpd_t port_type : { tcp_socket udp_socket } \
{ send_msg recv_msg };
allow dhcpd_t port_type : { tcp_socket udp_socket } \
{ send_msg recv_msg };
allow dhcpd_t self : rawip_socket { create ioctl read \
getattr write setattr append bind connect getopt \
setopt shutdown };
allow dhcpd_t self : tcp_socket { create ioctl read \
getattr write setattr append bind connect getopt \
setopt shutdown listen accept };
allow dhcpd_t self : udp_socket { create ioctl read \
getattr write setattr append bind connect getopt \
setopt shutdown };
allow dhcpd_t self : unix_dgram_socket { create \
ioctl read getattr write setattr append bind \
connect getopt setopt shutdown };
allow dhcpd_t self : unix_stream_socket { create \
ioctl read getattr write setattr append bind \
connect getopt setopt shutdown };
|
-
As a network service, dhcpd is allowed
to open a TCP or UDP socket to send and receive messages from any
port. The attribute port_type
covers a long list of ports: dns_port_t, dhcpd_port_t, http_cache_port_t, port_t, reserved_port_t, http_port_t, pxe_port_t, smtp_port_t, mysqld_port_t, rndc_port_t, ntp_port_t, portmap_port_t, postgresql_port_t, snmp_port_t, syslogd_port_t. The rule looks like
this:
allow dhcpd_t port_type:{ tcp_socket udp_socket } \
{ send_msg recv_msg };
|
-
This rule allows dhcpd to control the
dhcpd_t type, that is, itself,
for process signaling:
allow dhcpd_t self : process { sigchld sigkill sigstop \
signull signal fork };
|
- dhcpd_exec_t
-
This is the file type for the dhcpd
executable. This type is the entry point for the dhcpd_t domain.
- dhcpd_port_t
-
The dhcpd_port_t type has
one direct rule governing it:
allow dhcpd_t dhcpd_port_t : udp_socket name_bind;
|
The daemon with the domain of dhcpd_t, that is, dhcpd, has the permission to bind to the object
class of udp_socket, which opens a UDP port. Policy states that UDP
port 67 is created with the domain of dhcpd_port_t:
grep dhcpd_port_t $SELINUX_SRC/net_contexts
ifdef(`use_dhcpd', `portcon udp 67 system_u:object_r:\
dhcpd_port_t')
|
SELinux has controls for port binding, meaning it is able to
allow or deny port binding requests based on security labels.
However, SELinux only controls attempts to bind to reserved ports,
which are ports less than 1024, and to ports outside of the local
port range, which is set in /proc/sys/net/ipv4/ip_local_port_range.
If dhcpd tries to bind to any port
other than 67 port that is reserved or outside of the local range,
the daemon is denied. This is because dhcpd_t is only allowed to bind to a port
with the type of dhcpd_port_t,
and only one port has that type, port 67.
- dhcpd_state_t
-
This type dhcpd_state_t is
the file type for the dhcpd lease file
located at /var/lib/dhcp/dhcpd.leases.
The dhcpd daemon is allowed to create,
read, write, etc. a file with the context of dhcpd_state_t:
allow dhcpd_t dhcpd_state_t : file { create ioctl read \
getattr lock write setattr append link unlink rename };
type_transition dhcpd_t dhcp_state_t : file dhcpd_state_t;
|
The second rule is a type_transition rule that comes from a
macro defined in $SELINUX_SRC/macros/core_macros.te and used in the
dhcpd.te file, file_type_auto_trans(dhcpd_t, dhcp_state_t,
dhcpd_state_t, file).
This rule ensures that unless explicitly overwritten by the
dhcpd daemon, when the daemon creates a
regular file (object class file) in a directory with the type
dhcpd_state_t, the file is
automatically assigned the file context of dhcp_state_t. This allows the dhcpd daemon to fully control just the DHCP lease
files in /var/lib/dhcp/ and not, for
example, the dhclient files in the same
directory.
This shows a case where the policy explicitly does not want a
file to gain the default label from the parent directory. To
prevent this, a type_transition
is put into place to guide the context when the file is
created.
- dhcpd_tmp_t
-
There are several direct rules and transitions for dhcpd_tmp_t, and multiple indirect rules
through the attribute file_type.
These rules describe how dhcpd_t can act upon an object of the type
dhcpd_tmp_t, which is the type
of the dhcpd temporary files in /tmp/. For example, dhcpd_t can create, read, and get and set
file attributes on files, socket files, and FIFO files that have
the type dhcpd_tmp_t. Similar
actions can be done with directories (dir) and file linking (lnk_file):
allow dhcpd_t dhcpd_tmp_t : { file sock_file fifo_file } \
{ create ioctl read getattr lock write setattr append link \
unlink rename };
allow dhcpd_t dhcpd_tmp_t : lnk_file { create read getattr \
setattr link unlink rename };
allow dhcpd_t dhcpd_tmp_t : dir { create read getattr lock \
setattr ioctl link unlink rename search add_name \
remove_name reparent write rmdir };
|
Having this separate derived type isolates the dhcpd temporary files to ensure that only dhcpd can read and write these files, and not any
other daemon. Similarly, other temporary files are protected by
being in their own type that dhcpd cannot
access. For example, this protects the daemon from using a
malicious symlink in /tmp/.
These rules enable the dhcpd daemon to
create its files and directories in /tmp.
The first rule specifies that when the dhcpd_t domain creates a file in a
directory with the type tmp_t,
the new subdirectory should be labeled with the dhcpd_tmp_t type. Similarly, the second
rule specifics the same transition for a file, file link, socket
file, or FIFO (named pipe):
type_transition dhcpd_t tmp_t : dir dhcpd_tmp_t;
type_transition dhcpd_t tmp_t : { file lnk_file sock_file \
fifo_file } dhcpd_tmp_t;
|
The indirect rules are derived from rules associated with the
file_type attribute. These deal
with allowing file systems to associate default file types, and the
manipulation of file_type
objects such as dhcpd_tmp_t by
the unconfined_t domain:
allow { file_type device_type } fs_t : filesystem associate;
allow file_type removable_t : filesystem associate;
allow file_type nfs_t : filesystem associate;
allow unconfined_t file_type : filesystem *;
allow unconfined_t file_type : { dir file lnk_file sock_file \
fifo_file chr_file blk_file } *;
allow unconfined_t file_type : { unix_stream_socket \
unix_dgram_socket } name_bind;
|
The dhcpd_tmp_t type is also
influenced by two generic neverallow assertions. Assertions are
discussed in Section 2.8
TE Rules - Access Vectors.
- dhcpd_var_run_t
-
This security context is also part of the file_type attribute and shares those rules
with dhcpd_tmp_t and others.
The direct rules that govern dhcpd_var_run_t allow the dhcpd_t domain to manipulate files and
directories with the dhcpd_var_run_t type in the /var/run/ file system. This is the directory where
process IDs exist, and this rule allows for the creation and
manipulation of /var/run/dhcpd.pid :
allow dhcpd_t dhcpd_var_run_t : file { create ioctl read \
getattr lock write setattr append link unlink rename };
allow dhcpd_t dhcpd_var_run_t : dir { read getattr lock \
search ioctl add_name remove_name write };
type_transition dhcpd_t var_run_t : file dhcpd_var_run_t;
|
- dhcp_etc_t
-
The two direct rules using this type allow the dhcpd_t domain to read and get attributes
on files of the type dhcp_etc_t, as well as search directories
of the same type. This means the daemon cannot overwrite the
configuration file. Indirect rules derive from the dhcp_etc_t type being part of the
file_type attribute set, along
with dhcpd_tmp_t, dhcpd_var_run_t, and others:
allow dhcpd_t dhcp_etc_t : file { read getattr };
allow dhcpd_t dhcp_etc_t : dir search;
|
- dhcp_state_t
-
In addition to being covered by the rules governing the
file_type attribute, this file
type has two direct policy rules. The first allows the dhcpd_t domain to perform standard file
system functions, such as read, write, and lock on directories,
with the type dhcp_state_t.
This directory is defined as /var/lib/dhcp/ in $SELINUX_SRC/file_contexts/program/dhcpc.fc, and is
where dhcpd stores its lease files. The
second rule is the transition rule stating when the dhcpd_t domain creates a file in a
directory labeled dhcp_state_t,
this file gets a security type of dhcpd_state_t:
allow dhcpd_t dhcp_state_t : dir { read getattr lock search \
ioctl add_name remove_name write };
type_transition dhcpd_t dhcp_state_t : file dhcpd_state_t;
|
|
Note |
|
There are two distinct security contexts being discussed here:
dhcp_state_t and dhcpd_state_t.
dhcp_state_t is the type of
the directory /var/lib/dhcp where both
dhcpd and other clients and daemons store
DHCP lease information.
dhcpd_state_t is the type in
the security label of a DHCP lease file created in /var/lib/dhcp by the dhcpd
daemon, running in the domain of dhcpd_t.
The dhcpd_state_t type is a
derivative type, the way dhcpc_state_t derives from the dhcpc_t domain in a stricter policy.
In the /var/lib/dhcp directory, the
only allowed actions of the dhcpd_t domain are a series of
directory-level operations. The domain cannot affect the files
within unless those files are of the type dhcpd_state_t:
allow dhcpd_t dhcpd_state_t:file { create ioctl read getattr lock \
write setattr append link unlink rename };
|
This separation allows the different DHCP applications to keep
lease information in the same, traditional directory, yet not be
able to affect other DHCP program files.
|
|
|
|