new helper: readlink_copy()
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 14 Mar 2014 17:42:45 +0000 (13:42 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 2 Apr 2014 03:19:15 +0000 (23:19 -0400)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c
fs/proc/namespaces.c
fs/proc/self.c
fs/xfs/xfs_ioctl.c
include/linux/fs.h

index 617de9e..4fb52f0 100644 (file)
@@ -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);
index 9ae46b8..8902609 100644 (file)
@@ -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 = {
index ffeb202..4348bb8 100644 (file)
@@ -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)
index bcfe612..0b18776 100644 (file)
@@ -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;
 
index d9d88a0..db181b5 100644 (file)
@@ -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 *);