Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2a48e52 authored by Keith Packard's avatar Keith Packard Committed by Daniel Vetter
Browse files

drm: move lease init after validation in drm_lease_create



Patch bd36d3ba fixed a deadlock in the
failure path of drm_lease_create. This made the partially initialized
lease object visible for a short window of time.

To avoid having the lessee state appear transiently, I've rearranged
the code so that the lessor fields are not filled in until the
parameters are all validated and the function will succeed.

Signed-off-by: default avatarKeith Packard <keithp@keithp.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Link: https://patchwork.freedesktop.org/patch/msgid/20171221065424.1304-1-keithp@keithp.com
parent ce0769e0
Loading
Loading
Loading
Loading
+11 −11
Original line number Original line Diff line number Diff line
@@ -220,17 +220,6 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr


	mutex_lock(&dev->mode_config.idr_mutex);
	mutex_lock(&dev->mode_config.idr_mutex);


	/* Insert the new lessee into the tree */
	id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL);
	if (id < 0) {
		error = id;
		goto out_lessee;
	}

	lessee->lessee_id = id;
	lessee->lessor = drm_master_get(lessor);
	list_add_tail(&lessee->lessee_list, &lessor->lessees);

	idr_for_each_entry(leases, entry, object) {
	idr_for_each_entry(leases, entry, object) {
		error = 0;
		error = 0;
		if (!idr_find(&dev->mode_config.crtc_idr, object))
		if (!idr_find(&dev->mode_config.crtc_idr, object))
@@ -246,6 +235,17 @@ static struct drm_master *drm_lease_create(struct drm_master *lessor, struct idr
		}
		}
	}
	}


	/* Insert the new lessee into the tree */
	id = idr_alloc(&(drm_lease_owner(lessor)->lessee_idr), lessee, 1, 0, GFP_KERNEL);
	if (id < 0) {
		error = id;
		goto out_lessee;
	}

	lessee->lessee_id = id;
	lessee->lessor = drm_master_get(lessor);
	list_add_tail(&lessee->lessee_list, &lessor->lessees);

	/* Move the leases over */
	/* Move the leases over */
	lessee->leases = *leases;
	lessee->leases = *leases;
	DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor);
	DRM_DEBUG_LEASE("new lessee %d %p, lessor %d %p\n", lessee->lessee_id, lessee, lessor->lessee_id, lessor);