Commit 48030fc4 authored by Rob Clark's avatar Rob Clark Committed by Zeng Heng
Browse files

drm/virtio: Fix GEM handle creation UAF

stable inclusion
from stable-v4.19.270
commit 19ec87d06acfab2313ee82b2a689bf0c154e57ea
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IALIA1
CVE: CVE-2022-48899

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



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

[ Upstream commit 52531258 ]

Userspace can guess the handle value and try to race GEM object creation
with handle close, resulting in a use-after-free if we dereference the
object after dropping the handle's reference.  For that reason, dropping
the handle's reference must be done *after* we are done dereferencing
the object.

Signed-off-by: default avatarRob Clark <robdclark@chromium.org>
Reviewed-by: default avatarChia-I Wu <olvaffe@gmail.com>
Fixes: 62fb7a5e ("virtio-gpu: add 3d/virgl support")
Cc: stable@vger.kernel.org
Signed-off-by: default avatarDmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20221216233355.542197-2-robdclark@gmail.com


Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarZeng Heng <zengheng4@huawei.com>
parent 0e9c3469
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -309,7 +309,6 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
		}
		return ret;
	}
	drm_gem_object_put_unlocked(obj);

	rc->res_handle = res_id; /* similiar to a VM address */
	rc->bo_handle = handle;
@@ -318,6 +317,15 @@ static int virtio_gpu_resource_create_ioctl(struct drm_device *dev, void *data,
		virtio_gpu_unref_list(&validate_list);
		dma_fence_put(&fence->f);
	}

	/*
	 * The handle owns the reference now.  But we must drop our
	 * remaining reference *after* we no longer need to dereference
	 * the obj.  Otherwise userspace could guess the handle and
	 * race closing it from another thread.
	 */
	drm_gem_object_put_unlocked(obj);

	return 0;
fail_unref:
	if (vgdev->has_virgl_3d) {