staging: lustre: libcfs: double copy bug
authorDan Carpenter <dan.carpenter@oracle.com>
Mon, 30 Jan 2017 10:51:49 +0000 (13:51 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 3 Feb 2017 12:01:38 +0000 (13:01 +0100)
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.carpenter@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/lustre/lnet/libcfs/linux/linux-module.c

index 3f5d58babc2f0f65c757e2520a6af258e3c23577..075826bd3a2a666bc8bbe56c2a051bd2333da50e 100644 (file)
@@ -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;
 }