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

Commit 5d826c84 authored by Al Viro's avatar Al Viro
Browse files

new helper: readlink_copy()



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 4efcc9ff
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -4297,11 +4297,9 @@ SYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newna
	return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname);
}

int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link)
int readlink_copy(char __user *buffer, int buflen, const char *link)
{
	int len;

	len = PTR_ERR(link);
	int len = PTR_ERR(link);
	if (IS_ERR(link))
		goto out;

@@ -4313,7 +4311,7 @@ int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const c
out:
	return len;
}
EXPORT_SYMBOL(vfs_readlink);
EXPORT_SYMBOL(readlink_copy);

/*
 * A helper for ->readlink().  This should be used *ONLY* for symlinks that
@@ -4331,7 +4329,7 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen)
	if (IS_ERR(cookie))
		return PTR_ERR(cookie);

	res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
	res = readlink_copy(buffer, buflen, nd_get_link(&nd));
	if (dentry->d_inode->i_op->put_link)
		dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
	return res;
@@ -4356,8 +4354,7 @@ static char *page_getlink(struct dentry * dentry, struct page **ppage)
int page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
{
	struct page *page = NULL;
	char *s = page_getlink(dentry, &page);
	int res = vfs_readlink(dentry,buffer,buflen,s);
	int res = readlink_copy(buffer, buflen, page_getlink(dentry, &page));
	if (page) {
		kunmap(page);
		page_cache_release(page);
+4 −10
Original line number Diff line number Diff line
@@ -146,7 +146,7 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl
	struct task_struct *task;
	void *ns;
	char name[50];
	int len = -EACCES;
	int res = -EACCES;

	task = get_proc_task(inode);
	if (!task)
@@ -155,24 +155,18 @@ static int proc_ns_readlink(struct dentry *dentry, char __user *buffer, int bufl
	if (!ptrace_may_access(task, PTRACE_MODE_READ))
		goto out_put_task;

	len = -ENOENT;
	res = -ENOENT;
	ns = ns_ops->get(task);
	if (!ns)
		goto out_put_task;

	snprintf(name, sizeof(name), "%s:[%u]", ns_ops->name, ns_ops->inum(ns));
	len = strlen(name);

	if (len > buflen)
		len = buflen;
	if (copy_to_user(buffer, name, len))
		len = -EFAULT;

	res = readlink_copy(buffer, buflen, name);
	ns_ops->put(ns);
out_put_task:
	put_task_struct(task);
out:
	return len;
	return res;
}

static const struct inode_operations proc_ns_link_inode_operations = {
+1 −1
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@ static int proc_self_readlink(struct dentry *dentry, char __user *buffer,
	if (!tgid)
		return -ENOENT;
	sprintf(tmp, "%d", tgid);
	return vfs_readlink(dentry,buffer,buflen,tmp);
	return readlink_copy(buffer, buflen, tmp);
}

static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)
+1 −27
Original line number Diff line number Diff line
@@ -271,32 +271,6 @@ xfs_open_by_handle(
	return error;
}

/*
 * This is a copy from fs/namei.c:vfs_readlink(), except for removing it's
 * unused first argument.
 */
STATIC int
do_readlink(
	char __user		*buffer,
	int			buflen,
	const char		*link)
{
        int len;

	len = PTR_ERR(link);
	if (IS_ERR(link))
		goto out;

	len = strlen(link);
	if (len > (unsigned) buflen)
		len = buflen;
	if (copy_to_user(buffer, link, len))
		len = -EFAULT;
 out:
	return len;
}


int
xfs_readlink_by_handle(
	struct file		*parfilp,
@@ -334,7 +308,7 @@ xfs_readlink_by_handle(
	error = -xfs_readlink(XFS_I(dentry->d_inode), link);
	if (error)
		goto out_kfree;
	error = do_readlink(hreq->ohandle, olen, link);
	error = readlink_copy(hreq->ohandle, olen, link);
	if (error)
		goto out_kfree;

+1 −1
Original line number Diff line number Diff line
@@ -2517,7 +2517,7 @@ extern const struct file_operations generic_ro_fops;

#define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m))

extern int vfs_readlink(struct dentry *, char __user *, int, const char *);
extern int readlink_copy(char __user *, int, const char *);
extern int page_readlink(struct dentry *, char __user *, int);
extern void *page_follow_link_light(struct dentry *, struct nameidata *);
extern void page_put_link(struct dentry *, struct nameidata *, void *);