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 |