Implementing SELinux as a Linux Security Module | ||
---|---|---|
<<< Previous | Next >>> |
The SELinux task hook function implementations manage the security
fields of task_struct
structures and perform
access control for task operations. This section
describes these hooks and their helper functions.
The task_security_struct
structure contains
security information for tasks. This structure is defined as follows:
struct task_security_struct { unsigned long magic; struct task_struct *task; struct list_head list; security_id_t osid; security_id_t sid; security_id_t in_sid[2]; security_id_t out_sid[2]; avc_entry_ref_t avcr; }; |
Table 1. task_security_struct
Field | Description |
---|---|
magic | Module id for the SELinux module. |
task | Back pointer to the associated
task_struct structure.
|
list | Pointer used to maintain the list of allocated task security structures. |
osid | SID prior to the last execve. |
sid | SID for the task. |
in_sid[2] | Input SIDs used by SELinux system calls. |
out_sid[2] | Output SIDs returned by SELinux system calls. |
avcr | AVC entry reference. |
The task_alloc_security and task_free_security helper functions are the primitive allocation functions for task security structures. The selinux_task_alloc_security hook function calls task_alloc_security for the new task and then copies the SID fields from the current task into the new task. The selinux_task_free_security hook function simply calls the corresponding helper function.
This helper function is the precondition function for task security structures. This function ensures that the task security structure is allocated and initialized prior to use. If the task security structure is not already allocated, then the task was created prior to the loading of the SELinux module. In this case, this helper function attempts to retroactively determine the SID for the task.
If the task has no parent task, then this function assigns the
kernel
initial SID to the task. Otherwise, the
security structure of the parent task is obtained and used to provide
default values for the child task's security structure. The security
structure for the inode that represents the task's executable is then
obtained, and the SID of the task is computed based on the SID of the
parent task and the SID of the inode using the
security_transition_sid interface.
This parallels the computation that would occur normally if the parent task had forked the child and then the child had executed the program while running SELinux. However, there are several possible reasons why this computation might yield a different SID than the SID that would have been used if the SELinux module had been running when the child task was created. For example, the original parent task may have died or undergone a change in SID since creating the child. Additionally, if SELinux had been running at an earlier point, then the child task or one of its ancestors might have used one of the new system calls to explicitly set the SID, e.g. to set the user identity and role upon login.
This hook function is called by the kernel
exec_usermodehelper function to set the security
attributes for the kernel task running user-mode helper programs,
such as modprobe.
This is used for operations such as automatic kernel module loading
and hotplug support. This hook function first calls the secondary
security module to support Linux capabilities. It then sets the SID
of the task to the kmod
initial SID.
This hook function is called after a setuid operation has successfully completed. Since the SELinux module does not use the Linux identity attributes, this hook function does not perform any SELinux processing. However, it does call the secondary security module to support Linux capabilities.
Several helper functions are provided for performing task permission
checks. These functions and their permission checks are summarized in
Table 2. The task_has_perm function
checks whether a task has a particular permission to another task.
The task_has_capability function checks whether a
task has permission to use a particular Linux capability. The
task_has_system function checks whether a task
has one of the permissions in the system
security
class. This security class is used for permissions that control
system operations when there is no existing capability check or the
capability check is too coarse-grained. The
task_has_security function checks whether a task
has permission to use one of the security server system calls.
Table 2. Task Helper Function Permission Checks
Function | Source | Target | Permission(s) |
---|---|---|---|
task_has_perm | SourceTask | TargetTask | ProcessPermission |
task_has_capability | Task | Task | CapabilityPermission |
task_has_system | Task | Kernel | SystemPermission |
task_has_security | Task | Security | SecurityPermission |
Except for task_has_perm, these permission checks are simply based on a single task, so the target SID is unnecessary. In the case of task_has_capability, the task's SID is passed for both the source and target SIDs. For task_has_system and task_has_security, a distinct initial SID is used for the target SID.
The task hook functions that perform access control and their permission checks are summarized in Table 3. These functions call the task_has_perm helper function.
Table 3. Task Hook Function Permission Checks
Hook | Source | Target | Permission(s) | ||||
---|---|---|---|---|---|---|---|
selinux_task_create | Current | Current | fork | ||||
selinux_task_setpgid | Current | TargetTask | setpgid | ||||
selinux_task_getpgid | Current | TargetTask | getpgid | ||||
selinux_task_getsid | Current | TargetTask | getsession | ||||
selinux_task_getscheduler | Current | TargetTask | getsched | ||||
| Current | TargetTask | setsched | ||||
selinux_task_kill | Current | TargetTask |
| ||||
selinux_task_wait | ChildTask | Current |
|
Only two of these hook functions require further explanation. The
selinux_task_kill hook function checks a
permission between the current task and the target task based on the
signal being sent. The selinux_task_wait checks
a permission between the child task and the current task based on the
exit signal set for the child task. This allows control over the
ability of a process to reap a child process of a different SID. In
both hooks, the SIGKILL
and
SIGSTOP
signals have their own distinct
permissions because neither of these two signals can be blocked. The
SIGCHLD
signal has its own distinct permission
because it is commonly sent from child processes to parent processes.
For all other signals, the generic signal
permission is used.
Several of the task hook functions for controlling operations are not used by the SELinux security module. These hook functions are:
selinux_task_setuid
selinux_task_setgid
selinux_task_setgroups
selinux_task_setrlimit
selinux_task_prctl
<<< Previous | Home | Next >>> |
Helper Functions for Hook Functions | Program Loading Hook Functions |