forked from mirrors/linux
		
	fs: add open_tree_attr()
Add open_tree_attr() which allow to atomically create a detached mount tree and set mount options on it. If OPEN_TREE_CLONE is used this will allow the creation of a detached mount with a new set of mount options without it ever being exposed to userspace without that set of mount options applied. Link: https://lore.kernel.org/r/20250128-work-mnt_idmap-update-v2-v1-3-c25feb0d2eb3@kernel.org Reviewed-by: "Seth Forshee (DigitalOcean)" <sforshee@kernel.org> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
		
							parent
							
								
									474f7825d5
								
							
						
					
					
						commit
						c4a16820d9
					
				
					 20 changed files with 63 additions and 1 deletions
				
			
		|  | @ -506,3 +506,4 @@ | ||||||
| 574	common	getxattrat			sys_getxattrat | 574	common	getxattrat			sys_getxattrat | ||||||
| 575	common	listxattrat			sys_listxattrat | 575	common	listxattrat			sys_listxattrat | ||||||
| 576	common	removexattrat			sys_removexattrat | 576	common	removexattrat			sys_removexattrat | ||||||
|  | 577	common	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -481,3 +481,4 @@ | ||||||
| 464	common	getxattrat			sys_getxattrat | 464	common	getxattrat			sys_getxattrat | ||||||
| 465	common	listxattrat			sys_listxattrat | 465	common	listxattrat			sys_listxattrat | ||||||
| 466	common	removexattrat			sys_removexattrat | 466	common	removexattrat			sys_removexattrat | ||||||
|  | 467	common	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -478,3 +478,4 @@ | ||||||
| 464	common	getxattrat			sys_getxattrat | 464	common	getxattrat			sys_getxattrat | ||||||
| 465	common	listxattrat			sys_listxattrat | 465	common	listxattrat			sys_listxattrat | ||||||
| 466	common	removexattrat			sys_removexattrat | 466	common	removexattrat			sys_removexattrat | ||||||
|  | 467	common	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -466,3 +466,4 @@ | ||||||
| 464	common	getxattrat			sys_getxattrat | 464	common	getxattrat			sys_getxattrat | ||||||
| 465	common	listxattrat			sys_listxattrat | 465	common	listxattrat			sys_listxattrat | ||||||
| 466	common	removexattrat			sys_removexattrat | 466	common	removexattrat			sys_removexattrat | ||||||
|  | 467	common	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -472,3 +472,4 @@ | ||||||
| 464	common	getxattrat			sys_getxattrat | 464	common	getxattrat			sys_getxattrat | ||||||
| 465	common	listxattrat			sys_listxattrat | 465	common	listxattrat			sys_listxattrat | ||||||
| 466	common	removexattrat			sys_removexattrat | 466	common	removexattrat			sys_removexattrat | ||||||
|  | 467	common	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -405,3 +405,4 @@ | ||||||
| 464	n32	getxattrat			sys_getxattrat | 464	n32	getxattrat			sys_getxattrat | ||||||
| 465	n32	listxattrat			sys_listxattrat | 465	n32	listxattrat			sys_listxattrat | ||||||
| 466	n32	removexattrat			sys_removexattrat | 466	n32	removexattrat			sys_removexattrat | ||||||
|  | 467	n32	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -381,3 +381,4 @@ | ||||||
| 464	n64	getxattrat			sys_getxattrat | 464	n64	getxattrat			sys_getxattrat | ||||||
| 465	n64	listxattrat			sys_listxattrat | 465	n64	listxattrat			sys_listxattrat | ||||||
| 466	n64	removexattrat			sys_removexattrat | 466	n64	removexattrat			sys_removexattrat | ||||||
|  | 467	n64	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -454,3 +454,4 @@ | ||||||
| 464	o32	getxattrat			sys_getxattrat | 464	o32	getxattrat			sys_getxattrat | ||||||
| 465	o32	listxattrat			sys_listxattrat | 465	o32	listxattrat			sys_listxattrat | ||||||
| 466	o32	removexattrat			sys_removexattrat | 466	o32	removexattrat			sys_removexattrat | ||||||
|  | 467	o32	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -465,3 +465,4 @@ | ||||||
| 464	common	getxattrat			sys_getxattrat | 464	common	getxattrat			sys_getxattrat | ||||||
| 465	common	listxattrat			sys_listxattrat | 465	common	listxattrat			sys_listxattrat | ||||||
| 466	common	removexattrat			sys_removexattrat | 466	common	removexattrat			sys_removexattrat | ||||||
|  | 467	common	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -557,3 +557,4 @@ | ||||||
| 464	common	getxattrat			sys_getxattrat | 464	common	getxattrat			sys_getxattrat | ||||||
| 465	common	listxattrat			sys_listxattrat | 465	common	listxattrat			sys_listxattrat | ||||||
| 466	common	removexattrat			sys_removexattrat | 466	common	removexattrat			sys_removexattrat | ||||||
|  | 467	common	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -469,3 +469,4 @@ | ||||||
| 464  common	getxattrat		sys_getxattrat			sys_getxattrat | 464  common	getxattrat		sys_getxattrat			sys_getxattrat | ||||||
| 465  common	listxattrat		sys_listxattrat			sys_listxattrat | 465  common	listxattrat		sys_listxattrat			sys_listxattrat | ||||||
| 466  common	removexattrat		sys_removexattrat		sys_removexattrat | 466  common	removexattrat		sys_removexattrat		sys_removexattrat | ||||||
|  | 467  common	open_tree_attr		sys_open_tree_attr		sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -470,3 +470,4 @@ | ||||||
| 464	common	getxattrat			sys_getxattrat | 464	common	getxattrat			sys_getxattrat | ||||||
| 465	common	listxattrat			sys_listxattrat | 465	common	listxattrat			sys_listxattrat | ||||||
| 466	common	removexattrat			sys_removexattrat | 466	common	removexattrat			sys_removexattrat | ||||||
|  | 467	common	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -512,3 +512,4 @@ | ||||||
| 464	common	getxattrat			sys_getxattrat | 464	common	getxattrat			sys_getxattrat | ||||||
| 465	common	listxattrat			sys_listxattrat | 465	common	listxattrat			sys_listxattrat | ||||||
| 466	common	removexattrat			sys_removexattrat | 466	common	removexattrat			sys_removexattrat | ||||||
|  | 467	common	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -472,3 +472,4 @@ | ||||||
| 464	i386	getxattrat		sys_getxattrat | 464	i386	getxattrat		sys_getxattrat | ||||||
| 465	i386	listxattrat		sys_listxattrat | 465	i386	listxattrat		sys_listxattrat | ||||||
| 466	i386	removexattrat		sys_removexattrat | 466	i386	removexattrat		sys_removexattrat | ||||||
|  | 467	i386	open_tree_attr		sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -390,6 +390,7 @@ | ||||||
| 464	common	getxattrat		sys_getxattrat | 464	common	getxattrat		sys_getxattrat | ||||||
| 465	common	listxattrat		sys_listxattrat | 465	common	listxattrat		sys_listxattrat | ||||||
| 466	common	removexattrat		sys_removexattrat | 466	common	removexattrat		sys_removexattrat | ||||||
|  | 467	common	open_tree_attr		sys_open_tree_attr | ||||||
| 
 | 
 | ||||||
| # | # | ||||||
| # Due to a historical design error, certain syscalls are numbered differently | # Due to a historical design error, certain syscalls are numbered differently | ||||||
|  |  | ||||||
|  | @ -437,3 +437,4 @@ | ||||||
| 464	common	getxattrat			sys_getxattrat | 464	common	getxattrat			sys_getxattrat | ||||||
| 465	common	listxattrat			sys_listxattrat | 465	common	listxattrat			sys_listxattrat | ||||||
| 466	common	removexattrat			sys_removexattrat | 466	common	removexattrat			sys_removexattrat | ||||||
|  | 467	common	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
|  | @ -4995,6 +4995,45 @@ SYSCALL_DEFINE5(mount_setattr, int, dfd, const char __user *, path, | ||||||
| 	return err; | 	return err; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | SYSCALL_DEFINE5(open_tree_attr, int, dfd, const char __user *, filename, | ||||||
|  | 		unsigned, flags, struct mount_attr __user *, uattr, | ||||||
|  | 		size_t, usize) | ||||||
|  | { | ||||||
|  | 	struct file __free(fput) *file = NULL; | ||||||
|  | 	int fd; | ||||||
|  | 
 | ||||||
|  | 	if (!uattr && usize) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	file = vfs_open_tree(dfd, filename, flags); | ||||||
|  | 	if (IS_ERR(file)) | ||||||
|  | 		return PTR_ERR(file); | ||||||
|  | 
 | ||||||
|  | 	if (uattr) { | ||||||
|  | 		int ret; | ||||||
|  | 		struct mount_kattr kattr = { | ||||||
|  | 			.recurse = !!(flags & AT_RECURSIVE), | ||||||
|  | 		}; | ||||||
|  | 
 | ||||||
|  | 		ret = copy_mount_setattr(uattr, usize, &kattr); | ||||||
|  | 		if (ret) | ||||||
|  | 			return ret; | ||||||
|  | 
 | ||||||
|  | 		ret = do_mount_setattr(&file->f_path, &kattr); | ||||||
|  | 		if (ret) | ||||||
|  | 			return ret; | ||||||
|  | 
 | ||||||
|  | 		finish_mount_kattr(&kattr); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	fd = get_unused_fd_flags(flags & O_CLOEXEC); | ||||||
|  | 	if (fd < 0) | ||||||
|  | 		return fd; | ||||||
|  | 
 | ||||||
|  | 	fd_install(fd, no_free_ptr(file)); | ||||||
|  | 	return fd; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| int show_path(struct seq_file *m, struct dentry *root) | int show_path(struct seq_file *m, struct dentry *root) | ||||||
| { | { | ||||||
| 	if (root->d_sb->s_op->show_path) | 	if (root->d_sb->s_op->show_path) | ||||||
|  |  | ||||||
|  | @ -951,6 +951,10 @@ asmlinkage long sys_statx(int dfd, const char __user *path, unsigned flags, | ||||||
| asmlinkage long sys_rseq(struct rseq __user *rseq, uint32_t rseq_len, | asmlinkage long sys_rseq(struct rseq __user *rseq, uint32_t rseq_len, | ||||||
| 			 int flags, uint32_t sig); | 			 int flags, uint32_t sig); | ||||||
| asmlinkage long sys_open_tree(int dfd, const char __user *path, unsigned flags); | asmlinkage long sys_open_tree(int dfd, const char __user *path, unsigned flags); | ||||||
|  | asmlinkage long sys_open_tree_attr(int dfd, const char __user *path, | ||||||
|  | 				   unsigned flags, | ||||||
|  | 				   struct mount_attr __user *uattr, | ||||||
|  | 				   size_t usize); | ||||||
| asmlinkage long sys_move_mount(int from_dfd, const char __user *from_path, | asmlinkage long sys_move_mount(int from_dfd, const char __user *from_path, | ||||||
| 			       int to_dfd, const char __user *to_path, | 			       int to_dfd, const char __user *to_path, | ||||||
| 			       unsigned int ms_flags); | 			       unsigned int ms_flags); | ||||||
|  |  | ||||||
|  | @ -849,9 +849,11 @@ __SYSCALL(__NR_getxattrat, sys_getxattrat) | ||||||
| __SYSCALL(__NR_listxattrat, sys_listxattrat) | __SYSCALL(__NR_listxattrat, sys_listxattrat) | ||||||
| #define __NR_removexattrat 466 | #define __NR_removexattrat 466 | ||||||
| __SYSCALL(__NR_removexattrat, sys_removexattrat) | __SYSCALL(__NR_removexattrat, sys_removexattrat) | ||||||
|  | #define __NR_open_tree_attr 467 | ||||||
|  | __SYSCALL(__NR_open_tree_attr, sys_open_tree_attr) | ||||||
| 
 | 
 | ||||||
| #undef __NR_syscalls | #undef __NR_syscalls | ||||||
| #define __NR_syscalls 467 | #define __NR_syscalls 468 | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  * 32 bit systems traditionally used different |  * 32 bit systems traditionally used different | ||||||
|  |  | ||||||
|  | @ -407,3 +407,4 @@ | ||||||
| 464	common	getxattrat			sys_getxattrat | 464	common	getxattrat			sys_getxattrat | ||||||
| 465	common	listxattrat			sys_listxattrat | 465	common	listxattrat			sys_listxattrat | ||||||
| 466	common	removexattrat			sys_removexattrat | 466	common	removexattrat			sys_removexattrat | ||||||
|  | 467	common	open_tree_attr			sys_open_tree_attr | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Christian Brauner
						Christian Brauner