Implementing SELinux as a Linux Security Module | ||
---|---|---|
<<< Previous | Next >>> |
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.
<<< Previous | Home | Next >>> |
Program Loading Hook Functions | Inode Hook Functions |