The kernel's inode structure represents a basic filesystem object, e.g., a file, directory, or symlink. The LSM inode hooks mediate access to this fundamental kernel structure. A well defined set of operations, inode_operations, describe the actions that can be taken on an inode -- create(), unlink(), lookup(), mknod(), rename(), and so on. This encapsulation defines a nice interface for LSM to mediate access to the inode object. In addition, LSM adds a security field to the inode structure and corresponding inode hooks to manage security labelling.
The kernel's inode cache is populated by either file lookup operations or filesystem object-creation operations. When a new inode is created, the security module allocates space for the inode security field with the alloc_security() inode hook. Either post-lookup or post-creation, the newly created objects are labelled. The label may be cleared by the delete() inode hook when an inode's link count reaches zero. And finally, when an inode is destroyed, the free_security() inode hook is called to release the space allocated for the security field.
In many cases, the LSM inode hooks are identical to the inode_operations. For all inode_operations that can create new filesystem objects a ``post'' inode hook is defined for coherent security labelling. For example, when a task creates a new symlink, the symlink() inode hook is called to check permission to create the symlink. Then if the symlink creation is successful, the post_symlink() hook is called to set the security label on the newly created symlink.
Whenever possible, LSM leverages the existing Linux kernel security infrastructure. The kernel's standard UNIX DAC checks compare the uids, guids, and mode bits when checking for permission to access filesystem objects. The VFS layer already has a permission() function which is a wrapper for the permission() inode_operation. LSM uses this pre-existing infrastructure and adds its permission() inode hook to the VFS wrapper.