* [PATCH 6.6.y 0/3] drm/exynos: vidi: fix various memory corruption bugs
@ 2026-02-27 4:59 Jeongjun Park
2026-02-27 4:59 ` [PATCH 6.6.y 1/3] drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl() Jeongjun Park
` (2 more replies)
0 siblings, 3 replies; 7+ messages in thread
From: Jeongjun Park @ 2026-02-27 4:59 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, Inki Dae, Seung-Woo Kim, Kyungmin Park,
David Airlie, Simona Vetter, Krzysztof Kozlowski, Alim Akhtar,
dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel,
Jeongjun Park
This backport patch is for 6.6.y only and fixes a bug in the
Exynos VIDI driver.
https://lore.kernel.org/all/20260119082553.195181-1-aha310510@gmail.com/
Jeongjun Park (3):
drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl()
drm/exynos: vidi: fix to avoid directly dereferencing user pointer
drm/exynos: vidi: use ctx->lock to protect struct vidi_context member variables related to memory alloc/free
drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 +
drivers/gpu/drm/exynos/exynos_drm_vidi.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------
2 files changed, 60 insertions(+), 13 deletions(-)
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 6.6.y 1/3] drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl() 2026-02-27 4:59 [PATCH 6.6.y 0/3] drm/exynos: vidi: fix various memory corruption bugs Jeongjun Park @ 2026-02-27 4:59 ` Jeongjun Park 2026-03-19 12:01 ` Patch "drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl()" has been added to the 6.6-stable tree gregkh 2026-02-27 4:59 ` [PATCH 6.6.y 2/3] drm/exynos: vidi: fix to avoid directly dereferencing user pointer Jeongjun Park 2026-02-27 4:59 ` [PATCH 6.6.y 3/3] drm/exynos: vidi: use ctx->lock to protect struct vidi_context member variables related to memory alloc/free Jeongjun Park 2 siblings, 1 reply; 7+ messages in thread From: Jeongjun Park @ 2026-02-27 4:59 UTC (permalink / raw) To: stable Cc: Greg Kroah-Hartman, Inki Dae, Seung-Woo Kim, Kyungmin Park, David Airlie, Simona Vetter, Krzysztof Kozlowski, Alim Akhtar, dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel, Jeongjun Park [ Upstream commit d3968a0d85b211e197f2f4f06268a7031079e0d0 ] vidi_connection_ioctl() retrieves the driver_data from drm_dev->dev to obtain a struct vidi_context pointer. However, drm_dev->dev is the exynos-drm master device, and the driver_data contained therein is not the vidi component device, but a completely different device. This can lead to various bugs, ranging from null pointer dereferences and garbage value accesses to, in unlucky cases, out-of-bounds errors, use-after-free errors, and more. To resolve this issue, we need to store/delete the vidi device pointer in exynos_drm_private->vidi_dev during bind/unbind, and then read this exynos_drm_private->vidi_dev within ioctl() to obtain the correct struct vidi_context pointer. Cc: <stable@vger.kernel.org> Signed-off-by: Jeongjun Park <aha310510@gmail.com> Signed-off-by: Inki Dae <inki.dae@samsung.com> --- drivers/gpu/drm/exynos/exynos_drm_drv.h | 1 + drivers/gpu/drm/exynos/exynos_drm_vidi.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index 23646e55f142..06c29ff2aac0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -199,6 +199,7 @@ struct drm_exynos_file_private { struct exynos_drm_private { struct device *g2d_dev; struct device *dma_dev; + struct device *vidi_dev; void *mapping; /* for atomic commit */ diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 6de0cced6c9d..b31eefb3a8b1 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -223,9 +223,14 @@ ATTRIBUTE_GROUPS(vidi); int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, struct drm_file *file_priv) { - struct vidi_context *ctx = dev_get_drvdata(drm_dev->dev); + struct exynos_drm_private *priv = drm_dev->dev_private; + struct device *dev = priv ? priv->vidi_dev : NULL; + struct vidi_context *ctx = dev ? dev_get_drvdata(dev) : NULL; struct drm_exynos_vidi_connection *vidi = data; + if (!ctx) + return -ENODEV; + if (!vidi) { DRM_DEV_DEBUG_KMS(ctx->dev, "user data for vidi is null.\n"); @@ -374,6 +379,7 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) { struct vidi_context *ctx = dev_get_drvdata(dev); struct drm_device *drm_dev = data; + struct exynos_drm_private *priv = drm_dev->dev_private; struct drm_encoder *encoder = &ctx->encoder; struct exynos_drm_plane *exynos_plane; struct exynos_drm_plane_config plane_config = { 0 }; @@ -381,6 +387,8 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) int ret; ctx->drm_dev = drm_dev; + if (priv) + priv->vidi_dev = dev; plane_config.pixel_formats = formats; plane_config.num_pixel_formats = ARRAY_SIZE(formats); @@ -426,8 +434,12 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) static void vidi_unbind(struct device *dev, struct device *master, void *data) { struct vidi_context *ctx = dev_get_drvdata(dev); + struct drm_device *drm_dev = data; + struct exynos_drm_private *priv = drm_dev->dev_private; del_timer_sync(&ctx->timer); + if (priv) + priv->vidi_dev = NULL; } static const struct component_ops vidi_component_ops = { -- ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Patch "drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl()" has been added to the 6.6-stable tree 2026-02-27 4:59 ` [PATCH 6.6.y 1/3] drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl() Jeongjun Park @ 2026-03-19 12:01 ` gregkh 0 siblings, 0 replies; 7+ messages in thread From: gregkh @ 2026-03-19 12:01 UTC (permalink / raw) To: aha310510, airlied, alim.akhtar, dri-devel, gregkh, inki.dae, krzk, kyungmin.park, linux-arm-kernel, simona, sw0312.kim Cc: stable-commits This is a note to let you know that I've just added the patch titled drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl() to the 6.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: drm-exynos-vidi-use-priv-vidi_dev-for-ctx-lookup-in-vidi_connection_ioctl.patch and it can be found in the queue-6.6 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@vger.kernel.org> know about it. From stable+bounces-219909-greg=kroah.com@vger.kernel.org Fri Feb 27 06:00:30 2026 From: Jeongjun Park <aha310510@gmail.com> Date: Fri, 27 Feb 2026 13:59:51 +0900 Subject: drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl() To: stable@vger.kernel.org Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Inki Dae <inki.dae@samsung.com>, Seung-Woo Kim <sw0312.kim@samsung.com>, Kyungmin Park <kyungmin.park@samsung.com>, David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>, Krzysztof Kozlowski <krzk@kernel.org>, Alim Akhtar <alim.akhtar@samsung.com>, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org, Jeongjun Park <aha310510@gmail.com> Message-ID: <20260227045953.165751-2-aha310510@gmail.com> From: Jeongjun Park <aha310510@gmail.com> [ Upstream commit d3968a0d85b211e197f2f4f06268a7031079e0d0 ] vidi_connection_ioctl() retrieves the driver_data from drm_dev->dev to obtain a struct vidi_context pointer. However, drm_dev->dev is the exynos-drm master device, and the driver_data contained therein is not the vidi component device, but a completely different device. This can lead to various bugs, ranging from null pointer dereferences and garbage value accesses to, in unlucky cases, out-of-bounds errors, use-after-free errors, and more. To resolve this issue, we need to store/delete the vidi device pointer in exynos_drm_private->vidi_dev during bind/unbind, and then read this exynos_drm_private->vidi_dev within ioctl() to obtain the correct struct vidi_context pointer. 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_drv.h | 1 + drivers/gpu/drm/exynos/exynos_drm_vidi.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -199,6 +199,7 @@ struct drm_exynos_file_private { struct exynos_drm_private { struct device *g2d_dev; struct device *dma_dev; + struct device *vidi_dev; void *mapping; /* for atomic commit */ --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -224,9 +224,14 @@ ATTRIBUTE_GROUPS(vidi); int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, struct drm_file *file_priv) { - struct vidi_context *ctx = dev_get_drvdata(drm_dev->dev); + struct exynos_drm_private *priv = drm_dev->dev_private; + struct device *dev = priv ? priv->vidi_dev : NULL; + struct vidi_context *ctx = dev ? dev_get_drvdata(dev) : NULL; struct drm_exynos_vidi_connection *vidi = data; + if (!ctx) + return -ENODEV; + if (!vidi) { DRM_DEV_DEBUG_KMS(ctx->dev, "user data for vidi is null.\n"); @@ -386,6 +391,7 @@ static int vidi_bind(struct device *dev, { struct vidi_context *ctx = dev_get_drvdata(dev); struct drm_device *drm_dev = data; + struct exynos_drm_private *priv = drm_dev->dev_private; struct drm_encoder *encoder = &ctx->encoder; struct exynos_drm_plane *exynos_plane; struct exynos_drm_plane_config plane_config = { 0 }; @@ -393,6 +399,8 @@ static int vidi_bind(struct device *dev, int ret; ctx->drm_dev = drm_dev; + if (priv) + priv->vidi_dev = dev; plane_config.pixel_formats = formats; plane_config.num_pixel_formats = ARRAY_SIZE(formats); @@ -438,8 +446,12 @@ static int vidi_bind(struct device *dev, static void vidi_unbind(struct device *dev, struct device *master, void *data) { struct vidi_context *ctx = dev_get_drvdata(dev); + struct drm_device *drm_dev = data; + struct exynos_drm_private *priv = drm_dev->dev_private; del_timer_sync(&ctx->timer); + if (priv) + priv->vidi_dev = NULL; } static const struct component_ops vidi_component_ops = { Patches currently in stable-queue which might be from aha310510@gmail.com are queue-6.6/drm-exynos-vidi-use-ctx-lock-to-protect-struct-vidi_context-member-variables-related-to-memory-alloc-free.patch queue-6.6/drm-exynos-vidi-use-priv-vidi_dev-for-ctx-lookup-in-vidi_connection_ioctl.patch queue-6.6/drm-exynos-vidi-fix-to-avoid-directly-dereferencing-user-pointer.patch ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 6.6.y 2/3] drm/exynos: vidi: fix to avoid directly dereferencing user pointer 2026-02-27 4:59 [PATCH 6.6.y 0/3] drm/exynos: vidi: fix various memory corruption bugs Jeongjun Park 2026-02-27 4:59 ` [PATCH 6.6.y 1/3] drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl() Jeongjun Park @ 2026-02-27 4:59 ` Jeongjun Park 2026-03-19 12:01 ` Patch "drm/exynos: vidi: fix to avoid directly dereferencing user pointer" has been added to the 6.6-stable tree gregkh 2026-02-27 4:59 ` [PATCH 6.6.y 3/3] drm/exynos: vidi: use ctx->lock to protect struct vidi_context member variables related to memory alloc/free Jeongjun Park 2 siblings, 1 reply; 7+ messages in thread From: Jeongjun Park @ 2026-02-27 4:59 UTC (permalink / raw) To: stable Cc: Greg Kroah-Hartman, Inki Dae, Seung-Woo Kim, Kyungmin Park, David Airlie, Simona Vetter, Krzysztof Kozlowski, Alim Akhtar, dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel, Jeongjun Park [ Upstream commit d4c98c077c7fb2dfdece7d605e694b5ea2665085 ] 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> --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index d0e394397eca..576d79ebe9a8 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 -- ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Patch "drm/exynos: vidi: fix to avoid directly dereferencing user pointer" has been added to the 6.6-stable tree 2026-02-27 4:59 ` [PATCH 6.6.y 2/3] drm/exynos: vidi: fix to avoid directly dereferencing user pointer Jeongjun Park @ 2026-03-19 12:01 ` gregkh 0 siblings, 0 replies; 7+ messages in thread From: gregkh @ 2026-03-19 12:01 UTC (permalink / raw) To: aha310510, airlied, alim.akhtar, dri-devel, gregkh, inki.dae, krzk, kyungmin.park, linux-arm-kernel, simona, sw0312.kim Cc: stable-commits This is a note to let you know that I've just added the patch titled drm/exynos: vidi: fix to avoid directly dereferencing user pointer to the 6.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: drm-exynos-vidi-fix-to-avoid-directly-dereferencing-user-pointer.patch and it can be found in the queue-6.6 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@vger.kernel.org> know about it. From stable+bounces-219910-greg=kroah.com@vger.kernel.org Fri Feb 27 06:00:25 2026 From: Jeongjun Park <aha310510@gmail.com> Date: Fri, 27 Feb 2026 13:59:52 +0900 Subject: drm/exynos: vidi: fix to avoid directly dereferencing user pointer To: stable@vger.kernel.org Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Inki Dae <inki.dae@samsung.com>, Seung-Woo Kim <sw0312.kim@samsung.com>, Kyungmin Park <kyungmin.park@samsung.com>, David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>, Krzysztof Kozlowski <krzk@kernel.org>, Alim Akhtar <alim.akhtar@samsung.com>, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org, Jeongjun Park <aha310510@gmail.com> Message-ID: <20260227045953.165751-3-aha310510@gmail.com> From: Jeongjun Park <aha310510@gmail.com> [ Upstream commit d4c98c077c7fb2dfdece7d605e694b5ea2665085 ] 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 | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) --- 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_dev 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 Patches currently in stable-queue which might be from aha310510@gmail.com are queue-6.6/drm-exynos-vidi-use-ctx-lock-to-protect-struct-vidi_context-member-variables-related-to-memory-alloc-free.patch queue-6.6/drm-exynos-vidi-use-priv-vidi_dev-for-ctx-lookup-in-vidi_connection_ioctl.patch queue-6.6/drm-exynos-vidi-fix-to-avoid-directly-dereferencing-user-pointer.patch ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 6.6.y 3/3] drm/exynos: vidi: use ctx->lock to protect struct vidi_context member variables related to memory alloc/free 2026-02-27 4:59 [PATCH 6.6.y 0/3] drm/exynos: vidi: fix various memory corruption bugs Jeongjun Park 2026-02-27 4:59 ` [PATCH 6.6.y 1/3] drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl() Jeongjun Park 2026-02-27 4:59 ` [PATCH 6.6.y 2/3] drm/exynos: vidi: fix to avoid directly dereferencing user pointer Jeongjun Park @ 2026-02-27 4:59 ` Jeongjun Park 2026-03-19 12:01 ` Patch "drm/exynos: vidi: use ctx->lock to protect struct vidi_context member variables related to memory alloc/free" has been added to the 6.6-stable tree gregkh 2 siblings, 1 reply; 7+ messages in thread From: Jeongjun Park @ 2026-02-27 4:59 UTC (permalink / raw) To: stable Cc: Greg Kroah-Hartman, Inki Dae, Seung-Woo Kim, Kyungmin Park, David Airlie, Simona Vetter, Krzysztof Kozlowski, Alim Akhtar, dri-devel, linux-arm-kernel, linux-samsung-soc, linux-kernel, Jeongjun Park [ Upstream commit 52b330799e2d6f825ae2bb74662ec1b10eb954bb ] Exynos Virtual Display driver performs memory alloc/free operations without lock protection, which easily causes concurrency problem. For example, use-after-free can occur in race scenario like this: ``` CPU0 CPU1 CPU2 ---- ---- ---- vidi_connection_ioctl() if (vidi->connection) // true drm_edid = drm_edid_alloc(); // alloc drm_edid ... ctx->raw_edid = drm_edid; ... drm_mode_getconnector() drm_helper_probe_single_connector_modes() vidi_get_modes() if (ctx->raw_edid) // true drm_edid_dup(ctx->raw_edid); if (!drm_edid) // false ... vidi_connection_ioctl() if (vidi->connection) // false drm_edid_free(ctx->raw_edid); // free drm_edid ... drm_edid_alloc(drm_edid->edid) kmemdup(edid); // UAF!! ... ``` To prevent these vulns, at least in vidi_context, member variables related to memory alloc/free should be protected with ctx->lock. Cc: <stable@vger.kernel.org> Signed-off-by: Jeongjun Park <aha310510@gmail.com> --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 43 +++++++++++++++++++----- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index 576d79ebe9a8..b7eae2469b31 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -186,15 +186,17 @@ static ssize_t vidi_store_connection(struct device *dev, const char *buf, size_t len) { struct vidi_context *ctx = dev_get_drvdata(dev); - int ret; + int ret, new_connected; - ret = kstrtoint(buf, 0, &ctx->connected); + ret = kstrtoint(buf, 0, &new_connected); if (ret) return ret; - if (ctx->connected > 1) + if (new_connected > 1) return -EINVAL; + mutex_lock(&ctx->lock); + /* use fake edid data for test. */ if (!ctx->raw_edid) ctx->raw_edid = (struct edid *)fake_edid_info; @@ -202,14 +204,21 @@ static ssize_t vidi_store_connection(struct device *dev, /* if raw_edid isn't same as fake data then it can't be tested. */ if (ctx->raw_edid != (struct edid *)fake_edid_info) { DRM_DEV_DEBUG_KMS(dev, "edid data is not fake data.\n"); - return -EINVAL; + ret = -EINVAL; + goto fail; } + ctx->connected = new_connected; + mutex_unlock(&ctx->lock); + DRM_DEV_DEBUG_KMS(dev, "requested connection.\n"); drm_helper_hpd_irq_event(ctx->drm_dev); return len; +fail: + mutex_unlock(&ctx->lock); + return ret; } static DEVICE_ATTR(connection, 0644, vidi_show_connection, @@ -244,11 +253,14 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, return -EINVAL; } + mutex_lock(&ctx->lock); if (ctx->connected == vidi->connection) { + mutex_unlock(&ctx->lock); DRM_DEV_DEBUG_KMS(ctx->dev, "same connection request.\n"); return -EINVAL; } + mutex_unlock(&ctx->lock); if (vidi->connection) { struct edid *raw_edid; @@ -271,20 +283,27 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, "failed to allocate raw_edid.\n"); return -ENOMEM; } + mutex_lock(&ctx->lock); ctx->raw_edid = raw_edid; + mutex_unlock(&ctx->lock); } else { /* * with connection = 0, free raw_edid * only if raw edid data isn't same as fake data. */ + mutex_lock(&ctx->lock); if (ctx->raw_edid && ctx->raw_edid != (struct edid *)fake_edid_info) { kfree(ctx->raw_edid); ctx->raw_edid = NULL; } + mutex_unlock(&ctx->lock); } + mutex_lock(&ctx->lock); ctx->connected = vidi->connection; + mutex_unlock(&ctx->lock); + drm_helper_hpd_irq_event(ctx->drm_dev); return 0; @@ -299,7 +318,7 @@ static enum drm_connector_status vidi_detect(struct drm_connector *connector, * connection request would come from user side * to do hotplug through specific ioctl. */ - return ctx->connected ? connector_status_connected : + return READ_ONCE(ctx->connected) ? connector_status_connected : connector_status_disconnected; } @@ -321,22 +340,24 @@ static int vidi_get_modes(struct drm_connector *connector) struct vidi_context *ctx = ctx_from_connector(connector); struct edid *edid; int edid_len; - int count; + int count = 0; /* * the edid data comes from user side and it would be set * to ctx->raw_edid through specific ioctl. */ + + mutex_lock(&ctx->lock); if (!ctx->raw_edid) { DRM_DEV_DEBUG_KMS(ctx->dev, "raw_edid is null.\n"); - return 0; + goto fail; } edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL); if (!edid) { DRM_DEV_DEBUG_KMS(ctx->dev, "failed to allocate edid\n"); - return 0; + goto fail; } drm_connector_update_edid_property(connector, edid); @@ -345,6 +366,8 @@ static int vidi_get_modes(struct drm_connector *connector) kfree(edid); +fail: + mutex_unlock(&ctx->lock); return count; } @@ -490,11 +513,15 @@ static int vidi_remove(struct platform_device *pdev) { struct vidi_context *ctx = platform_get_drvdata(pdev); + mutex_lock(&ctx->lock); + if (ctx->raw_edid != (struct edid *)fake_edid_info) { kfree(ctx->raw_edid); ctx->raw_edid = NULL; } + mutex_unlock(&ctx->lock); + component_del(&pdev->dev, &vidi_component_ops); return 0; -- ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Patch "drm/exynos: vidi: use ctx->lock to protect struct vidi_context member variables related to memory alloc/free" has been added to the 6.6-stable tree 2026-02-27 4:59 ` [PATCH 6.6.y 3/3] drm/exynos: vidi: use ctx->lock to protect struct vidi_context member variables related to memory alloc/free Jeongjun Park @ 2026-03-19 12:01 ` gregkh 0 siblings, 0 replies; 7+ messages in thread From: gregkh @ 2026-03-19 12:01 UTC (permalink / raw) To: aha310510, airlied, alim.akhtar, dri-devel, gregkh, inki.dae, krzk, kyungmin.park, linux-arm-kernel, simona, sw0312.kim Cc: stable-commits This is a note to let you know that I've just added the patch titled drm/exynos: vidi: use ctx->lock to protect struct vidi_context member variables related to memory alloc/free to the 6.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: drm-exynos-vidi-use-ctx-lock-to-protect-struct-vidi_context-member-variables-related-to-memory-alloc-free.patch and it can be found in the queue-6.6 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@vger.kernel.org> know about it. From stable+bounces-219911-greg=kroah.com@vger.kernel.org Fri Feb 27 06:01:30 2026 From: Jeongjun Park <aha310510@gmail.com> Date: Fri, 27 Feb 2026 13:59:53 +0900 Subject: drm/exynos: vidi: use ctx->lock to protect struct vidi_context member variables related to memory alloc/free To: stable@vger.kernel.org Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>, Inki Dae <inki.dae@samsung.com>, Seung-Woo Kim <sw0312.kim@samsung.com>, Kyungmin Park <kyungmin.park@samsung.com>, David Airlie <airlied@gmail.com>, Simona Vetter <simona@ffwll.ch>, Krzysztof Kozlowski <krzk@kernel.org>, Alim Akhtar <alim.akhtar@samsung.com>, dri-devel@lists.freedesktop.org, linux-arm-kernel@lists.infradead.org, linux-samsung-soc@vger.kernel.org, linux-kernel@vger.kernel.org, Jeongjun Park <aha310510@gmail.com> Message-ID: <20260227045953.165751-4-aha310510@gmail.com> From: Jeongjun Park <aha310510@gmail.com> [ Upstream commit 52b330799e2d6f825ae2bb74662ec1b10eb954bb ] Exynos Virtual Display driver performs memory alloc/free operations without lock protection, which easily causes concurrency problem. For example, use-after-free can occur in race scenario like this: ``` CPU0 CPU1 CPU2 ---- ---- ---- vidi_connection_ioctl() if (vidi->connection) // true drm_edid = drm_edid_alloc(); // alloc drm_edid ... ctx->raw_edid = drm_edid; ... drm_mode_getconnector() drm_helper_probe_single_connector_modes() vidi_get_modes() if (ctx->raw_edid) // true drm_edid_dup(ctx->raw_edid); if (!drm_edid) // false ... vidi_connection_ioctl() if (vidi->connection) // false drm_edid_free(ctx->raw_edid); // free drm_edid ... drm_edid_alloc(drm_edid->edid) kmemdup(edid); // UAF!! ... ``` To prevent these vulns, at least in vidi_context, member variables related to memory alloc/free should be protected with ctx->lock. Cc: <stable@vger.kernel.org> Signed-off-by: Jeongjun Park <aha310510@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- drivers/gpu/drm/exynos/exynos_drm_vidi.c | 43 +++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 8 deletions(-) --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c @@ -186,15 +186,17 @@ static ssize_t vidi_store_connection(str const char *buf, size_t len) { struct vidi_context *ctx = dev_get_drvdata(dev); - int ret; + int ret, new_connected; - ret = kstrtoint(buf, 0, &ctx->connected); + ret = kstrtoint(buf, 0, &new_connected); if (ret) return ret; - if (ctx->connected > 1) + if (new_connected > 1) return -EINVAL; + mutex_lock(&ctx->lock); + /* use fake edid data for test. */ if (!ctx->raw_edid) ctx->raw_edid = (struct edid *)fake_edid_info; @@ -202,14 +204,21 @@ static ssize_t vidi_store_connection(str /* if raw_edid isn't same as fake data then it can't be tested. */ if (ctx->raw_edid != (struct edid *)fake_edid_info) { DRM_DEV_DEBUG_KMS(dev, "edid data is not fake data.\n"); - return -EINVAL; + ret = -EINVAL; + goto fail; } + ctx->connected = new_connected; + mutex_unlock(&ctx->lock); + DRM_DEV_DEBUG_KMS(dev, "requested connection.\n"); drm_helper_hpd_irq_event(ctx->drm_dev); return len; +fail: + mutex_unlock(&ctx->lock); + return ret; } static DEVICE_ATTR(connection, 0644, vidi_show_connection, @@ -244,11 +253,14 @@ int vidi_connection_ioctl(struct drm_dev return -EINVAL; } + mutex_lock(&ctx->lock); if (ctx->connected == vidi->connection) { + mutex_unlock(&ctx->lock); DRM_DEV_DEBUG_KMS(ctx->dev, "same connection request.\n"); return -EINVAL; } + mutex_unlock(&ctx->lock); if (vidi->connection) { struct edid *raw_edid; @@ -271,20 +283,27 @@ int vidi_connection_ioctl(struct drm_dev "failed to allocate raw_edid.\n"); return -ENOMEM; } + mutex_lock(&ctx->lock); ctx->raw_edid = raw_edid; + mutex_unlock(&ctx->lock); } else { /* * with connection = 0, free raw_edid * only if raw edid data isn't same as fake data. */ + mutex_lock(&ctx->lock); if (ctx->raw_edid && ctx->raw_edid != (struct edid *)fake_edid_info) { kfree(ctx->raw_edid); ctx->raw_edid = NULL; } + mutex_unlock(&ctx->lock); } + mutex_lock(&ctx->lock); ctx->connected = vidi->connection; + mutex_unlock(&ctx->lock); + drm_helper_hpd_irq_event(ctx->drm_dev); return 0; @@ -299,7 +318,7 @@ static enum drm_connector_status vidi_de * connection request would come from user side * to do hotplug through specific ioctl. */ - return ctx->connected ? connector_status_connected : + return READ_ONCE(ctx->connected) ? connector_status_connected : connector_status_disconnected; } @@ -321,22 +340,24 @@ static int vidi_get_modes(struct drm_con struct vidi_context *ctx = ctx_from_connector(connector); struct edid *edid; int edid_len; - int count; + int count = 0; /* * the edid data comes from user side and it would be set * to ctx->raw_edid through specific ioctl. */ + + mutex_lock(&ctx->lock); if (!ctx->raw_edid) { DRM_DEV_DEBUG_KMS(ctx->dev, "raw_edid is null.\n"); - return 0; + goto fail; } edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; edid = kmemdup(ctx->raw_edid, edid_len, GFP_KERNEL); if (!edid) { DRM_DEV_DEBUG_KMS(ctx->dev, "failed to allocate edid\n"); - return 0; + goto fail; } drm_connector_update_edid_property(connector, edid); @@ -345,6 +366,8 @@ static int vidi_get_modes(struct drm_con kfree(edid); +fail: + mutex_unlock(&ctx->lock); return count; } @@ -490,11 +513,15 @@ static int vidi_remove(struct platform_d { struct vidi_context *ctx = platform_get_drvdata(pdev); + mutex_lock(&ctx->lock); + if (ctx->raw_edid != (struct edid *)fake_edid_info) { kfree(ctx->raw_edid); ctx->raw_edid = NULL; } + mutex_unlock(&ctx->lock); + component_del(&pdev->dev, &vidi_component_ops); return 0; Patches currently in stable-queue which might be from aha310510@gmail.com are queue-6.6/drm-exynos-vidi-use-ctx-lock-to-protect-struct-vidi_context-member-variables-related-to-memory-alloc-free.patch queue-6.6/drm-exynos-vidi-use-priv-vidi_dev-for-ctx-lookup-in-vidi_connection_ioctl.patch queue-6.6/drm-exynos-vidi-fix-to-avoid-directly-dereferencing-user-pointer.patch ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-03-19 12:02 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-27 4:59 [PATCH 6.6.y 0/3] drm/exynos: vidi: fix various memory corruption bugs Jeongjun Park 2026-02-27 4:59 ` [PATCH 6.6.y 1/3] drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl() Jeongjun Park 2026-03-19 12:01 ` Patch "drm/exynos: vidi: use priv->vidi_dev for ctx lookup in vidi_connection_ioctl()" has been added to the 6.6-stable tree gregkh 2026-02-27 4:59 ` [PATCH 6.6.y 2/3] drm/exynos: vidi: fix to avoid directly dereferencing user pointer Jeongjun Park 2026-03-19 12:01 ` Patch "drm/exynos: vidi: fix to avoid directly dereferencing user pointer" has been added to the 6.6-stable tree gregkh 2026-02-27 4:59 ` [PATCH 6.6.y 3/3] drm/exynos: vidi: use ctx->lock to protect struct vidi_context member variables related to memory alloc/free Jeongjun Park 2026-03-19 12:01 ` Patch "drm/exynos: vidi: use ctx->lock to protect struct vidi_context member variables related to memory alloc/free" has been added to the 6.6-stable tree gregkh
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox