System Hook Functions

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.

Capability-Related System Hook Functions

selinux_capable

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.

selinux_capget

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.

selinux_capset_check

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.

selinux_capset_set

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.

selinux_netlink_send

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.

selinux_netlink_recv

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.

Summary of Capability-Related Permission Checks

Table 42. Capability-Related Permission Checks

Hook FunctionSourceTargetPermission
selinux_capableTaskTaskCapabilityPermission
selinux_capgetCurrentTargetTaskgetcap
selinux_capset_checkCurrentTargetTasksetcap
selinux_capset_setCurrentTargetTasksetcap
selinux_netlink_sendCurrentCurrentnet_admin

System Hook Functions that Defer to Capable

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.

Table 43. System Hook Functions that Defer to Capable

HookPermission Checked by Capable

selinux_sethostname
selinux_setdomainname
selinux_swapoff

sys_admin
selinux_rebootsys_boot

selinux_ioperm
selinux_iopl

sys_rawio
selinux_acctsys_pacct

System Hook Function for sysctl

Shadow Sysctl Table

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.

search_ctl_sid

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.

selinux_sysctl

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.

Table 44. sysctl Permission Checks

Operation ValueSourceTargetPermission
1CurrentEntrySearch
4CurrentEntryread
2CurrentEntrywrite

Comparison with /proc/sys

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.

System Hook Function for quotactl

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.

System Hook Function for syslog

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.

System Hook Function for New System Calls

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.

Remaining System Hook Functions

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.

Table 45. Remaining System Hook Function Permission Checks

Hook FunctionSourceTargetPermission
selinux_ptraceParentTaskChildTaskptrace
selinux_swaponCurrentSwapFileswapon
selinux_nfsservctlCurrentKernelnfsd_control
selinux_quotaonCurrentQuotaFilequotaon
selinux_bdflushCurrentKernelbdflush