From 5c382f6344718786842aaec0930010679cd61927 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Fri, 7 Oct 2022 18:15:24 +0200 Subject: [PATCH] drm-lease-v1: fix error codepath We were crashing in the error codepath [1] when wlr_drm_create_lease() fails. To fix this, delay the creation of the wlr_drm_lease_v1 until the request is granted. Previously we were allocating that struct early without populating the drm_lease field. However that means we ended up with a half-constructed struct in the error codepath which is annoying to handle. [1]: https://github.com/swaywm/sway/issues/7204#issuecomment-1269797356 --- include/wlr/types/wlr_drm_lease_v1.h | 3 +-- types/wlr_drm_lease_v1.c | 35 ++++++++++++---------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/include/wlr/types/wlr_drm_lease_v1.h b/include/wlr/types/wlr_drm_lease_v1.h index 314eb8cc..4afa11e1 100644 --- a/include/wlr/types/wlr_drm_lease_v1.h +++ b/include/wlr/types/wlr_drm_lease_v1.h @@ -71,8 +71,7 @@ struct wlr_drm_lease_request_v1 { struct wlr_drm_lease_connector_v1 **connectors; size_t n_connectors; - /** NULL until the lease is submitted */ - struct wlr_drm_lease_v1 *lease; + struct wl_resource *lease_resource; bool invalid; diff --git a/types/wlr_drm_lease_v1.c b/types/wlr_drm_lease_v1.c index 463e2918..05d2520b 100644 --- a/types/wlr_drm_lease_v1.c +++ b/types/wlr_drm_lease_v1.c @@ -154,12 +154,17 @@ static void lease_handle_destroy(struct wl_listener *listener, void *data) { struct wlr_drm_lease_v1 *wlr_drm_lease_request_v1_grant( struct wlr_drm_lease_request_v1 *request) { - assert(request->lease); - + assert(!request->invalid); wlr_log(WLR_DEBUG, "Attempting to grant request %p", request); - struct wlr_drm_lease_v1 *lease = request->lease; - assert(!request->invalid); + struct wlr_drm_lease_v1 *lease = calloc(1, sizeof(*lease)); + if (!lease) { + wl_resource_post_no_memory(request->resource); + return NULL; + } + + lease->device = request->device; + lease->resource = request->lease_resource; /* Transform connectors list into wlr_output for leasing */ struct wlr_output *outputs[request->n_connectors + 1]; @@ -192,6 +197,9 @@ struct wlr_drm_lease_v1 *wlr_drm_lease_request_v1_grant( lease->destroy.notify = lease_handle_destroy; wl_signal_add(&lease->drm_lease->events.destroy, &lease->destroy); + wl_list_insert(&lease->device->leases, &lease->link); + wl_resource_set_user_data(lease->resource, lease); + wlr_log(WLR_DEBUG, "Granting request %p", request); wp_drm_lease_v1_send_lease_fd(lease->resource, fd); @@ -202,12 +210,12 @@ struct wlr_drm_lease_v1 *wlr_drm_lease_request_v1_grant( void wlr_drm_lease_request_v1_reject( struct wlr_drm_lease_request_v1 *request) { - assert(request && request->lease); + assert(request); wlr_log(WLR_DEBUG, "Rejecting request %p", request); request->invalid = true; - wp_drm_lease_v1_send_finished(request->lease->resource); + wp_drm_lease_v1_send_finished(request->lease_resource); } void wlr_drm_lease_v1_revoke(struct wlr_drm_lease_v1 *lease) { @@ -337,20 +345,7 @@ static void drm_lease_request_v1_handle_submit( } } - struct wlr_drm_lease_v1 *lease = calloc(1, sizeof(struct wlr_drm_lease_v1)); - if (!lease) { - wlr_log(WLR_ERROR, "Failed to allocate wlr_drm_lease_v1"); - wl_resource_post_no_memory(resource); - return; - } - - lease->device = request->device; - wl_list_insert(&lease->device->leases, &lease->link); - - lease->resource = lease_resource; - wl_resource_set_user_data(lease_resource, lease); - - request->lease = lease; + request->lease_resource = lease_resource; /* TODO: reject the request if the user does not grant it */ wl_signal_emit_mutable(&request->device->manager->events.request,