[Bug 231513] off-by-one overflow in drm_ioctl (sys/dev/drm/drm_drv.c)

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Thu Sep 20 13:17:03 UTC 2018


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=231513

            Bug ID: 231513
           Summary: off-by-one overflow in drm_ioctl
                    (sys/dev/drm/drm_drv.c)
           Product: Base System
           Version: CURRENT
          Hardware: Any
                OS: Any
            Status: New
          Severity: Affects Only Me
          Priority: ---
         Component: kern
          Assignee: bugs at FreeBSD.org
          Reporter: yangx92 at hotmail.com

Created attachment 197277
  --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=197277&action=edit
patch_for_drm_out-of-bouns_access

There is a off-by-one overflow in drm_ioctl (sys/dev/drm/drm_drv.c).

701 int drm_ioctl(struct cdev *kdev, u_long cmd, caddr_t data, int flags,
702     DRM_STRUCTPROC *p)
703 {
704         struct drm_device *dev = drm_get_device_from_kdev(kdev);
705         int retcode = 0;
706         drm_ioctl_desc_t *ioctl;
707         int (*func)(struct drm_device *dev, void *data, struct drm_file
*file_priv);
708         int nr = DRM_IOCTL_NR(cmd);
709         int is_driver_ioctl = 0;
710         struct drm_file *file_priv;
711 
... 
743         ioctl = &drm_ioctls[nr];
744         /* It's not a core DRM ioctl, try driver-specific. */
745         if (ioctl->func == NULL && nr >= DRM_COMMAND_BASE) {
746                 /* The array entries begin at DRM_COMMAND_BASE ioctl nr */
747                 nr -= DRM_COMMAND_BASE;
748                 if (nr > dev->driver->max_ioctl) {
749                         DRM_DEBUG("Bad driver ioctl number, 0x%x (of
0x%x)\n",
750                             nr, dev->driver->max_ioctl);
751                         return EINVAL;
752                 }
753                 ioctl = &dev->driver->ioctls[nr];
754                 is_driver_ioctl = 1;
755         }
756         func = ioctl->func;
757 
758         if (func == NULL) {
759                 DRM_DEBUG("no function\n");
760                 return EINVAL;
761         }
762 
763         if (((ioctl->flags & DRM_ROOT_ONLY) && !DRM_SUSER(p)) ||
764             ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) ||
765             ((ioctl->flags & DRM_MASTER) && !file_priv->master))
766                 return EACCES;
767 
768         if (is_driver_ioctl) {
769                 DRM_LOCK();
770                 /* shared code returns -errno */
771                 retcode = -func(dev, data, file_priv);
772                 DRM_UNLOCK();
773         } else {
774                 retcode = func(dev, data, file_priv);
775         }
776 
777         if (retcode != 0)
778                 DRM_DEBUG("    returning %d\n", retcode);
779 
780         return retcode;
781 }

The correct logic for line 748 is nr >= dev->driver->max_ioctl. Otherwise,
there would be out-of-bounds access in line 753. Then, ioctl is used in line
756.

The attachment is the proposal patch.

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-bugs mailing list