Implementing SELinux as a Linux Security Module | ||
---|---|---|
<<< Previous | Next >>> |
This section discusses how the new SELinux system calls were implemented in the SELinux security module. The code for these calls can be found in the syscalls.c and include/asm-i386/flask/syscalls.c files. All of the new system calls are multiplexed through the security system call added by LSM. However, SELinux could not use the sys_security function and hook provided by LSM, because they do not provide access to the registers on the stack. This information is needed by the execve_secure system call.
Hence, the SELinux security module inserts its own sys_security_selinux function into the system call table during initialization in place of the LSM function. The SELinux function checks the module identifier to ensure that the application is invoking a SELinux system call and then calls the individual function for the requested call with the appropriate parameters. In the case of execve_secure, the entrypoint function also passes a pointer to the registers on the stack.
As mentioned in the Section called Internal Architecture, the implementation of the
extended system calls required a different approach than in the
original SELinux prototype. Since the existing internal kernel
functions could not be extended to pass SIDs, input and output SID
arrays were added to the security structure associated with tasks
(task_security_struct
in
selinux_plug.h). The extended system calls can
set the elements of the in_sid
array in this structure prior to
calling the ordinary system call to pass SIDs to the hook functions
called during the system call. Likewise, the hook functions can set
the elements of the out_sid
array in this structure to pass SIDs back
to the extended system calls for return to the application. Since a
separate Linux task structure is created even when the
clone call is used to create threads, these
elements should be safe against concurrent access.
The new IPC system calls for obtaining SIDs were not as
straightforward. The semsid,
shmsid, and msgsid calls
could not directly look up the corresponding kernel object due to the
encapsulation of the IPC code, so they had to invoke an actual IPC
operation to permit a hook to obtain the SID and pass it back via the
out_sid
array. The corresponding control operation
(e.g. SEMCTL
) is called with the
IPC_STAT
operation for this purpose, with a
temporary kernel buffer and the data segment set to the kernel segment
to deal with the normal copyout.
Similarly, the msgrcv_secure call was complicated
by the fact that the sys_msgrcv function is not exported
directly to modules and the generic ipc call
expects a userspace ipc_kludge
structure.
This was resolved by using version 1
of the
MSGRCV
IPC call value, thereby avoiding the need
to pass such a structure. In this case, it would not have worked to
simply provide a temporary kernel structure and set the data segment,
because the other parameters include userspace pointers.
The implementation of the extended socket system calls is still in progress, and several issues still remain to be resolved. These issues include passing a message SID and a destination socket SID for a particular outgoing message from the socket layer hooks to the network buffer hooks, and labeling the SYNACK packet with the correct SID when the useclient flag is set. These issues are discussed further in the Section called Extended Socket Call Processing.
The final issue in implementing the new system calls was implementing
the execve_secure call. As mentioned above, this
call requires access to the registers on the stack, so SELinux had to
provide its own entrypoint function for the
security system call. This call
parallels the processing of the existing kernel
sys_execve entrypoint function, copying in the
filename and calling the kernel do_execve
function. It only differs in that it sets an element of the in_sid
array to the specified SID for use by the program loading hook
functions.
<<< Previous | Home | Next >>> |
Stacking with Other Modules | Helper Functions for Hook Functions |