Support for "control" nodes was removed from the drm subsystem some time
authorkettenis <kettenis@openbsd.org>
Fri, 29 Dec 2023 10:00:18 +0000 (10:00 +0000)
committerkettenis <kettenis@openbsd.org>
Fri, 29 Dec 2023 10:00:18 +0000 (10:00 +0000)
ago, but some code in drmopen() remained which means that opening a drm
device node with a minor that matches the range for the "control" nodes
will hit a kernel assertion.  A similar issue exists for "render" nodes
corresponding to a driver that only supports KMS (such as rkdrm(4)).

Add checks to see if the minor is valid and return ENXIO if that isn't the
case to prevent a kernel crash.

ok jsg@, miod@

sys/dev/pci/drm/drm_drv.c

index cce4310..de7239c 100644 (file)
@@ -1556,9 +1556,6 @@ struct drm_device *
 drm_get_device_from_kdev(dev_t kdev)
 {
        int unit = minor(kdev) & ((1 << CLONE_SHIFT) - 1);
-       /* control */
-       if (unit >= 64 && unit < 128)
-               unit -= 64;
        /* render */
        if (unit >= 128)
                unit -= 128;
@@ -1701,12 +1698,18 @@ drmopen(dev_t kdev, int flags, int fmt, struct proc *p)
        realminor =  dminor & ((1 << CLONE_SHIFT) - 1);
        if (realminor < 64)
                minor_type = DRM_MINOR_PRIMARY;
-       else if (realminor >= 64 && realminor < 128)
-               minor_type = DRM_MINOR_CONTROL;
-       else
+       else if (realminor >= 128 && realminor < 192)
                minor_type = DRM_MINOR_RENDER;
+       else {
+               ret = ENXIO;
+               goto err;
+       }
 
        dm = *drm_minor_get_slot(dev, minor_type);
+       if (dm == NULL) {
+               ret = ENXIO;
+               goto err;
+       }
        dm->index = minor(kdev);
 
        file_priv = drm_file_alloc(dm);