Whamcloud - gitweb
LU-6667 llite: improve ll_getname 89/15089/11
authorOleg Drokin <oleg.drokin@intel.com>
Mon, 24 Aug 2015 15:40:08 +0000 (11:40 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Sat, 29 Aug 2015 01:03:55 +0000 (01:03 +0000)
strncpy_from_user could return negative values on error,
so need to take those into account.
Since ll_getname is used to get a single component name from userspace
to transfer to server as-is, there's no need to allocate 4k buffer
as done by __getname. Allocate NAME_MAX+1 buffer instead to ensure
we have enough for a null terminated max valid length buffer.

Change-Id: I9ce50d33864c7efd6fd019b592199f4fcf75410c
Signed-off-by: Oleg Drokin <oleg.drokin@intel.com>
Reviewed-on: http://review.whamcloud.com/15089
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
lustre/llite/dir.c

index af02f98..51a42ab 100644 (file)
@@ -1059,29 +1059,33 @@ out:
         RETURN(rc);
 }
 
         RETURN(rc);
 }
 
-static char *
-ll_getname(const char __user *filename)
+/* This function tries to get a single name component,
+ * to send to the server. No actual path traversal involved,
+ * so we limit to NAME_MAX */
+static char *ll_getname(const char __user *filename)
 {
        int ret = 0, len;
 {
        int ret = 0, len;
-       char *tmp = __getname();
+       char *tmp;
+
+       OBD_ALLOC(tmp, NAME_MAX + 1);
 
        if (!tmp)
                return ERR_PTR(-ENOMEM);
 
 
        if (!tmp)
                return ERR_PTR(-ENOMEM);
 
-       len = strncpy_from_user(tmp, filename, PATH_MAX);
-       if (len == 0)
+       len = strncpy_from_user(tmp, filename, NAME_MAX + 1);
+       if (len < 0)
                ret = -ENOENT;
                ret = -ENOENT;
-       else if (len > PATH_MAX)
+       else if (len > NAME_MAX)
                ret = -ENAMETOOLONG;
 
        if (ret) {
                ret = -ENAMETOOLONG;
 
        if (ret) {
-               __putname(tmp);
+               OBD_FREE(tmp, NAME_MAX + 1);
                tmp =  ERR_PTR(ret);
        }
        return tmp;
 }
 
                tmp =  ERR_PTR(ret);
        }
        return tmp;
 }
 
-#define ll_putname(filename) __putname(filename)
+#define ll_putname(filename) OBD_FREE(filename, NAME_MAX + 1);
 
 static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
 
 static long ll_dir_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {