For file operations, three sets of hooks were defined: filesystem hooks, inode hooks, and file hooks. LSM adds a security field to each of the associated kernel data structures: super_block, inode, and file. The filesystem hooks enable security modules to control operations such as mounting and statfs. LSM leverages the existing permission function by inserting an inode hook into it, but LSM also defines a number of other inode hooks to provide finer-grained control over individual inode operations. Some of the file hooks allow security modules to perform additional checking on file operations such as read and write, for example, to revalidate permissions on use to support privilege bracketing or dynamic policy changes. A hook is also provided to allow security modules to control receipt of open file descriptors via socket IPC. Other file hooks provide finer-grained control over operations such as fcntl and ioctl.
An alternative to placing security fields in the inode and super_block structures would have been to place them in the dentry and vfsmount structures. The inode and super_block structures correspond to the actual objects and are independent of names and namespaces. The dentry and vfsmount structures contain a reference to the corresponding inode or super_block, and are associated with a particular name or namespace. Using the first pair of structures avoids object aliasing issues. The use of these structures also provides more coverage of kernel objects, since these structures also represent non-file objects such as pipes and sockets. These data structures are also readily available at any point in the filesystem code, whereas the second set of structures is often unavailable.