Implementing SELinux as a Linux Security Module | ||
---|---|---|
<<< Previous | Next >>> |
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 the Section called Procfs File Labeling. 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 the Section called New System Calls 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.
<<< Previous | Home | Next >>> |
Module Hook Functions | References |