The remaining LSM hooks are defined directly in the top-level
struct security_operations
. Most of these
hooks are used to control Linux system operations. This section describes
the SELinux hook function implementations for these system hooks.
This hook function is called by the kernel to determine whether a
particular Linux capability is granted to a task. After calling the
secondary security module to perform the ordinary Linux capability
test or superuser test, this hook function calls the
task_has_capability
helper function to check the
corresponding SELinux capability permission. Hence, the Linux
capability must be granted by both the secondary security module and
by SELinux.
This hook function is called by the kernel to get the capability sets
associated with a task. It first checks capget
permission between the current and target tasks. If this permission
is granted, it then calls the secondary security module to obtain
the capability sets, since SELinux does not maintain this information.
This hook function is called by the kernel to check permission before
setting the capability sets associated with a task or a set of tasks.
It checks capset
permission between the current
and target tasks, and also calls the secondary module to permit it to
perform any additional capability checking. However, this check is not always
meaningful, since the target task is also set to current if a set of
tasks was specified to the capset
system call.
This hook function is called by the kernel to set the capability sets
associated with a task. It also checks capset
permission between the current and target tasks since the target task
may have been inaccurate in the
selinux_capset_check
hook function. It then
calls the secondary module to set the capability sets, since SELinux
does not maintain this information. SELinux does not perform any
checks on the individual capabilities being set, since it revalidates
each capability on use in the selinux_capable
hook.
This hook function is called to save security information for a
netlink message when the message is sent. The kernel
capable
function is called to check whether the
current task (the sender) has the CAP_NET_ADMIN
capability and the corresponding SELinux
net_admin
permission. If so, then this
capability is raised in the effective capability set associated with
the netlink message. Otherwise, the effective capability set is
cleared.
This hook function is called to check permission when a netlink
message is received. It checks the effective capability set
associated with the netlink message to see if
CAP_NET_ADMIN
is set.
Some system operations are controlled by both the
capable
hook and a separate hook that offers
finer-grained control. In many of these cases, the checking performed
by selinux_capable
is adequate for SELinux, so no
other processing is required. Table 43 lists system
hook functions for which no additional processing is required and the
capability permission that is used to control the same operation.
Of course, finer-grained permissions may be added to SELinux in the
future, e.g. a permission to control what files can be used for
accounting, so these hooks may be used at a later point in time.
The ctl_sid
structure is used to map a name
from the sysctl namespace to a SID. This structure resembles the
ctl_table
structure defined in sysctl.h, with entries for the sysctl
name (which is an integer), the associated string from the
/proc/sys namespace, and the
SID to be used for the entry. The last field is an
optional pointer to a table containing the children of the entry.
A hierarchy of these tables is statically defined in the SELinux
security module. Each level of the hierarchy is an array of
ctl_sid
entries. The layout corresponds to
the hierarchy of ctl_table
entries defined
dynamically by the kernel and mapped into the
/proc/sys file system. The hierarchy starts with
the ctl_sid_root_table, providing SIDs for the
top-level sysctl entries, and having several child tables. For
example, the entry for CTL_KERN
has a pointer to
a table (ctl_sid_kern_table
) for children of the
/proc/sys/kernel entries.
The search_ctl_sid
helper function is used by the
selinux_sysctl
hook function to search the
ctl_sid_root_table hierarchy for a SID
corresponding to a given sysctl entry. The criteria used is that the
ctl_name and procname must both match. Of course, this is only a
heuristic and may not guarantee uniqueness. This function is
recursive, and will return the SID corresponding to
the ctl_sid table, or the sysctl
initial SID if
no match is found.
This hook function checks permission for the current task to access
a sysctl entry. It calls the search_ctl_sid
helper function to obtain the SID associated with the sysctl entry.
It then performs a permission check based on the requested operation,
treating the sysctl entry as a directory for search operations and
as a file for read or write operations on a variable.
Table 44 shows the permission checks associated with
each requested operation.
The labeling of entries in /proc/sys by the
procfs_set_sid
function is described in Section 14.1.3.1. This function also uses the shadow sysctl table to
determine SIDs for the inodes used to represent
/proc/sys entries. These SIDs are then used in
the file permission checks performed by the inode and file hook
functions.
However, procfs_set_sid
has certain advantages
over selinux_sysctl
in determining the SID of the
sysctl entry. It can determine the parent inode of the entry, and it
can save a pointer to the appropriate table in the inode's security
structure. Hence, it only needs to search a single table, and can
reliably identify the entry. Additionally, it can implement
inheritance semantics so that the shadow table only needs to contain
entries where the SID changes. To some extent, this could also be
implemented in selinux_sysctl
using the
proc_dir_entry
in the
ctl_table
. However, this would only work if
procfs was enabled.
The selinux_quotactl
hook function checks that
the current task has permission to perform a given quota control
command on a filesystem. If no filesystem was specified (i.e. a
Q_SYNC
or Q_GETSTATS
command), then the hook simply returns success, since these operations
require no control. Otherwise, one of the
quotamod
or quotaget
permissions is checked between the current task and the filesystem,
depending on whether the command sets information or merely gets
information related to quotas.
The selinux_syslog
hook function checks that the
current task has permission to perform a given system logging command.
For operation 3
, the
syslog_read
system permission is checked. For
operations that control logging to the console, the
syslog_console
system permission is checked. All
other operations (including unknown ones) are checked with
syslog_mod
system permission.
The selinux_sys_security
hook function is called
by the generic security
system call, which is
used as a multiplexor for new system calls for security-aware
applications. However, since SELinux replaces the entrypoint function
for the generic security
system call, this hook
is unused by SELinux. See Section 9 for further
discussion.
Each of the remaining system hook functions performs a simple
permission check, as summarized in Table 45. The
selinux_ptrace
hook function also calls the
secondary module to permit it to perform additional capability
checking.