staging: lustre: improve length checks in ioctls
authorDan Carpenter <dan.carpenter@oracle.com>
Thu, 24 Apr 2014 21:49:13 +0000 (00:49 +0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 25 Apr 2014 22:08:45 +0000 (15:08 -0700)
We copy "hdr->ioc_len" from the user twice but we only verify that it's
within the limit on the first copy.  Otherwise we could read unmapped
memory and Oops.

Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
Reviewed-by: Peng Tao <bergwolf@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/lustre/lustre/libcfs/linux/linux-module.c
drivers/staging/lustre/lustre/obdclass/linux/linux-module.c

index e6eae0666f0d30c599960431a2b530235f98e0ab..9a3b07bd2fac0237e1a5eb6384d7547f1bfe319e 100644 (file)
@@ -44,6 +44,7 @@ int libcfs_ioctl_getdata(char *buf, char *end, void *arg)
 {
        struct libcfs_ioctl_hdr   *hdr;
        struct libcfs_ioctl_data  *data;
+       int orig_len;
        int err;
 
        hdr = (struct libcfs_ioctl_hdr *)buf;
@@ -69,9 +70,12 @@ int libcfs_ioctl_getdata(char *buf, char *end, void *arg)
                return -EINVAL;
        }
 
+       orig_len = hdr->ioc_len;
        err = copy_from_user(buf, (void *)arg, hdr->ioc_len);
        if (err)
                return err;
+       if (orig_len != data->ioc_len)
+               return -EINVAL;
 
        if (libcfs_ioctl_is_invalid(data)) {
                CERROR("PORTALS: ioctl not correctly formatted\n");
index e4e94cc1713d2508bb7bc87587832d783f9d9508..dec10377f22276aad9622502b548445e25623eeb 100644 (file)
@@ -122,6 +122,8 @@ int obd_ioctl_getdata(char **buf, int *len, void *arg)
                OBD_FREE_LARGE(*buf, hdr.ioc_len);
                return err;
        }
+       if (hdr.ioc_len != data->ioc_len)
+               return -EINVAL;
 
        if (obd_ioctl_is_invalid(data)) {
                CERROR("ioctl not correctly formatted\n");