System V IPC Hook Functions

The SELinux System V Inter-Process Communication (IPC) hook functions manage the security fields and perform access control for System V semaphores, shared memory segments, and message queues. This section describes these hooks and their helper functions.

Managing System V IPC Security Fields

IPC Security Structure

The ipc_security_struct structure contains security information for IPC objects. This structure is defined as follows:

struct ipc_security_struct {
        unsigned long magic;
        struct kern_ipc_perm *ipc_perm;
        security_class_t sclass;
        struct list_head list;
        security_id_t sid;
        avc_entry_ref_t avcr;
};

Table 23. ipc_security_struct

FieldDescription
magicModule id for the SELinux module.
ipc_perm Back pointer to the associated kern_ipc_perm.
sclassSecurity class for the IPC object (see the Section called ipc_alloc_security and ipc_free_security).
list Pointer used to maintain the list of allocated IPC security structures.
sidSID for the IPC object.
avcrAVC entry reference.

Likewise, the msg_security_struct structure contains security information for IPC message objects. This structure is defined as follows:

struct msg_security_struct {
        unsigned long magic;
        struct msg_msg *msg;
        struct list_head list;
        security_id_t sid;
        avc_entry_ref_t avcr;
};

Table 24. msg_security_struct

FieldDescription
magicModule id for the SELinux module.
msg Back pointer to the associated IPC message;
list Pointer used to maintain the list of allocated IPC message security structures.
sidSID for the IPC message.
avcrAVC entry reference.

ipc_alloc_security and ipc_free_security

The ipc_alloc_security and ipc_free_security helper functions are the primitive allocation functions for the security structures for semaphores, shared memory segments, and message queues. The kernel data structures for these objects share a common substructure, kern_ipc_perm, and the security field is located in this shared substructure; a single set of helper functions can be used for all three object types. If a SID was specified using one of the new IPC system calls, then the specified SID is used for the IPC object. Otherwise, the IPC object inherits its SID from the creating task. The security class for the IPC object is passed by the caller; it will be one of SECCLASS_MSGQ, SECCLASS_SEM, or SECCLASS_SHM.

The ipc_alloc_security function is called by the following allocation hook functions:

  • selinux_sem_alloc_security

  • selinux_shm_alloc_security

  • selinux_msg_queue_alloc_security

Each of these hook functions calls task_precondition on the current task prior to calling ipc_alloc_security to ensure that task security structure will be available. This is not handled within the primitive allocation function itself, as with the other primitive allocation functions, to ensure that no cycles arise, although this would not currently be a problem for IPC objects. These hook functions then check the create permission between the current task and the IPC object. Hence, these hook functions have the unusual property of being used both for allocation and a permission check. Using two separate hooks for this purpose would be cleaner but inefficient, since they would both be called at the same point.

The ipc_free_security function is called by the following deallocation hook functions:

  • selinux_sem_free_security

  • selinux_shm_free_security

  • selinux_msg_queue_free_security

These deallocation hook functions do not perform any other processing.

msg_msg_alloc_security and msg_msg_free_security

The msg_msg_alloc_security and msg_msg_free_security helper functions are the primitive allocation functions for the security structures for individual messages on a message queue. These helper functions provide all of the processing for the selinux_msg_msg_alloc_security and selinux_msg_msg_free_security hook functions. These helper functions simply provide the standard processing for primitive allocation functions, and initialize the message SID to the unlabeled SID.

ipc_precondition

This helper function is the precondition function for IPC security structures. This function ensures that the IPC security structure is allocated and initialized prior to use. If the security structure is not already allocated, then this function first calls task_precondition on the current task and then calls ipc_alloc_security. Since it cannot determine the appropriate security class automatically, the security class is passed by the caller.

msg_precondition

This helper function is the precondition function for individual message security structures. This function ensures that the message security structure is allocated and initialized prior to use. If the security structure is not already allocated, then this function simply calls msg_msg_alloc_security.

ipc_savesid

This helper function saves the SID of an IPC object in the out_sid array of the current task's security structure for use by the new system calls. This helper function first calls the appropriate precondition functions to ensure that the necessary security structures are available. This function is called by the IPC control hooks when the command is IPC_STAT.

Controlling General IPC Operations

This section describes the helper and hook functions for controlling general IPC operations. Although the allocation functions do perform a create permission check, they are not listed here since they were discussed in the previous section.

ipc_has_perm

This helper function calls the appropriate precondition functions and then calls the AVC to check whether the current task has a particular permission to an IPC object. The security class of the IPC object is passed by the caller in case the IPC object's security structure has not yet been allocated.

selinux_ipc_permission

This hook function is called from the kernel ipcperms function, so it is called prior to all IPC operations that will read or modify the IPC object. This hook function checks unix_read and/or unix_write permission to the IPC object based on the flag, as shown in Table 25. These permissions provide a coarse-grained equivalent to the Unix permissions, whereas the other IPC hooks check finer-grained permissions. These coarse-grained permission checks are not strictly necessary, but ensure that all IPC accesses are mediated by the policy.

Table 25. ipc_permission Permission Checks

FlagPermission
S_IRUGOunix_read
S_IWUGOunix_write

selinux_ipc_getinfo

When a task attempts to use a *_INFO command in a *ctl call on an IPC object, the kernel calls this hook function. This hook function checks the ipc_info system permission for the current task.

selinux_*_associate

When a task attempts to obtain an IPC object identifier for an existing object via one of the *get calls, the kernel calls the corresponding associate hook function for the object type. The SELinux IPC associate hook functions are:

  • selinux_sem_associate

  • selinux_shm_associate

  • selinux_msg_queue_associate

These hook functions check associate permission between the current task and the IPC object. If one of the new *get_secure system calls was used to specify a desired SID for the IPC object, then these hook functions also verify that the SID matches the desired SID.

Controlling Semaphore Operations

selinux_semctl

This hook function checks permissions before performing an operation on the specified semaphore; the specific permission is determined by the operation being performed. The permissions required for each operation are shown in Table 26.

Table 26. Semaphore Control Permissions

OperationSourceTargetPermission

GETPID
GETNCNT
GETZCNT

CurrentSemgetattr

GETVAL
GETALL

CurrentSemread

SETVAL
SETALL

CurrentSemwrite
IPC_RMIDCurrentSemdestroy
IPC_SETCurrentSemsetattr

IPC_STAT
SEM_STAT

CurrentSemgetattr, associate

selinux_semop

This hook function checks permissions for semaphore operations. It always checks read permission between the current task and the semaphore. If the semaphore value is being altered, it also checks write permission between the current task and the semaphore. Notice that these permissions are different from the unix_read and unix_write permissions checked by selinux_ipc_permission.

Controlling Shared Memory Operations

selinux_shm_shmctl

This hook function checks permissions before performing an operation on the specified shared memory region; the specific permission is determined by the operation being performed. The permissions required for each operation are shown in Table 27.

Table 27. Shared Memory Control Permissions

OperationSourceTargetPermission

IPC_STAT
SHM_STAT

CurrentShmgetattr, associate
IPC_SETCurrentShmsetattr

SHM_LOCK
SHM_UNLOCK

CurrentShmlock
IPC_RMIDCurrentShmdestroy

selinux_shm_shmat

This hook function checks permissions for shared memory attach operations. It always check read permission between the current task and the shared memory object. If the SHM_RDONLY flag was not specified, then it also checks write permission between the current task and the shared memory object. Notice that these permissions are different from the unix_read and unix_write permissions checked by selinux_ipc_permission.

Controlling Message Queue Operations

selinux_msg_queue_msgctl

This hook function checks permissions before performing an operation on the specified message queue; the specific permission is determined by the operation being performed. The permissions required for each operation are shown in Table 28.

Table 28. Message Queue Control Permissions

OperationSourceTargetPermission

IPC_STAT
MSG_STAT

CurrentMessageQueuegetattr, associate
IPC_SETCurrentMessageQueuesetattr
IPC_RMIDCurrentMessageQueuedestroy

selinux_msg_queue_msgsnd

This hook function is called by the msgsnd system call to check the ability to place an individual message on a message queue. It performs three permission checks, involving the current task, the message queue, and the individual message. These checks are shown in Table 29. This hook function also sets the SID on the message if it is unlabeled. It uses the SID from the in_sid array of the task security structure if the new msgsnd_secure system call was used. Otherwise, it calls the security_transition_sid interface of the security server to obtain a SID based on the SID of the task and the SID of the message queue.

Table 29. Message Send Permissions

SourceTargetPermission
CurrentMessageQueuewrite
CurrentMessagesend
MessageMessageQueueenqueue

selinux_msg_queue_msgrcv

This hook function can be called by either the msgsnd system call (for a pipelined send) or by the msgrcv system call to check the ability to receive an individual message from a message queue. Hence, the receiving task may not be the current task and is explicitly passed to the hook. This hook function performs two permission checks, involving the receiving task, the message queue, and the individual message. These permission checks are shown in Table 30. In the case that the new msgrcv_secure system call is being used to specify a desired message SID, then this hook also checks the actual message SID against the desired message SID. This hook function also saves the SID of the message for use by the new system call. It is important to note that an error return from this hook simply causes the individual message to be ignored in the same manner as if it had the wrong message type. Hence, access denials on individual messages are not propagated to the calling process and may cause the calling process to block waiting for messages that are accessible.

Table 30. Message Receive Permissions

SourceTargetPermission
ReceiverTaskMessageQueueread
ReceiverTaskMessagereceive