Snipped all the bits where you are clearly correct.

On Mon, May 13, 2024 at 12:43:37PM -0700, Kees Cook wrote:
> > drivers/usb/class/usbtmc.c:852 usbtmc_generic_read() warn: potential 
> > integer overflow from user 'max_transfer_size + 1'
> >    842                   * wMaxPacketSize – 1) to avoid sending a 
> > zero-length
> >    843                   * packet
> >    844                   */
> >    845                  remaining = transfer_size;
> >    846                  if ((max_transfer_size % data->wMaxPacketSize) == 0)
> >    847                          max_transfer_size += (data->wMaxPacketSize 
> > - 1);
> >    848          } else {
> >    849                  /* round down to bufsize to avoid truncated data 
> > left */
> >    850                  if (max_transfer_size > bufsize) {
> >    851                          max_transfer_size =
> >    852                                  roundup(max_transfer_size + 1 - 
> > bufsize,
> >                                                 ^^^^^^^^^^^^^^^^^^^^^
> > This can overflow.  We should make it a rule that all size variables
> > have to be unsigned long.  That would have made this safe on 64 bit
> > systems.
> > 
> >    853                                          bufsize);
> >    854                  }
> >    855                  remaining = max_transfer_size;
> 
> Again, do we _want_ this to overflow? It looks like not. I'm not sure
> what this code is trying to do, though. The comment doesn't seem to
> match the code. Why isn't this just roundup(max_transfer_size, bufsize) ?
> 

roundup() has an integer overflow in it.


> > drivers/usb/misc/usbtest.c:1994 iso_alloc_urb() warn: potential integer 
> > overflow from user 'bytes + maxp'
> >   1974  static struct urb *iso_alloc_urb(
> >   1975          struct usb_device       *udev,
> >   1976          int                     pipe,
> >   1977          struct usb_endpoint_descriptor  *desc,
> >   1978          long                    bytes,
> >   1979          unsigned offset
> >   1980  )
> >   1981  {
> >   1982          struct urb              *urb;
> >   1983          unsigned                i, maxp, packets;
> >   1984  
> >   1985          if (bytes < 0 || !desc)
> >   1986                  return NULL;
> >   1987  
> >   1988          maxp = usb_endpoint_maxp(desc);
> >   1989          if (udev->speed >= USB_SPEED_SUPER)
> >   1990                  maxp *= ss_isoc_get_packet_num(udev, pipe);
> >   1991          else
> >   1992                  maxp *= usb_endpoint_maxp_mult(desc);
> >   1993  
> >   1994          packets = DIV_ROUND_UP(bytes, maxp);
> >                                        ^^^^^
> > The issue here is on a 32 bit system when bytes is INT_MAX.
> 
> All of these examples seem to be cases that should be mitigated. The
> earlier check should be expanded:
> 
>               if (bytes < 0 || bytes >= INT_MAX || !desc)

This doesn't work on 32bit systems.

> 
> > 
> >   1995  
> >   1996          urb = usb_alloc_urb(packets, GFP_KERNEL);
> >   1997          if (!urb)
> >   1998                  return urb;
> > 
> > 
> > drivers/char/ppdev.c:344 pp_set_timeout() warn: potential integer overflow 
> > from user 'tv_sec * 100'
> >    343  static int pp_set_timeout(struct pardevice *pdev, long tv_sec, int 
> > tv_usec)
> >    344  {
> >    345          long to_jiffies;
> >    346  
> >    347          if ((tv_sec < 0) || (tv_usec < 0))
> >    348                  return -EINVAL;
> >    349  
> >    350          to_jiffies = usecs_to_jiffies(tv_usec);
> >                                               ^^^^^^^
> > 
> >    351          to_jiffies += tv_sec * HZ;
> >                               ^^^^^^^^^^^
> > Both of these can overflow
> > 
> >    352          if (to_jiffies <= 0)
> >                     ^^^^^^^^^^^^^^^
> > But they're checked here.
> > 
> >    353                  return -EINVAL;
> >    354  
> >    355          pdev->timeout = to_jiffies;
> >    356          return 0;
> >    357  }
> 
> This doesn't look like a wrapping-desired case either, but just for fun,
> let's assume we want it.

The original programmer assumed it would wrap so it was intentional/desired.

> (And why are any of these signed?) Annotation
> is added to the variables:
> 
> static int pp_set_timeout(struct pardevice *pdev, long __wraps tv_sec, int 
> __wraps tv_usec)
> {
>       long __wraps to_jiffies;

Sure.

> > drivers/i2c/i2c-dev.c:485 i2cdev_ioctl() warn: potential integer overflow 
> > from user (local copy) 'arg * 10'
> >    478          case I2C_TIMEOUT:
> >    479                  if (arg > INT_MAX)
> >    480                          return -EINVAL;
> >    481  
> >    482                  /* For historical reasons, user-space sets the 
> > timeout
> >    483                   * value in units of 10 ms.
> >    484                   */
> >    485                  client->adapter->timeout = msecs_to_jiffies(arg * 
> > 10);
> >                                                                     
> > ^^^^^^^^^
> > This can overflow and then the msecs_to_jiffies() conversion also has
> > an integer overflow in it.
> 
> If we want these wrapping:
> 
>               unsigned long __wraps timeout = arg * 10;
>               client->adapter->timeout = msecs_to_jiffies(timeout);
> 
> and:
> 
> static inline unsigned long _msecs_to_jiffies(const unsigned int __wraps m)
> 
> 

Here we don't care about wrapping, but I wouldn't go so far as to say it
was intentional...  I guess this silences the warning.


> > drivers/hwmon/nct6775-core.c:2265 store_temp_offset() warn: potential 
> > integer overflow from user '__x + (__d / 2)'
> >   2251  static ssize_t
> >   2252  store_temp_offset(struct device *dev, struct device_attribute *attr,
> >   2253                    const char *buf, size_t count)
> >   2254  {
> >   2255          struct nct6775_data *data = dev_get_drvdata(dev);
> >   2256          struct sensor_device_attribute *sattr = 
> > to_sensor_dev_attr(attr);
> >   2257          int nr = sattr->index;
> >   2258          long val;
> >   2259          int err;
> >   2260  
> >   2261          err = kstrtol(buf, 10, &val);
> >   2262          if (err < 0)
> >   2263                  return err;
> >   2264  
> >   2265          val = clamp_val(DIV_ROUND_CLOSEST(val, 1000), -128, 127);
> >                                                   ^^^^^^^^^^
> > Overflow and then clamp.
> 
> Looks like DIV_ROUND_CLOSEST() needs to be made sane and use more modern
> helpers (it appears to be doing open-coded is_signed(), wants
> check_*_overflow(), etc).
> 

Sounds good.

regards,
dan carpenter

Reply via email to