Re: Documentation for inode security hooks

From: Stephen Smalley (sdsat_private)
Date: Tue Sep 18 2001 - 10:04:41 PDT

  • Next message: Stephen Smalley: "Re: Documentation for inode security hooks"

    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