Unverified Commit ab3a96c2 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!2846 [sync] PR-2840: drm/qxl: fix UAF on handle creation

parents ca7aa764 f7328523
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -329,7 +329,7 @@ int qxl_gem_object_create_with_handle(struct qxl_device *qdev,
				      u32 domain,
				      size_t size,
				      struct qxl_surface *surf,
				      struct qxl_bo **qobj,
				      struct drm_gem_object **gobj,
				      uint32_t *handle);
void qxl_gem_object_free(struct drm_gem_object *gobj);
int qxl_gem_object_open(struct drm_gem_object *obj, struct drm_file *file_priv);
+4 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ int qxl_mode_dumb_create(struct drm_file *file_priv,
{
	struct qxl_device *qdev = to_qxl(dev);
	struct qxl_bo *qobj;
	struct drm_gem_object *gobj;
	uint32_t handle;
	int r;
	struct qxl_surface surf;
@@ -62,11 +63,13 @@ int qxl_mode_dumb_create(struct drm_file *file_priv,

	r = qxl_gem_object_create_with_handle(qdev, file_priv,
					      QXL_GEM_DOMAIN_SURFACE,
					      args->size, &surf, &qobj,
					      args->size, &surf, &gobj,
					      &handle);
	if (r)
		return r;
	qobj = gem_to_qxl_bo(gobj);
	qobj->is_dumb = true;
	drm_gem_object_put(gobj);
	args->pitch = pitch;
	args->handle = handle;
	return 0;
+17 −8
Original line number Diff line number Diff line
@@ -72,32 +72,41 @@ int qxl_gem_object_create(struct qxl_device *qdev, int size,
	return 0;
}

/*
 * If the caller passed a valid gobj pointer, it is responsible to call
 * drm_gem_object_put() when it no longer needs to acess the object.
 *
 * If gobj is NULL, it is handled internally.
 */
int qxl_gem_object_create_with_handle(struct qxl_device *qdev,
				      struct drm_file *file_priv,
				      u32 domain,
				      size_t size,
				      struct qxl_surface *surf,
				      struct qxl_bo **qobj,
				      struct drm_gem_object **gobj,
				      uint32_t *handle)
{
	struct drm_gem_object *gobj;
	int r;
	struct drm_gem_object *local_gobj;

	BUG_ON(!qobj);
	BUG_ON(!handle);

	r = qxl_gem_object_create(qdev, size, 0,
				  domain,
				  false, false, surf,
				  &gobj);
				  &local_gobj);
	if (r)
		return -ENOMEM;
	r = drm_gem_handle_create(file_priv, gobj, handle);
	r = drm_gem_handle_create(file_priv, local_gobj, handle);
	if (r)
		return r;

	if (gobj)
		*gobj = local_gobj;
	else
		/* drop reference from allocate - handle holds it now */
	*qobj = gem_to_qxl_bo(gobj);
	drm_gem_object_put(gobj);
		drm_gem_object_put(local_gobj);

	return 0;
}

+2 −4
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ static int qxl_alloc_ioctl(struct drm_device *dev, void *data,
	struct qxl_device *qdev = to_qxl(dev);
	struct drm_qxl_alloc *qxl_alloc = data;
	int ret;
	struct qxl_bo *qobj;
	uint32_t handle;
	u32 domain = QXL_GEM_DOMAIN_VRAM;

@@ -51,7 +50,7 @@ static int qxl_alloc_ioctl(struct drm_device *dev, void *data,
						domain,
						qxl_alloc->size,
						NULL,
						&qobj, &handle);
						NULL, &handle);
	if (ret) {
		DRM_ERROR("%s: failed to create gem ret=%d\n",
			  __func__, ret);
@@ -393,7 +392,6 @@ static int qxl_alloc_surf_ioctl(struct drm_device *dev, void *data,
{
	struct qxl_device *qdev = to_qxl(dev);
	struct drm_qxl_alloc_surf *param = data;
	struct qxl_bo *qobj;
	int handle;
	int ret;
	int size, actual_stride;
@@ -413,7 +411,7 @@ static int qxl_alloc_surf_ioctl(struct drm_device *dev, void *data,
						QXL_GEM_DOMAIN_SURFACE,
						size,
						&surf,
						&qobj, &handle);
						NULL, &handle);
	if (ret) {
		DRM_ERROR("%s: failed to create gem ret=%d\n",
			  __func__, ret);