Commit bc9e619a authored by Maíra Canal's avatar Maíra Canal Committed by Kaixiong Yu
Browse files

drm/vc4: Stop the active perfmon before being destroyed

stable inclusion
from stable-v6.6.57
commit 937943c042503dc6087438bf3557f9057a588ba0
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IB2YWQ
CVE: CVE-2024-50187

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



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

commit 0b2ad4f6f2bec74a5287d96cb2325a5e11706f22 upstream.

Upon closing the file descriptor, the active performance monitor is not
stopped. Although all perfmons are destroyed in `vc4_perfmon_close_file()`,
the active performance monitor's pointer (`vc4->active_perfmon`) is still
retained.

If we open a new file descriptor and submit a few jobs with performance
monitors, the driver will attempt to stop the active performance monitor
using the stale pointer in `vc4->active_perfmon`. However, this pointer
is no longer valid because the previous process has already terminated,
and all performance monitors associated with it have been destroyed and
freed.

To fix this, when the active performance monitor belongs to a given
process, explicitly stop it before destroying and freeing it.

Cc: stable@vger.kernel.org # v4.17+
Cc: Boris Brezillon <bbrezillon@kernel.org>
Cc: Juan A. Suarez Romero <jasuarez@igalia.com>
Fixes: 65101d8c ("drm/vc4: Expose performance counters to userspace")
Signed-off-by: default avatarMaíra Canal <mcanal@igalia.com>
Reviewed-by: default avatarJuan A. Suarez <jasuarez@igalia.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20241004123817.890016-2-mcanal@igalia.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Conflicts:
	drivers/gpu/drm/vc4/vc4_perfmon.c
	drivers/gpu/drm/vc4/vc4_drv.h
[HULK-5.10 don't merge stable inclusion patch 30f8c74c
("drm/vc4: Warn if some v3d code is run on BCM2711"). Add struct vc4_dev *dev in
struct vc4_file]
Signed-off-by: default avatarKaixiong Yu <yukaixiong@huawei.com>
parent 929a9df3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -673,6 +673,8 @@ struct vc4_exec_info {
 * released when the DRM file is closed should be placed here.
 */
struct vc4_file {
	struct vc4_dev *dev;

	struct {
		struct idr idr;
		struct mutex lock;
+6 −1
Original line number Diff line number Diff line
@@ -83,6 +83,11 @@ void vc4_perfmon_open_file(struct vc4_file *vc4file)
static int vc4_perfmon_idr_del(int id, void *elem, void *data)
{
	struct vc4_perfmon *perfmon = elem;
	struct vc4_dev *vc4 = (struct vc4_dev *)data;

	/* If the active perfmon is being destroyed, stop it first */
	if (perfmon == vc4->active_perfmon)
		vc4_perfmon_stop(vc4, perfmon, false);

	vc4_perfmon_put(perfmon);

@@ -92,7 +97,7 @@ static int vc4_perfmon_idr_del(int id, void *elem, void *data)
void vc4_perfmon_close_file(struct vc4_file *vc4file)
{
	mutex_lock(&vc4file->perfmon.lock);
	idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, NULL);
	idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, vc4file->dev);
	idr_destroy(&vc4file->perfmon.idr);
	mutex_unlock(&vc4file->perfmon.lock);
}