Commit faa08b86 authored by Steven Price's avatar Steven Price Committed by Wang Wensheng
Browse files

drm/plane: Move range check for format_count earlier

stable inclusion
from stable-v4.19.247
commit 4ab7e453a3ee88c274cf97bee9487ab92a66d313
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IBP6CD
CVE: CVE-2021-47659

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



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

[ Upstream commit 4b674dd6 ]

While the check for format_count > 64 in __drm_universal_plane_init()
shouldn't be hit (it's a WARN_ON), in its current position it will then
leak the plane->format_types array and fail to call
drm_mode_object_unregister() leaking the modeset identifier. Move it to
the start of the function to avoid allocating those resources in the
first place.

Signed-off-by: default avatarSteven Price <steven.price@arm.com>
Signed-off-by: default avatarLiviu Dudau <liviu.dudau@arm.com>
Link: https://lore.kernel.org/dri-devel/20211203102815.38624-1-steven.price@arm.com/


Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarWang Wensheng <wangwensheng4@huawei.com>
parent a304375c
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -177,6 +177,13 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
	if (WARN_ON(config->num_total_plane >= 32))
		return -EINVAL;

	/*
	 * First driver to need more than 64 formats needs to fix this. Each
	 * format is encoded as a bit and the current code only supports a u64.
	 */
	if (WARN_ON(format_count > 64))
		return -EINVAL;

	WARN_ON(drm_drv_uses_atomic_modeset(dev) &&
		(!funcs->atomic_destroy_state ||
		 !funcs->atomic_duplicate_state));
@@ -198,13 +205,6 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
		return -ENOMEM;
	}

	/*
	 * First driver to need more than 64 formats needs to fix this. Each
	 * format is encoded as a bit and the current code only supports a u64.
	 */
	if (WARN_ON(format_count > 64))
		return -EINVAL;

	if (format_modifiers) {
		const uint64_t *temp_modifiers = format_modifiers;
		while (*temp_modifiers++ != DRM_FORMAT_MOD_INVALID)