The SELinux superblock hook function implementations manage the security fields of super_block structures and perform access control for filesystem operations. This section begins by describing the superblock hook functions for managing the security fields. It then discusses the superblock hook functions for performing access control.
The superblock_security_struct
structure
contains security information for superblock objects. This structure
is defined as follows:
struct superblock_security_struct { struct super_block *sb; struct list_head list; u32 sid; u32 def_sid; unsigned int behavior; unsigned char initialized; unsigned char proc; struct semaphore sem; struct list_head isec_head; spinlock_t isec_lock; }; |
Table 9. superblock_security_struct
Field | Description |
---|---|
sb | Back pointer to the associated superblock. |
list | Link into list of superblock security structures setup prior to initial policy load. |
sid | SID for the file system. |
def_sid | default SID for labeling |
behavior | Labeling behavior to apply to inodes. |
initialized | Flag indicating whether the security structure has been initialized. |
sem | Semaphore used to synchronize initialization. |
isec_head | List of inode security structures setup prior to superblock security initialization. |
isec_lock | Lock for list of inode security structures. |
The superblock_alloc_security
and
superblock_free_security
helper functions are
the primitive allocation functions for super_block security structures.
The selinux_sb_alloc_security
and
selinux_sb_free_security
hook functions
call these helper functions.
This helper function performs initialization for superblock security
structures. It is normally called by the
selinux_sb_kern_mount
hook function. However,
since this helper function cannot perform full initialization until
after the initial policy load, it is also called by the
selinux_complete_init
function to retroactively
complete initialization of superblocks setup prior to the initial
policy load.
The superblock_doinit
function begins by taking
the semaphore to synchronize with any other attempts to initialize the
superblock security data and then checks whether the superblock
security structure has already been marked initialized. If so, the
function returns after releasing the semaphore. Otherwise, it checks
whether the initial policy load has completed. If not, then the
function adds the superblock security structure to a global list for
deferred processing by selinux_complete_init
,
releases the semaphore and returns.
If the initial policy load has completed, then
superblock_doinit
calls the security server's
security_fs_use
interface to determine the
labeling behavior for the inodes associated with the superblock and to
obtain a SID for the superblock itself. It then calls the
try_context_mount
to handle any mount context
options, which can override the labeling behavior and superblock SID
returned by security_fs_use
. Context mount
support is discussed further in the Section called try_context_mount.
If the desired labeling behavior is to use extended attributes (xattr)
superblock_doinit
verifies that the filesystem
supports xattr and the security namespace, returning an error
otherwise. If the superblock is for the proc pseudo filesystem, the
function sets the proc flag in the superblock security structure for
special handling upon inode initialization. The function then marks
the superblock security structure as initialized.
Next, superblock_doinit
calls
inode_doinit_with_dentry
on the root inode to
initialize its security structure. The function likewise makes calls
to initialize the inode security structures for any inodes that were
setup prior to superblock security initialization (e.g. prior to
initial policy load or during get_sb by a filesystem that directly
populates itself). Finally, the function releases the semaphore
and returns.
The selinux_sb_copy_data
function is called to
allow mount option data to be copied prior to parsing by the
filesystem, so that the security module can extract security-specific
mount options cleanly, especially since the filesystem code may modify
the data while processing. The hook function also allows the
security-specific options to be stripped from the mount data so that
the filesystem code does not need to be aware of them at all. If the
filesystem type uses binary mount data, then this hook function simply
copies the binary data into the page for security data for later
processing. Otherwise, this hook function parses the mount option
string and extracts any mount context options for later use.
There are three kinds of mount context options: context,
fscontext, and defcontext.
The try_context_mount
function is called to
handle any context mount options extracted earlier by selinux_sb_copy_data
. If the filesystem type uses binary
mount data, then the function will extract context options if using a
version of the binary mount data that includes them. At present, only
NFS has support for such options, and it only supports one of the
context mount options (context=). For string mount data, the function
processes each context-related option, checking for invalid
combinations. The fscontext and defcontext options may be used
together as well as individually, but no other combination of options
is allowed. If any context option is specified, the function applies
several permission checks among the task SID, the original superblock
SID, and the SID for the provided context to verify that the use of
the option is authorized.
For the context or fscontext options, the superblock SID is set to the SID for the provided context. The context option further changes the labeling behavior to mountpoint labeling, which means that all inodes in the filesystem are treated as having the provided context as well, and the xattr API is not supported for the inodes in the filesystem even if the filesystem type itself supports xattrs. In contrast, the fscontext option only sets the superblock SID and leaves the labeling behavior unchanged. The defcontext option only sets the default SID (def_sid) for inodes in the filesystem, overriding the typical value of the file initial SID.
This hook function is called to setup the superblock security structure
and to check permissions for the mount of a particular superblock. It
calls superblock_doinit
to perform the initialization
and then calls superblock_has_perm
to check filesystem
mount permission to the superblock.
This helper function checks whether a task has a particular permission to a filesystem. It takes the task, the super_block, the requested permissions, and optionally audit data as parameters. This function simply calls the AVC with the appropriate parameters.
This hook function is called to check permission when obtaining
filesystem attributes. It checks getattr
permission between the current task and the filesystem.
This hook function is called to check permission when mounting
a filesystem prior to the actual reading of the superblock.
If the filesystem is being remounted (i.e. the
mount flags are being changed), then this function checks
remount
permission between the current
task and the filesystem. Otherwise, this function checks
mounton
permission between the current
task and the mountpoint directory.
This hook function is called to check permission when unmounting a
filesystem. This function checks unmount
permission between the current task and the filesystem.
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 permission checks for the super_block hooks are summarized in Table 10.
Table 10. Filesystem Permission Checks
Hook | Source | Target | Permission(s) | ||||||
---|---|---|---|---|---|---|---|---|---|
selinux_sb_statfs | Current | Filesystem | getattr | ||||||
selinux_mount |
|
|
| ||||||
selinux_sb_kern_mount | Current | Filesystem | mount | ||||||
selinux_umount | Current | Filesystem | unmount | ||||||
selinux_quotactl | Current | Filesystem |
|