]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/exynos: vidi: fix to avoid directly dereferencing user pointer
authorJeongjun Park <aha310510@gmail.com>
Mon, 19 Jan 2026 08:25:52 +0000 (17:25 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 26 Feb 2026 22:59:47 +0000 (14:59 -0800)
commit d4c98c077c7fb2dfdece7d605e694b5ea2665085 upstream.

In vidi_connection_ioctl(), vidi->edid(user pointer) is directly
dereferenced in the kernel.

This allows arbitrary kernel memory access from the user space, so instead
of directly accessing the user pointer in the kernel, we should modify it
to copy edid to kernel memory using copy_from_user() and use it.

Cc: <stable@vger.kernel.org>
Signed-off-by: Jeongjun Park <aha310510@gmail.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/exynos/exynos_drm_vidi.c

index bf5ba545891746e4eec07b23f604b190bea3fa46..37733f2ac0e7a695bf27a5e5e61ed540467e5357 100644 (file)
@@ -262,13 +262,27 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
 
        if (vidi->connection) {
                const struct drm_edid *drm_edid;
-               const struct edid *raw_edid;
+               const void __user *edid_userptr = u64_to_user_ptr(vidi->edid);
+               void *edid_buf;
+               struct edid hdr;
                size_t size;
 
-               raw_edid = (const struct edid *)(unsigned long)vidi->edid;
-               size = (raw_edid->extensions + 1) * EDID_LENGTH;
+               if (copy_from_user(&hdr, edid_userptr, sizeof(hdr)))
+                       return -EFAULT;
 
-               drm_edid = drm_edid_alloc(raw_edid, size);
+               size = (hdr.extensions + 1) * EDID_LENGTH;
+
+               edid_buf = kmalloc(size, GFP_KERNEL);
+               if (!edid_buf)
+                       return -ENOMEM;
+
+               if (copy_from_user(edid_buf, edid_userptr, size)) {
+                       kfree(edid_buf);
+                       return -EFAULT;
+               }
+
+               drm_edid = drm_edid_alloc(edid_buf, size);
+               kfree(edid_buf);
                if (!drm_edid)
                        return -ENOMEM;