Skip to contentSkip to conversation

gdth: integer overflow in ioctl

PATCH In review Dan Carpenter 1 participant 2 messages Oct 8, 2010 – Oct 21, 2010

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

PATCH 1/1 gdth: integer overflow in ioctl

gdth_ioctl_alloc() takes the size variable as an int. copy_from_user() takes the size variable as an unsigned long. gen.data_len and gen.sense_len are unsigned longs. On x86_64 longs are 64 bit and ints are 32 bit.

We could pass in a very large number and the allocation would truncate the size to 32 bits and allocate a small buffer. Then when we do the copy_from_user(), it would result in a memory corruption.

drivers/scsi/gdth.c +8 -0
index b860d65..4cf7ffa 100644
@@ -4175,6 +4175,14 @@ static int ioc_general(void __user *arg, char *cmnd)
     ha = gdth_find_ha(gen.ionode);
     if (!ha)
         return -EFAULT;
+
+    if (gen.data_len > INT_MAX)
+        return -EINVAL;
+    if (gen.sense_len > INT_MAX)
+        return -EINVAL;
+    if (gen.data_len + gen.sense_len > INT_MAX)
+        return -EINVAL;
+
     if (gen.data_len + gen.sense_len != 0) {
         if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len,
                                      FALSE, &paddr)))
#1 lore raw
Quoted 5 lines · Dan Carpenter

gdth_ioctl_alloc() takes the size variable as an int. copy_from_user() takes the size variable as an unsigned long. gen.data_len and gen.sense_len are unsigned longs. On x86_64 longs are 64 bit and ints are 32 bit.

Quoted 7 lines

We could pass in a very large number and the allocation would truncate the size to 32 bits and allocate a small buffer. Then when we do the copy_from_user(), it would result in a memory corruption.

I never know if anyone gets my emails and so I has a small sad face on
the front of my head here: ---------------> :(

regards,
dan carpenter