Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e4543edd authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Linus Torvalds
Browse files

[PATCH] add a vfs_permission helper



Most permission() calls have a struct nameidata * available.  This helper
takes that as an argument and thus makes sure we pass it down for lookup
intents and prepares for per-mount read-only support where we need a struct
vfsmount for checking whether a file is writeable.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent e4a53cba
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ asmlinkage long sys_uselib(const char __user * library)
	if (!S_ISREG(nd.dentry->d_inode->i_mode))
		goto exit;

	error = permission(nd.dentry->d_inode, MAY_READ | MAY_EXEC, &nd);
	error = vfs_permission(&nd, MAY_READ | MAY_EXEC);
	if (error)
		goto exit;

@@ -495,7 +495,7 @@ struct file *open_exec(const char *name)
		file = ERR_PTR(-EACCES);
		if (!(nd.mnt->mnt_flags & MNT_NOEXEC) &&
		    S_ISREG(inode->i_mode)) {
			int err = permission(inode, MAY_EXEC, &nd);
			int err = vfs_permission(&nd, MAY_EXEC);
			if (!err && !(inode->i_mode & 0111))
				err = -EACCES;
			file = ERR_PTR(err);
+1 −1
Original line number Diff line number Diff line
@@ -372,7 +372,7 @@ static int find_inode(const char __user *dirname, struct nameidata *nd)
	if (error)
		return error;
	/* you can only watch an inode if you have read permissions on it */
	error = permission(nd->dentry->d_inode, MAY_READ, NULL);
	error = vfs_permission(nd, MAY_READ);
	if (error) 
		path_release(nd);
	return error;
+19 −4
Original line number Diff line number Diff line
@@ -256,6 +256,21 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
	return security_inode_permission(inode, mask, nd);
}

/**
 * vfs_permission  -  check for access rights to a given path
 * @nd:		lookup result that describes the path
 * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
 *
 * Used to check for read/write/execute permissions on a path.
 * We use "fsuid" for this, letting us set arbitrary permissions
 * for filesystem access without changing the "normal" uids which
 * are used for other things.
 */
int vfs_permission(struct nameidata *nd, int mask)
{
	return permission(nd->dentry->d_inode, mask, nd);
}

/*
 * get_write_access() gets write permission for a file.
 * put_write_access() releases this write permission.
@@ -765,9 +780,8 @@ static fastcall int __link_path_walk(const char * name, struct nameidata *nd)

		nd->flags |= LOOKUP_CONTINUE;
		err = exec_permission_lite(inode, nd);
		if (err == -EAGAIN) { 
			err = permission(inode, MAY_EXEC, nd);
		}
		if (err == -EAGAIN)
			err = vfs_permission(nd, MAY_EXEC);
 		if (err)
			break;

@@ -1407,7 +1421,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
	if (S_ISDIR(inode->i_mode) && (flag & FMODE_WRITE))
		return -EISDIR;

	error = permission(inode, acc_mode, nd);
	error = vfs_permission(nd, acc_mode);
	if (error)
		return error;

@@ -2536,6 +2550,7 @@ EXPORT_SYMBOL(path_lookup);
EXPORT_SYMBOL(path_release);
EXPORT_SYMBOL(path_walk);
EXPORT_SYMBOL(permission);
EXPORT_SYMBOL(vfs_permission);
EXPORT_SYMBOL(unlock_rename);
EXPORT_SYMBOL(vfs_create);
EXPORT_SYMBOL(vfs_follow_link);
+1 −1
Original line number Diff line number Diff line
@@ -637,7 +637,7 @@ static int mount_is_safe(struct nameidata *nd)
		if (current->uid != nd->dentry->d_inode->i_uid)
			return -EPERM;
	}
	if (permission(nd->dentry->d_inode, MAY_WRITE, nd))
	if (vfs_permission(nd, MAY_WRITE))
		return -EPERM;
	return 0;
#endif
+6 −6
Original line number Diff line number Diff line
@@ -240,7 +240,7 @@ static inline long do_sys_truncate(const char __user * path, loff_t length)
	if (!S_ISREG(inode->i_mode))
		goto dput_and_out;

	error = permission(inode,MAY_WRITE,&nd);
	error = vfs_permission(&nd, MAY_WRITE);
	if (error)
		goto dput_and_out;

@@ -394,7 +394,7 @@ asmlinkage long sys_utime(char __user * filename, struct utimbuf __user * times)
                        goto dput_and_out;

		if (current->fsuid != inode->i_uid &&
		    (error = permission(inode,MAY_WRITE,&nd)) != 0)
		    (error = vfs_permission(&nd, MAY_WRITE)) != 0)
			goto dput_and_out;
	}
	down(&inode->i_sem);
@@ -447,7 +447,7 @@ long do_utimes(char __user * filename, struct timeval * times)
                        goto dput_and_out;

		if (current->fsuid != inode->i_uid &&
		    (error = permission(inode,MAY_WRITE,&nd)) != 0)
		    (error = vfs_permission(&nd, MAY_WRITE)) != 0)
			goto dput_and_out;
	}
	down(&inode->i_sem);
@@ -506,7 +506,7 @@ asmlinkage long sys_access(const char __user * filename, int mode)

	res = __user_walk(filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
	if (!res) {
		res = permission(nd.dentry->d_inode, mode, &nd);
		res = vfs_permission(&nd, mode);
		/* SuS v2 requires we report a read only fs too */
		if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
		   && !special_file(nd.dentry->d_inode->i_mode))
@@ -530,7 +530,7 @@ asmlinkage long sys_chdir(const char __user * filename)
	if (error)
		goto out;

	error = permission(nd.dentry->d_inode,MAY_EXEC,&nd);
	error = vfs_permission(&nd, MAY_EXEC);
	if (error)
		goto dput_and_out;

@@ -581,7 +581,7 @@ asmlinkage long sys_chroot(const char __user * filename)
	if (error)
		goto out;

	error = permission(nd.dentry->d_inode,MAY_EXEC,&nd);
	error = vfs_permission(&nd, MAY_EXEC);
	if (error)
		goto dput_and_out;

Loading