mirror of
				https://github.com/torvalds/linux.git
				synced 2025-10-31 08:38:45 +02:00 
			
		
		
		
	fs: add __remove_file_privs() with flags parameter
This adds the function __remove_file_privs, which allows the caller to pass the kiocb flags parameter. No intended functional changes in this patch. Signed-off-by: Stefan Roesch <shr@fb.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Link: https://lore.kernel.org/r/20220623175157.1715274-9-shr@fb.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
		
							parent
							
								
									8017553980
								
							
						
					
					
						commit
						faf99b5635
					
				
					 1 changed files with 37 additions and 20 deletions
				
			
		
							
								
								
									
										57
									
								
								fs/inode.c
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								fs/inode.c
									
									
									
									
									
								
							|  | @ -2010,36 +2010,43 @@ static int __remove_privs(struct user_namespace *mnt_userns, | |||
| 	return notify_change(mnt_userns, dentry, &newattrs, NULL); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Remove special file priviledges (suid, capabilities) when file is written | ||||
|  * to or truncated. | ||||
|  */ | ||||
| int file_remove_privs(struct file *file) | ||||
| static int __file_remove_privs(struct file *file, unsigned int flags) | ||||
| { | ||||
| 	struct dentry *dentry = file_dentry(file); | ||||
| 	struct inode *inode = file_inode(file); | ||||
| 	int error; | ||||
| 	int kill; | ||||
| 	int error = 0; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Fast path for nothing security related. | ||||
| 	 * As well for non-regular files, e.g. blkdev inodes. | ||||
| 	 * For example, blkdev_write_iter() might get here | ||||
| 	 * trying to remove privs which it is not allowed to. | ||||
| 	 */ | ||||
| 	if (IS_NOSEC(inode) || !S_ISREG(inode->i_mode)) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	kill = dentry_needs_remove_privs(dentry); | ||||
| 	if (kill < 0) | ||||
| 	if (kill <= 0) | ||||
| 		return kill; | ||||
| 	if (kill) | ||||
| 		error = __remove_privs(file_mnt_user_ns(file), dentry, kill); | ||||
| 
 | ||||
| 	if (flags & IOCB_NOWAIT) | ||||
| 		return -EAGAIN; | ||||
| 
 | ||||
| 	error = __remove_privs(file_mnt_user_ns(file), dentry, kill); | ||||
| 	if (!error) | ||||
| 		inode_has_no_xattr(inode); | ||||
| 
 | ||||
| 	return error; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * file_remove_privs - remove special file privileges (suid, capabilities) | ||||
|  * @file: file to remove privileges from | ||||
|  * | ||||
|  * When file is modified by a write or truncation ensure that special | ||||
|  * file privileges are removed. | ||||
|  * | ||||
|  * Return: 0 on success, negative errno on failure. | ||||
|  */ | ||||
| int file_remove_privs(struct file *file) | ||||
| { | ||||
| 	return __file_remove_privs(file, 0); | ||||
| } | ||||
| EXPORT_SYMBOL(file_remove_privs); | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -2090,18 +2097,28 @@ int file_update_time(struct file *file) | |||
| } | ||||
| EXPORT_SYMBOL(file_update_time); | ||||
| 
 | ||||
| /* Caller must hold the file's inode lock */ | ||||
| /**
 | ||||
|  * file_modified - handle mandated vfs changes when modifying a file | ||||
|  * @file: file that was modified | ||||
|  * | ||||
|  * When file has been modified ensure that special | ||||
|  * file privileges are removed and time settings are updated. | ||||
|  * | ||||
|  * Context: Caller must hold the file's inode lock. | ||||
|  * | ||||
|  * Return: 0 on success, negative errno on failure. | ||||
|  */ | ||||
| int file_modified(struct file *file) | ||||
| { | ||||
| 	int err; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Clear the security bits if the process is not being run by root. | ||||
| 	 * This keeps people from modifying setuid and setgid binaries. | ||||
| 	 */ | ||||
| 	err = file_remove_privs(file); | ||||
| 	if (err) | ||||
| 		return err; | ||||
| 	ret = __file_remove_privs(file, 0); | ||||
| 	if (ret) | ||||
| 		return ret; | ||||
| 
 | ||||
| 	if (unlikely(file->f_mode & FMODE_NOCMTIME)) | ||||
| 		return 0; | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Stefan Roesch
						Stefan Roesch