forked from mirrors/linux
		
	fs: Call d_automount with the filesystems creds
Seth Forshee reported a mount regression in nfs autmounts
with "fs: Add user namespace member to struct super_block".
It turns out that the assumption that current->cred is something
reasonable during mount while necessary to improve support of
unprivileged mounts is wrong in the automount path.
To fix the existing filesystems override current->cred with the
init_cred before calling d_automount and restore current->cred after
d_automount completes.
To support unprivileged mounts would require a more nuanced cred
selection, so fail on unprivileged mounts for the time being.  As none
of the filesystems that currently set FS_USERNS_MOUNT implement
d_automount this check is only good for preventing future problems.
Fixes: 6e4eab577a ("fs: Add user namespace member to struct super_block")
Tested-by: Seth Forshee <seth.forshee@canonical.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
			
			
This commit is contained in:
		
							parent
							
								
									8175435777
								
							
						
					
					
						commit
						aeaa4a79ff
					
				
					 1 changed files with 7 additions and 0 deletions
				
			
		|  | @ -36,6 +36,7 @@ | |||
| #include <linux/posix_acl.h> | ||||
| #include <linux/hash.h> | ||||
| #include <linux/bitops.h> | ||||
| #include <linux/init_task.h> | ||||
| #include <asm/uaccess.h> | ||||
| 
 | ||||
| #include "internal.h" | ||||
|  | @ -1099,6 +1100,7 @@ static int follow_automount(struct path *path, struct nameidata *nd, | |||
| 			    bool *need_mntput) | ||||
| { | ||||
| 	struct vfsmount *mnt; | ||||
| 	const struct cred *old_cred; | ||||
| 	int err; | ||||
| 
 | ||||
| 	if (!path->dentry->d_op || !path->dentry->d_op->d_automount) | ||||
|  | @ -1120,11 +1122,16 @@ static int follow_automount(struct path *path, struct nameidata *nd, | |||
| 	    path->dentry->d_inode) | ||||
| 		return -EISDIR; | ||||
| 
 | ||||
| 	if (path->dentry->d_sb->s_user_ns != &init_user_ns) | ||||
| 		return -EACCES; | ||||
| 
 | ||||
| 	nd->total_link_count++; | ||||
| 	if (nd->total_link_count >= 40) | ||||
| 		return -ELOOP; | ||||
| 
 | ||||
| 	old_cred = override_creds(&init_cred); | ||||
| 	mnt = path->dentry->d_op->d_automount(path); | ||||
| 	revert_creds(old_cred); | ||||
| 	if (IS_ERR(mnt)) { | ||||
| 		/*
 | ||||
| 		 * The filesystem is allowed to return -EISDIR here to indicate | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Eric W. Biederman
						Eric W. Biederman