On Tue, 18 Sep 2001, Chris Wright wrote: > I agree that our fundamental need is to differentiate the use of > the file_security_ops and inode_security_ops permission functions. I > didn't think listing all uses would be useful, just confusing. In > general the inode_ops check is an inode attribute check, whereas > the file_ops is the check against the way the file was opened. Perhaps > something as succinct as that would suffice. For SELinux (and I thought SubDomain), the file_security_ops permission hook is used to revalidate permission to the file upon the actual read/write operation since it may have been revoked (or in the case of SubDomain, it may not be valid at present because of a change_hat). I've applied your earlier patch and then tried rewording the descriptions of the two permission hooks to clarify the issue better. What do you think of the new attached patch? -- Stephen D. Smalley, NAI Labs ssmalleyat_private --- lsm-wirex/include/linux/security.h Tue Sep 18 08:28:12 2001 +++ lsm/include/linux/security.h Tue Sep 18 13:00:32 2001 @@ -261,7 +261,7 @@ /** * post_addmount - Update module state when a non-root filesystem is mounted * @mnt: the mounted filesystem - * @nd: the nameidata structure for the mount point + * @mountpoint_nd: the nameidata structure for the mount point * * called: do_add_mount <fs/super.c> * @@ -274,39 +274,389 @@ *mountpoint_nd); }; +/** + * Security hooks for inode operations. + */ struct inode_security_ops { - int (* alloc_security) (struct inode *inode); /* create per inode security stuff */ - void (* free_security) (struct inode *inode); /* free it */ + /** + * alloc_security - allocate security structure for this inode + * @inode: the inode structure + * + * called: alloc_inode <fs/inode.c> + * + * Allocate and attach a security structure to @inode->i_security. + * The i_security field is initialized to NULL when the inode + * structure is allocated. Return 0 if operation was successful. + */ + int (* alloc_security) (struct inode *inode); + + /** + * free_security - deallocate security structure for this inode + * @inode: the inode structure + * + * called: destroy_inode <fs/inode.c> + * + * Deallocate the inode security structure and set @inode->i_security + * to NULL. + */ + void (* free_security) (struct inode *inode); - int (* create) (struct inode *dir, struct dentry *dentry, int mode); - void (* post_create) (struct inode *dir, struct dentry *dentry, int mode); - int (* link) (struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry); - void (* post_link) (struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry); - int (* unlink) (struct inode *dir, struct dentry *dentry); - int (* symlink) (struct inode *dir, struct dentry *dentry, const char *old_name); - void (* post_symlink) (struct inode *dir, struct dentry *dentry, const char *old_name); - int (* mkdir) (struct inode *dir, struct dentry *dentry, int mode); - void (* post_mkdir) (struct inode *dir, struct dentry *dentry, int mode); - int (* rmdir) (struct inode *dir, struct dentry *dentry); - int (* mknod) (struct inode *dir, struct dentry *dentry, int mode, dev_t dev); - void (* post_mknod) (struct inode *dir, struct dentry *dentry, int mode, dev_t dev); - int (* rename) (struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry); - void (* post_rename) (struct inode *old_dir, struct dentry *old_dentry, - struct inode *new_dir, struct dentry *new_dentry); - int (* readlink) (struct dentry *dentry); - int (* follow_link) (struct dentry *dentry, struct nameidata *nd); - int (* permission) (struct inode *inode, int mask); - int (* revalidate) (struct dentry *dentry); - int (* setattr) (struct dentry *dentry, struct iattr *attr); - int (* stat) (struct inode *inode); - void (* post_lookup) (struct inode *ino, struct dentry *d); - void (* delete) (struct inode *ino); + /** + * create - check the permissions when creating a directory or file + * @dir: inode structure of the parent of the new file + * @dentry: the dentry structure for the file to be created + * @mode: the file mode of the file to be created + * + * called: vfs_create <fs/namei.c> + * + * lock: The @dir i_sem semaphore is held. + * lock: The @dir i_zombie semaphore is held. + * + * Check permission to create a regular file. + * Return 0 if permission is granted. + */ + int (* create) (struct inode *dir, struct dentry *dentry, int mode); + + /** + * post_create - set the security attributes on a newly created file + * @dir: inode structure of the parent directory of the new file + * @dentry: the dentry structure for the newly created file + * @mode: the file mode + * + * called: vfs_create <fs/namei.c> + * + * lock: The @dir i_sem semaphore is held. + * + * Set the security attributes on a newly created regular file. + * This hook is called after a file has been successfully created. + */ + void (* post_create) (struct inode *dir, struct dentry *dentry, + int mode); + + /** + * link - check permissions when creating a hard link to a file + * @old_dentry: dentry structure for an existing link to the file + * @dir: the inode structure of the parent directory of the new link + * @new_dentry: dentry structure for the new link + * + * called: vfs_link <fs/namei.c> + * + * lock: The @dir i_sem semaphore is held. + * lock: The @dir i_zombie semaphore is held. + * + * Check permission before creating a new hard link to a file. + * Return 0 if permission is granted. + */ + int (* link) (struct dentry *old_dentry, struct inode *dir, + struct dentry *new_dentry); + + /** + * post_link - set security attributes for a new file link + * @old_dentry: dentry structure for the existing link + * @dir: the inode structure of the parent directory of the new file + * @new_dentry: dentry structure for the new file link + * + * called: vfs_link <fs/namei.c> + * + * lock: The @dir i_sem semaphore is held. + * + * Set security attributes for a new hard link to a file. + */ + void (* post_link) (struct dentry *old_dentry, struct inode *dir, + struct dentry *new_dentry); + + /** + * unlink - check permissions when unlinking a file + * @dir: inode structure of parent directory of the file + * @dentry: dentry structure for file to be unlinked + * + * called: vfs_unlink <fs/namei.c> + * + * lock: The @dir i_sem semaphore is held. + * lock: The @dir i_zombie semaphore is held. + * + * Check the permission to remove a hard link to a file. + * Return 0 if permission is granted. + */ + int (* unlink) (struct inode *dir, struct dentry *dentry); + + /** + * symlink - check permissions when creating a symbolic link to a file + * @dir: inode structure of parent directory of the symbolic link + * @dentry: dentry structure of the symbolic link + * @old_name: pathname of file + * + * called: vfs_symlink <fs/namei.c> + * + * lock: The @dir i_sem semaphore is held. + * lock: The @dir i_zombie semaphore is held. + * + * Check the permission to create a symbolic link to a file. + * Return 0 if permission is granted. + */ + int (* symlink) (struct inode *dir, struct dentry *dentry, + const char *old_name); + + /** + * post_symlink - set security attributes on a new symbolic link + * @dir: inode structure of the parent directory of the new link + * @dentry: dentry structure of new symbolic link + * @old_name: pathname of file + * + * called: vfs_symlink <fs/namei.c> + * + * lock: The @dir i_sem semaphore is held. + * + * Set security attributes for a newly created symbolic link. + * Note that @dentry->d_inode may be NULL, since the filesystem + * might not instantiate the dentry (e.g. NFS). + */ + void (* post_symlink) (struct inode *dir, struct dentry *dentry, + const char *old_name); + + /** + * mkdir - check permissions when creating a directory + * @dir: inode structure of parent of the directory to be created + * @dentry: dentry structure of new directory + * @mode: mode of new directory + * + * called: vfs_mkdir <fs/namei.c> + * + * lock: The @dir i_sem semaphore is held. + * lock: The @dir i_zombie semaphore is held. + * + * Check permissions to create a new directory in the existing + * directory associated with inode strcture @dir. + * Return 0 if permission is granted. + */ + int (* mkdir) (struct inode *dir, struct dentry *dentry, int mode); + + /** + * post_mkdir - set security attributes on new directory + * @dir: inode structure of parent of the directory to be created + * @dentry: dentry structure of new directory + * @mode: mode of new directory + * + * called: vfs_mkdir <fs/namei.c> + * + * lock: The @dir i_sem semaphore is held. + * + * Set security attributes on a newly created directory. + */ + void (* post_mkdir) (struct inode *dir, struct dentry *dentry, + int mode); + + /** + * rmdir - check permissions when removing a directory + * @dir: inode structure of parent of the directory to be removed + * @dentry: dentry structure of directory to be removed + * + * called: vfs_rmdir <fs/namei.c> + * + * lock: The @dir i_sem semaphore is held. + * lock: The @dir i_zombie semaphore is held. + * lock: The @dentry->d_inode i_zombie semaphore is held. + * + * Check the permission to remove a directory. + * Return 0 if permission is granted. + */ + int (* rmdir) (struct inode *dir, struct dentry *dentry); + + /** + * mknod - check permissions when creating a special file + * @dir: inode structure of parent of the new file + * @dentry: dentry structure of the new file + * @mode: mode of the new file + * @dev: the device number + * + * called: vfs_mknod <fs/namei.c> + * + * lock: The @dir i_sem semaphore is held. + * lock: The @dir i_zombie semaphore is held. + * + * Check permissions when creating a special file (or a + * socket or a fifo file created via the mknod system call). + * Note that if mknod operation is being done for a regular file, + * then the create hook will be called and not this hook. + * Return 0 if permission is granted. + */ + int (* mknod) (struct inode *dir, struct dentry *dentry, int mode, + dev_t dev); + + /** + * post_mknod - set security attributes on a special file + * @dir: inode structure of parent of the new node + * @dentry: dentry structure of the new node + * @mode: mode of the new node + * @dev: the device number + * + * called: vfs_mknod <fs/namei.c> + * + * lock: The @dir i_sem semaphore is held. + * + * Set security attributes on a newly created special file + * (or socket or fifo file created via the mknod system call). + */ + void (* post_mknod) (struct inode *dir, struct dentry *dentry, + int mode, dev_t dev); + + /** + * rename - check permissions to rename a file or directory + * @old_dir: inode structure for parent of the old link + * @old_dentry: dentry structure of the old link + * @new_dir: inode structure for parent of the new link + * @new_dentry: dentry structure of the new link + * + * called: vfs_rename_dir <fs/namei.c> + * called: vfs_rename_other <fs/namei.c> + * + * lock: The @old_dir->d_inode i_sem lock is held by do_rename. + * lock: The @new_dir_d_inode i_sem lock is held by do_rename. + * lock: The big kernel lock is held by do_rename <fs/namei.c> + * + * Check for permission to rename a file or directory. + * Return 0 if permission is granted. + */ + int (* rename) (struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry); + + /** + * post_rename - set security attributes on newly renamed file or directory + * @old_dir: inode structure for parent of the old link + * @old_dentry: dentry structure of the old link + * @new_dir: inode structure for parent of the new link + * @new_dentry: dentry structure of the new link + * + * called: vfs_rename_dir <fs/namei.c> + * called: vfs_rename_other <fs/namei.c> + * + * lock: The big kernel lock is held by do_rename <fs/namei.c> + * lock: The @old_dir->i_sb->s_vfs_rename_sem semaphore is held. + * + * Set security attributes on a renamed file or directory. + */ + void (* post_rename) (struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry); + + /** + * readlink - check permissions when reading a symbolic link + * @dentry: dentry structure for the file link + * + * called: sys_readlink <fs/stat.c> + * + * Check the permission to read the symbolic link. + * Return 0 if permission is granted. + */ + int (* readlink) (struct dentry *dentry); + + /** + * follow_link - check permission to follow symbolic links + * @dentry: dentry structure for the link + * @nd: nameidata structure for the parent directory + * + * called: do_follow_link <fs/namei.c> + * called: open_namei <fs/namei.c> + * + * Check permission to follow a symbolic link when looking up + * a pathname. Return 0 if permission is granted. + */ + int (* follow_link) (struct dentry *dentry, struct nameidata *nd); + + /** + * permission - check permission when accessing an inode + * @inode: inode structure to check + * @mask: permission mask + * + * called: permission <fs/namei.c> + * + * Check permission before accessing an inode. This hook + * is called by the existing Linux permission function, + * so a security module can use it to provide additional + * checking for existing Linux permission checks. Notice + * that this hook is called when a file is opened (as well + * as many other operations), whereas the file_security_ops + * permission hook is called when the actual read/write + * operations are performed. + * Return 0 if permission is granted. + */ + int (* permission) (struct inode *inode, int mask); + + /** + * revalidate - revalidate the inode attributes + * @dentry: dentry structure associated with the inode + * + * called: do_revalidate <fs/stat.c> + * + * Revalidate the inode attributes. This hook can be used + * by a security module to revalidate the attributes stored in + * the i_security field to maintain consistency when the file + * is remote. Return 0 if successful. + */ + int (* revalidate) (struct dentry *dentry); + + /** + * setattr - check permissions to set file attributes + * @dentry: dentry structure for the file + * @attr: iattr structure containing the new file attributes + * + * called: notify_change <fs/attr.c> + * + * lock: The big kernel lock is held by notify_change + * + * Check permission before setting file attributes. + * Note that the kernel call to notify_change is performed from several + * locations, whenever file attributes change (such as when a file + * is truncated, chown/chmod operations, transferring disk quotas, + * etc). Return 0 if permission is granted. + */ + int (* setattr) (struct dentry *dentry, struct iattr *attr); + + /** + * stat - check permissions to get file attributes + * @inode: inode structure for the file + * + * called: cp_old_stat <fs/stat.c> + * called: cp_new_stat <fs/stat.c> + * called: cp_new_stat64 <fs/stat.c> + * + * Check permission before obtaining file attributes. + * Return 0 if permission is granted. + */ + int (* stat) (struct inode *inode); + + /** + * post_lookup - set security attributes for looked up file + * @ino: inode structure for parent directory + * @d: dentry structure for the file + * + * called: real_lookup <fs/namei.c> + * called: lookup_hash <fs/namei.c> + * + * lock: The @ino i_sem semaphore MAY be held. + * + * Set the security attributes for a file after it has + * been looked up. + */ + void (* post_lookup) (struct inode *ino, struct dentry *d); + + /** + * delete - update module's state when an inode is deleted + * @ino: inode structure for deleted inode + * + * called: iput <fs/inode.c> + * + * This hook is called when a deleted inode is released + * (i.e. an inode with no hard links has its use count drop to + * zero). A security module can use this hook to release any + * persistent label associated with the inode. + */ + void (* delete) (struct inode *ino); + }; struct file_security_ops { /** - * permission - check permission when accessing a file + * permission - check permission when accessing an open file * @file: file structure being accessed * @mask: requested permissions * @@ -320,10 +670,15 @@ * called: sys_sendfile <mm/filemap.c> * called: sys_sendfile <mm/filemap.c> * - * Check file permissions before accessing a file. - * This hook is called to check permission for the actual - * read/write operations, whereas the inode_security_ops - * permission hook is called when the file is opened. + * Check file permissions before accessing an open file. + * This hook is called by various operations that read + * or write files. A security module can use this hook + * to perform additional checking on these operations, e.g. + * to revalidate permissions on use to support privilege + * bracketing or policy changes. Notice that this hook + * is used when the actual read/write operations are + * performed, whereas the inode_security_ops hook is called + * when a file is opened (as well as many other operations). * Return 0 if permission is granted. */ int (*permission) (struct file * file, int mask); _______________________________________________ linux-security-module mailing list linux-security-moduleat_private http://mail.wirex.com/mailman/listinfo/linux-security-module
This archive was generated by hypermail 2b30 : Tue Sep 18 2001 - 10:08:12 PDT