Implementing SELinux as a Linux Security Module | ||
---|---|---|
<<< Previous | Next >>> |
The SELinux file hook functions manage the security fields of
file
structures and perform access control
for file operations. Each file
structure
contains state such as the file offset and file flags for an open
file. Since file descriptors may be inherited across
execve calls and may be transferred through IPC,
they can potentially be shared among processes with different security
attributes, so it is desirable to separately label these structures
and control the use of them. Additionally, it is necessary to save
task security information in these structures for SIGIO
signals.
The file_security_struct
structure contains
security information for file objects. This structure is defined as
follows:
struct file_security_struct { unsigned long magic; struct file *file; struct list_head list; security_id_t sid; security_id_t fown_sid; avc_entry_ref_t avcr; avc_entry_ref_t inode_avcr; }; |
Table 20. file_security_struct
Field | Description |
---|---|
magic | Module id for the SELinux module. |
file | Back pointer to the associated file .
|
list | Pointer used to maintain the list of allocated file security structures. |
sid | SID of the open file descriptor. |
fown_sid | SID of the file owner; used for SIGIO
events.
|
avcr | AVC entry reference for the file. |
inode_avcr | AVC entry reference for the associated inode. |
The file_alloc_security and file_free_security helper functions are the primitive allocation functions for file security structures. In addition to the general security field management, file_alloc_security tries to associate the file with the SID of the current task. If the security structure of the current task is not already set, the file is associated with the unlabeled SID. Callers of this function should first call task_precondition on the current task if possible. The file_free_security simply releases all resources.
The selinux_file_alloc_security calls the task_precondition function to ensure that the SID of the current task is set and then calls the helper function. The selinux_file_free_security hook functions merely calls the helper function.
The file_precondition helper function ensures that the file security structure is allocated and initialized prior to use. This function calls task_precondition on the current task and then calls file_alloc_security.
This hook function is called to save security information about the
current task in the file security structure for later use by the
selinux_file_send_sigiotask hook. One example of
where this hook is called is the fcntl call for
the F_SETOWN
command. This hook saves the SID of
the current task in the fown_sid
field of
the file security structure.
This helper function checks whether a task can use an open file descriptor to
access a file in a given way. It takes the task, the file, and the
requested file permissions as parameters. This function first calls
the AVC to check use
permission between the task
and the file descriptor. If this permission is granted, then this
function also checks the requested permissions to the file using the
dentry_has_perm helper function. In some cases
(e.g. lseek), this helper function is called with no requested file
permissions in order to simply check the ability to use the
descriptor. In these cases, the latter check is omitted.
This hook function is called by operations such as
read, write, and
sendfile to revalidate permissions on use to
support privilege bracketing or policy changes. It takes the file and
permission mask as parameters. If the O_APPEND
flag is set in the file flags, then this hook function first sets the
MAY_APPEND
flag in permission mask. This
function then converts the permission mask to an access vector using
the file_mask_to_av function, and calls
file_has_perm with the appropriate parameters.
This hook function is called by the lseek and llseek system calls to control access to the file offset. It calls file_has_perm with no requested file permissions to simply check access to the file descriptor.
This hook function is called by the ioctl system
call. It calls file_has_perm with a requested
file permission based on the command argument. For some commands, no
file permission is specified so only the use
permission is checked. The generic ioctl
file permission is used for commands that are not specifically handled.
Table 21 shows the permission checks performed for each
command.
Table 21. I/O Control Permission Checks
Command | Source | Target | Permission(s) | |||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
| Current |
|
| |||||||||
| Current |
|
| |||||||||
| Current | FileDescriptor | use | |||||||||
Other | Current |
|
|
This hook function is called by mmap to check
permission when mapping a file. At present, if anonymous memory is
being mapped, i.e. the file parameter is NULL
, no checks are
performed. However, this may be changed later to ensure that execute
access to anonymous memory can be controlled. If a file is being
mapped, then file_has_perm is called with a
set of permissions based on the flags and protection parameters.
Since read access is always possible with file mapping, the
read
permission is always required. The
write
permission is only checked if the mapping
is shared and PROT_WRITE
was requested. The
execute
permission is only checked if
PROT_EXEC
was requested. However, on some
architectures, read access to memory is sufficient to execute code
from it, so the ability to strictly control code execution is
limited on such architectures.
It should be noted that the protection on a mapping may subsequently become invalid due to a file relabel or a change in the security policy. Hence, support for efficiently locating and invalidating the appropriate mappings upon such changes is needed to support full revocation. This support has not yet been implemented for the SELinux security module.
This hook function is called by the mprotect call to check the requested new protection for an existing mapping. This hook simply calls selinux_file_mmap with the file, new protection value, and the existing flags for the mapping.
This hook function is called by the flock system
call. It calls file_has_perm with the
lock
permission.
This hook function is called by the fcntl system call. It calls file_has_perm with a requested file permission based on the command parameter. The basic permission checks performed for each command are shown in Table 22.
Table 22. File Control Permission Checks
Command | Source | Target | Permission(s) | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Current | FileDescriptor | use | ||||||||||
| Current |
|
|
In addition to these basic checks, the write
permission is checked if the F_SETFL
command is
used to clear the O_APPEND
flag. This ensures
that a process that only has append
permission to
the file cannot subsequently obtain full write access after opening
the file.
This hook function is called to check whether a signal generated by an
event on a file descriptor can be sent to a task. This function is
always called from interrupt. It is passed the target task, a file
owner structure and several other parameters that are unused by
SELinux. Since the file owner structure is embedded in a file
structure, the file structure and its security field can be extracted
by the hook function. The hook function calls the AVC to check the
appropriate signal permission between the
fown_sid
in the file security structure and
the target task SID.
This hook function is called to check whether the current task can receive an open file descriptor that was sent via socket IPC. This function calls the file_to_av function to convert the file flags and mode to an access vector and then calls file_has_perm to check that the receiving task has these permissions to the file. If this hook returns an error, then the kernel will cease processing the message and will pass a truncated message to the receiving task.
<<< Previous | Home | Next >>> |
Inode Hook Functions | System V IPC Hook Functions |