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 { unsigned long magic; struct super_block *sb; struct list_head list; security_id_t sid; struct psidtab *psidtab; unsigned char uses_psids; unsigned char initialized; unsigned long initializing; unsigned char uses_task; struct semaphore sem; };
Table 7. superblock_security_struct
Field | Description |
---|---|
magic | Module id for the SELinux module. |
sb | Back pointer to the associated superblock. |
list | Pointer used to maintain the list of allocated superblock security structures. |
sid | SID for the file system. |
uses_psids | Flag indicating whether or not the file system uses persistent SIDs. |
initialized | Flag indicating whether the security structure has been initialized. |
initializing | Flag indicating whether the security structure is in the process of being initialized. |
uses_task | Flag indicating whether inodes in this filesystem should inherit the SID of the creating task (e.g. pipes, sockets). |
sem | Semaphore used to synchronize filesystem relabels. |
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 is
the precondition function for super_block security structures. This
function ensures that the super_block security structure is allocated
and initialized prior to use. If the filesystem can use the
persistent label mapping, then the psid_init
function is called to initialize the mapping and to set the SID of the
super_block. This is used for regular persistent filesystem types
like ext2 and reiserfs. If the filesystem is a pseudo filesystem for
private objects such as pipes or sockets, then a flag is set to
indicate that inodes associated with the filesystem should inherit the
SID of the creating process. If the filesystem is a pseudo filesystem
like procfs, devpts, tmpfs, or devfs, then an appropriate initial SID
is assigned to the super_block.
This hook function is called after the root filesystem has been
mounted. If the security server has not yet been initialized, this
function calls the security_init
function to
initialize the security server and load the initial policy
configuration. A failure at this point is fatal unless the
development module option is enabled, in which case SELinux will defer
initialization and processing until a subsequent policy load or AVC
toggle. If the security server has already been initialized (i.e. the
hook has been called twice due to a change_root
for an initrd), then this hook function tries to reload the policy
from the new root filesystem. If the reload fails due to either a
lack of permission for the current process or a lack of a policy on
the new root filesystem, then SELinux will continue operating under
the old (initrd) policy. The hook function then calls the
superblock_precondition
function on the root
filesystem to initialize its persistent label mapping.
This hook function is called after a successful pivot of the root
filesystem via the pivot_root
system call,
typically when an initrd is used. This hook function tries to reload
the policy from the new root filesystem. If the reload fails due to
either a lack of permission for the current process or a lack of a
policy on the new root filesystem, then SELinux will continue
operating under the old (initrd) policy.
This hook function is called after a non-root filesystem has been
mounted. It calls superblock_precondition
to
initialize the persistent label mapping of the filesystem. However,
this is obsoleted by the newer selinux_check_sb
hook
and will be reduced to doing nothing in the future.
This hook function is called after a successful remount of a
filesystem (i.e. after the mount flags have been changed). If the
filesystem uses the persistent label mapping, then this hook calls the
psid_remount
function to update the mapping at
this time if the filesystem was previously mounted read-only and is
now mounted read-write.
This hook function is called when a filesystem is being unmounted
prior to checking whether the filesystem is busy. If the filesystem
uses the persistent label mapping, then this hook calls the
psid_release
to free any memory and release any
files used for the mapping.
This hook function is called when the kernel determines that a
filesystem cannot be unmounted (e.g. the filesystem is busy) after
calling the umount_close
hook. If the filesystem
uses the persistent label mapping, then this hook function calls
psid_init
to reinitialize the mapping.
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. It also saves
the SID of the filesystem in an element of the
out_sid
array in the task security
structure for use by the statfs_secure
system calls.
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 mounting a
filesystem after reading the superblock. This function checks
mount
permission between the current task
and the filesystem. Prior to checking permission,
superblock_precondition
is called, so the
persistent label mapping for the filesystem will be initialized
by this hook.
This hook function is called to check permission when unmounting a
filesystem. This function checks unmount
permission between the current task and the filesystem.
This (recently added) hook function is called to check permission when
pivoting the root filesystem. Since the
pivot_root
system call also invokes the
capable
function with the
CAP_SYS_ADMIN
capability, the SELinux module
already requires that the current process have permission to use this
capability. This hook enables security modules to impose
finer-grained restrictions on the use of the operation,
e.g. distinguishing the operation from other operations that use the
same capability and basing decisions on the security attributes of the
new root filesystem. The SELinux module does not yet take
advantage of this ability, but a finer-grained permission check
is planned for the future.
The permission checks for the super_block hooks are summarized in Table 8.