VYPR
Unrated severityNVD Advisory· Published May 27, 2026· Updated May 27, 2026

CVE-2026-45958

CVE-2026-45958

Description

In the Linux kernel, the following vulnerability has been resolved:

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

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.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A user-space pointer dereference in the Exynos DRM vidi driver allows arbitrary kernel memory read/write via vidi_connection_ioctl().

Vulnerability

In the Linux kernel, the Exynos DRM vidi driver function vidi_connection_ioctl() directly dereferences a user-supplied pointer (vidi->edid) without proper copy from user space. This vulnerability affects kernel versions up to the point where the fix was applied (commit 235d702b7714). The bug is in the staging/exynos DRM subsystem, specifically in the vidi (virtual display) component. No special kernel configuration beyond enabling the Exynos DRM driver is required.

Exploitation

An attacker with local access and the ability to issue DRM_IOCTL calls to the /dev/dri/card* device (typically requiring the video group or root privileges) can craft a malicious EDID data pointer. By supplying a controlled user-space pointer, the attacker bypasses the kernel's intended copy_from_user() mechanism, leading to arbitrary kernel memory being read or written as the kernel treats the pointer as a kernel address.

Impact

Successful exploitation allows an attacker to read or write arbitrary kernel memory, leading to full kernel compromise. This includes potential privilege escalation from local user to root, information disclosure of sensitive kernel data, and possible denial of service via memory corruption. The attack vector is local, and the impact is immediate with no user interaction required beyond issuing the ioctl.

Mitigation

The fix was committed in the Linux kernel stable repository at commit 235d702b7714. Users should update to a kernel version that includes this commit or apply the patch directly. The patch replaces the direct pointer dereference with copy_from_user() to safely copy EDID data from user space. No workaround is available without patching, as the vulnerable code path is in the mainline driver. The CVE is not listed in CISA's Known Exploited Vulnerabilities (KEV) catalog as of publication date.

[1]

AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

16
2e147aa3169b

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJeongjun ParkFeb 27, 2026Fixed in 6.6.130via kernel-cna
2 files changed · +22 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index d0e394397eca81..576d79ebe9a82f 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -252,19 +252,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index d0e394397eca81..576d79ebe9a82f 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -252,19 +252,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
235d702b7714

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJeongjun ParkJan 19, 2026Fixed in 6.19.4via kernel-cna
2 files changed · +36 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 02e22806450577..67bbf9b8bc0ef8 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -263,13 +263,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;
     
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 02e22806450577..67bbf9b8bc0ef8 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -263,13 +263,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;
     
    -- 
    cgit 1.3-korg
    
    
    
d4c98c077c7f

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJeongjun ParkJan 19, 2026Fixed in 7.0via kernel-cna
2 files changed · +36 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 480c99a8f9f757..9709c07e5d8f48 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -252,13 +252,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;
     
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 480c99a8f9f757..9709c07e5d8f48 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -252,13 +252,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;
     
    -- 
    cgit 1.3-korg
    
    
    
7efb6a4e6b1b

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJeongjun ParkJan 19, 2026Fixed in 6.1.167via kernel-cna
2 files changed · +22 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index d0e394397eca81..576d79ebe9a82f 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -252,19 +252,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index d0e394397eca81..576d79ebe9a82f 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -252,19 +252,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
13537f7f6d28

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJeongjun ParkJan 19, 2026Fixed in 5.10.253via kernel-cna
2 files changed · +22 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 89a0a7e74473a9..97a1690dac3aa9 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -251,19 +251,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 89a0a7e74473a9..97a1690dac3aa9 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -251,19 +251,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
c2914c0ca755

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJeongjun ParkJan 19, 2026Fixed in 5.15.203via kernel-cna
2 files changed · +22 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 89a0a7e74473a9..97a1690dac3aa9 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -251,19 +251,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 89a0a7e74473a9..97a1690dac3aa9 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -251,19 +251,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
4949e32387fe

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJeongjun ParkJan 19, 2026Fixed in 6.18.14via kernel-cna
2 files changed · +36 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index bf5ba545891746..37733f2ac0e7a6 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -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;
     
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index bf5ba545891746..37733f2ac0e7a6 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -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;
     
    -- 
    cgit 1.3-korg
    
    
    
4c4193829109

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitJeongjun ParkJan 19, 2026Fixed in 6.12.77via kernel-cna
2 files changed · +36 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 6de0cced6c9d21..007fd8dad35598 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -246,13 +246,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;
     
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 6de0cced6c9d21..007fd8dad35598 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -246,13 +246,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;
     
    -- 
    cgit 1.3-korg
    
    
    
2e147aa3169b

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

2 files changed · +22 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index d0e394397eca81..576d79ebe9a82f 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -252,19 +252,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index d0e394397eca81..576d79ebe9a82f 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -252,19 +252,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
13537f7f6d28

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

2 files changed · +22 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 89a0a7e74473a9..97a1690dac3aa9 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -251,19 +251,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 89a0a7e74473a9..97a1690dac3aa9 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -251,19 +251,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
235d702b7714

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

2 files changed · +36 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 02e22806450577..67bbf9b8bc0ef8 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -263,13 +263,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;
     
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 02e22806450577..67bbf9b8bc0ef8 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -263,13 +263,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;
     
    -- 
    cgit 1.3-korg
    
    
    
7efb6a4e6b1b

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

2 files changed · +22 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index d0e394397eca81..576d79ebe9a82f 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -252,19 +252,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index d0e394397eca81..576d79ebe9a82f 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -252,19 +252,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
c2914c0ca755

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

2 files changed · +22 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 89a0a7e74473a9..97a1690dac3aa9 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -251,19 +251,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+11 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 89a0a7e74473a9..97a1690dac3aa9 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -251,19 +251,26 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data,
     
     	if (vidi->connection) {
     		struct edid *raw_edid;
    +		struct edid edid_buf;
    +		void *edid_userptr = u64_to_user_ptr(vidi->edid);
     
    -		raw_edid = (struct edid *)(unsigned long)vidi->edid;
    -		if (!drm_edid_is_valid(raw_edid)) {
    +		if (copy_from_user(&edid_buf, edid_userptr, sizeof(struct edid)))
    +			return -EFAULT;
    +
    +		if (!drm_edid_is_valid(&edid_buf)) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "edid data is invalid.\n");
     			return -EINVAL;
     		}
    -		ctx->raw_edid = drm_edid_duplicate(raw_edid);
    -		if (!ctx->raw_edid) {
    +
    +		raw_edid = drm_edid_duplicate(&edid_buf);
    +
    +		if (!raw_edid) {
     			DRM_DEV_DEBUG_KMS(ctx->dev,
     					  "failed to allocate raw_edid.\n");
     			return -ENOMEM;
     		}
    +		ctx->raw_edid = raw_edid;
     	} else {
     		/*
     		 * with connection = 0, free raw_edid
    -- 
    cgit 1.3-korg
    
    
    
4949e32387fe

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

2 files changed · +36 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index bf5ba545891746..37733f2ac0e7a6 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -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;
     
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index bf5ba545891746..37733f2ac0e7a6 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -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;
     
    -- 
    cgit 1.3-korg
    
    
    
4c4193829109

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

2 files changed · +36 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 6de0cced6c9d21..007fd8dad35598 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -246,13 +246,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;
     
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 6de0cced6c9d21..007fd8dad35598 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -246,13 +246,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;
     
    -- 
    cgit 1.3-korg
    
    
    
d4c98c077c7f

drm/exynos: vidi: fix to avoid directly dereferencing user pointer

2 files changed · +36 10
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 480c99a8f9f757..9709c07e5d8f48 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -252,13 +252,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;
     
    -- 
    cgit 1.3-korg
    
    
    
  • drivers/gpu/drm/exynos/exynos_drm_vidi.c+18 5 modified
    diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    index 480c99a8f9f757..9709c07e5d8f48 100644
    --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c
    @@ -252,13 +252,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;
     
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Directly dereferencing a user-space pointer (vidi->edid) in the kernel without using copy_from_user(), allowing arbitrary kernel memory access."

Attack vector

An attacker with access to the Exynos DRM device can invoke the vidi_connection_ioctl() and supply a crafted user-space pointer via vidi->edid. The vulnerable code casts this pointer directly to a struct edid* and dereferences it in kernel context [patch_id=2660989]. Because no copy_from_user() is used, the attacker can read or write arbitrary kernel memory by pointing vidi->edid at any kernel address. The only precondition is that the attacker can open the DRM device and issue the VIDI connection ioctl.

Affected code

The vulnerable function is vidi_connection_ioctl() in drivers/gpu/drm/exynos/exynos_drm_vidi.c. The fault lies in the lines that cast vidi->edid (a user pointer) to (struct edid*)(unsigned long)vidi->edid and then dereference it directly [patch_id=2660989].

What the fix does

The patch replaces the direct dereference with a safe copy_from_user() call. In the simpler variant [patch_id=2660989], a stack buffer (edid_buf) is used to copy sizeof(struct edid) bytes from user space before validation. In the more complete variant [patch_id=2660992], the code first copies the EDID header to determine the total size (extensions+1 * EDID_LENGTH), kmalloc()s a buffer of that size, then copies the full EDID from user space. Both variants eliminate the unsafe (struct edid*)(unsigned long)vidi->edid cast and ensure all user data is accessed via copy_from_user(), which returns -EFAULT on failure.

Preconditions

  • authAttacker must be able to open the Exynos DRM device and call the vidi_connection_ioctl() ioctl.
  • configThe vidi->connection flag must be set to enter the vulnerable code path.
  • inputAttacker controls the vidi->edid user pointer value passed to the ioctl.

Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

8

News mentions

0

No linked articles in our index yet.