The Linux kernel currently provides support for a subset of POSIX.1e capabilities. One of the requirements for the LSM project was to move this functionality to an optional security module, as mentioned in Section 2. POSIX.1e capabilities provides a mechanism for partitioning traditional superuser privileges and assigning them to particular processes.
By nature, privilege granting is a permissive form of access control, since it grants an access that would ordinarily be denied. Consequently, the LSM framework had to provide a permissive interface with at least the same granularity of the Linux capabilities implementation. LSM retains the existing capable interface used within the kernel for performing capability checks, but reduces the capable function to a simple wrapper for a LSM hook, allowing any desired logic to be implemented in the security module. This approach allowed LSM to leverage the numerous (more than 500) existing kernel calls to capable and to avoid pervasive changes to the kernel. LSM also defines hooks to allow the logic for other forms of capability checking and capability computations to be encapsulated within the security module.
A process capability set, a simple bit vector, is stored in the task_struct structure. Because LSM adds an opaque security field to the task_struct and hooks to manage the field, it would be possible to move the existing bit vector into the field. Such a change would be logical under the LSM framework but this change has not been implemented in order to ease stacking with other modules. One of the difficulties of stacking security modules in the LSM framework is the need to share the opaque security fields. Many security modules will want to stack with the capabilities module, because the capabilities logic has been integrated into the mainstream kernel for some time and is relied upon by some applications such as named and sendmail. Leaving the capability bit vector in the task_struct eases this composition at the cost of wasted space for modules that don't need to use it.
The Linux kernel support for capabilities also includes two system call calls: capset and capget. To remain compatible with existing applications, these system calls are retained by LSM but the core capabilities logic for these functions has been replaced by calls to LSM hooks. Ultimately, these calls should be reimplemented via the security system call. This change should have little impact on applications since the portable interface for capabilities is through the libcap library rather than direct use of these calls.
The LSM project has developed a capabilities security module and migrated much of the core capabilities logic into it; however, the kernel still shows vestiges of the pre-existing Linux capabilities. Moving the bit vector from the task_struct proper to the opaque security field and relocating the system call interface are the only major steps left to making the capability module completely standalone.