The problem is that we copy hdr.ioc_len, we verify it, then we copy it
again without checking to see if it has changed in between the two
copies.

This could result in an information leak.

Signed-off-by: Dan Carpenter <dan.carpen...@oracle.com>

diff --git a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c 
b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c
index 3f5d58babc2f..075826bd3a2a 100644
--- a/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c
+++ b/drivers/staging/lustre/lnet/libcfs/linux/linux-module.c
@@ -122,7 +122,7 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp,
                         const struct libcfs_ioctl_hdr __user *uhdr)
 {
        struct libcfs_ioctl_hdr hdr;
-       int err = 0;
+       int err;
 
        if (copy_from_user(&hdr, uhdr, sizeof(hdr)))
                return -EFAULT;
@@ -150,9 +150,20 @@ int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp,
                return -ENOMEM;
 
        if (copy_from_user(*hdr_pp, uhdr, hdr.ioc_len)) {
-               LIBCFS_FREE(*hdr_pp, hdr.ioc_len);
                err = -EFAULT;
+               goto free;
        }
+
+       if ((*hdr_pp)->ioc_version != hdr.ioc_version ||
+           (*hdr_pp)->ioc_len != hdr.ioc_len) {
+               err = -EINVAL;
+               goto free;
+       }
+
+       return 0;
+
+free:
+       LIBCFS_FREE(*hdr_pp, hdr.ioc_len);
        return err;
 }
 
_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to