Commit 301f56a1 authored by Katya Orlova's avatar Katya Orlova Committed by Zhang Kunbo
Browse files

drm/stm: Avoid use-after-free issues with crtc and plane

stable inclusion
from stable-v6.6.55
commit 0a1741d10da29aa84955ef89ae9a03c4b6038657
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAYRAF
CVE: CVE-2024-49992

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=0a1741d10da29aa84955ef89ae9a03c4b6038657

--------------------------------

[ Upstream commit 19dd9780b7ac673be95bf6fd6892a184c9db611f ]

ltdc_load() calls functions drm_crtc_init_with_planes(),
drm_universal_plane_init() and drm_encoder_init(). These functions
should not be called with parameters allocated with devm_kzalloc()
to avoid use-after-free issues [1].

Use allocations managed by the DRM framework.

Found by Linux Verification Center (linuxtesting.org).

[1]
https://lore.kernel.org/lkml/u366i76e3qhh3ra5oxrtngjtm2u5lterkekcz6y2jkndhuxzli@diujon4h7qwb/



Signed-off-by: default avatarKatya Orlova <e.orlova@ispras.ru>
Acked-by: default avatarRaphaël Gallais-Pou <raphael.gallais-pou@foss.st.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240216125040.8968-1-e.orlova@ispras.ru


Signed-off-by: default avatarRaphael Gallais-Pou <raphael.gallais-pou@foss.st.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>

Conflicts:
	drivers/gpu/drm/stm/drv.c
	drivers/gpu/drm/stm/ltdc.c
[ context conflicts in drv.c,
  keep operations after allocation of struct drm_encoder, drm_plane unchanged, only replace `devm_kzalloc`]
Signed-off-by: default avatarZhang Kunbo <zhangkunbo@huawei.com>
parent cc5e1415
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
#include <drm/drm_managed.h>

#include "ltdc.h"

@@ -73,7 +74,7 @@ static int drv_load(struct drm_device *ddev)

	DRM_DEBUG("%s\n", __func__);

	ldev = devm_kzalloc(ddev->dev, sizeof(*ldev), GFP_KERNEL);
	ldev = drmm_kzalloc(ddev, sizeof(*ldev), GFP_KERNEL);
	if (!ldev)
		return -ENOMEM;

+4 −4
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <drm/drm_plane_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
#include <drm/drm_managed.h>

#include <video/videomode.h>

@@ -956,7 +957,6 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
{
	unsigned long possible_crtcs = CRTC_MASK;
	struct ltdc_device *ldev = ddev->dev_private;
	struct device *dev = ddev->dev;
	struct drm_plane *plane;
	unsigned int i, nb_fmt = 0;
	u32 formats[NB_PF * 2];
@@ -984,7 +984,7 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev,
		formats[nb_fmt++] = drm_fmt_no_alpha;
	}

	plane = devm_kzalloc(dev, sizeof(*plane), GFP_KERNEL);
	plane = drmm_kzalloc(ddev, sizeof(*plane), GFP_KERNEL);
	if (!plane)
		return NULL;

@@ -1115,7 +1115,7 @@ static int ltdc_encoder_init(struct drm_device *ddev, struct drm_bridge *bridge)
	struct drm_encoder *encoder;
	int ret;

	encoder = devm_kzalloc(ddev->dev, sizeof(*encoder), GFP_KERNEL);
	encoder = drmm_kzalloc(ddev, sizeof(*encoder), GFP_KERNEL);
	if (!encoder)
		return -ENOMEM;

@@ -1327,7 +1327,7 @@ int ltdc_load(struct drm_device *ddev)

	}

	crtc = devm_kzalloc(dev, sizeof(*crtc), GFP_KERNEL);
	crtc = drmm_kzalloc(ddev, sizeof(*crtc), GFP_KERNEL);
	if (!crtc) {
		DRM_ERROR("Failed to allocate crtc\n");
		ret = -ENOMEM;