out of bounds warning in via_driver_irq_wait()

Dan Carpenter dan.carpenter at oracle.com
Fri Feb 13 00:25:27 PST 2015


Hello DRM devs,

Some ancient code leads to the following static checker warning:

	drivers/gpu/drm/via/via_irq.c:242 via_driver_irq_wait()
	error: buffer overflow 'masks' 4 <= 5

drivers/gpu/drm/via/via_irq.c
   207  static int
   208  via_driver_irq_wait(struct drm_device *dev, unsigned int irq, int force_sequence,
   209                      unsigned int *sequence)
   210  {
   211          drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
   212          unsigned int cur_irq_sequence;
   213          drm_via_irq_t *cur_irq;
   214          int ret = 0;
   215          maskarray_t *masks;
   216          int real_irq;
   217  
   218          DRM_DEBUG("\n");
   219  
   220          if (!dev_priv) {
   221                  DRM_ERROR("called with no initialization\n");
   222                  return -EINVAL;
   223          }
   224  
   225          if (irq >= drm_via_irq_num) {

We cap "irq" at 5.

   226                  DRM_ERROR("Trying to wait on unknown irq %d\n", irq);
   227                  return -EINVAL;
   228          }
   229  
   230          real_irq = dev_priv->irq_map[irq];

Then we get a "real_irq" which is capped at (-1)-3.

   231  
   232          if (real_irq < 0) {
   233                  DRM_ERROR("Video IRQ %d not available on this hardware.\n",
   234                            irq);
   235                  return -EINVAL;
   236          }

"real_irq" is now "0-3".

   237  
   238          masks = dev_priv->irq_masks;

Masks has ->num_irqs elements, but up to 4.

   239          cur_irq = dev_priv->via_irqs + real_irq;
   240  
   241          if (masks[real_irq][2] && !force_sequence) {
   242                  DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * HZ,
   243                              ((VIA_READ(masks[irq][2]) & masks[irq][3]) ==
                                                     ^^^              ^^^
   244                               masks[irq][4]));
                                           ^^^

Smatch says that 5 is more than 3 so these are possibly out of bounds.
I suspect that it should be "real_irq" here, but I'm not positive.

   245                  cur_irq_sequence = atomic_read(&cur_irq->irq_received);
   246          } else {

regards,
dan carpenter


More information about the dri-devel mailing list