Skip to contentSkip to conversation

staging: lustre: improve length checks in ioctls

PATCH In review Dan Carpenter 2 participants 2 messages Apr 24, 2014 – Apr 25, 2014

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/2 staging: lustre: improve length checks in ioctls

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.

---
Not tested.

drivers/staging/lustre/lustre/obdclass/linux/linux-module.c +2 -0
index e4e94cc..dec1037 100644
@@ -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");
drivers/staging/lustre/lustre/libcfs/linux/linux-module.c +4 -0
index e6eae06..9a3b07b 100644
@@ -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");
Reviewed-by on v1 1/2
#1 lore raw
Quoted 4 lines · Dan Carpenter

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.

Thanks for the patch.

Quoted 30 lines

---
Not tested.

drivers/staging/lustre/lustre/obdclass/linux/linux-module.c +2 -0
index e4e94cc..dec1037 100644
@@ -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");
drivers/staging/lustre/lustre/libcfs/linux/linux-module.c +1 -0
index e6eae06..9a3b07b 100644
@@ -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;

drivers/staging/lustre/lustre/libcfs/linux/linux-module.c int libcfs_ioctl_getdata(char *buf, char *end, void *arg) · line 76

Quoted 7 lines
drivers/staging/lustre/lustre/libcfs/linux/linux-module.c +1 -0
@@ -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;

will you fix this as well?

Thanks,
Tao