From 5904a68a390c69ed1c4d77c82576a03b693172c2 Mon Sep 17 00:00:00 2001 From: Brian Ashworth Date: Thu, 16 Jan 2020 22:19:13 -0500 Subject: [PATCH] output: return on wlr_output_commit failures There were two wlr_output_commit calls that were not being checked. If the commits fail, apply_output_config should early return false instead of continuing to apply more. In one of the two cases, it was possible for output_enable to be called immediately after a commit failed for wlr_output_enable. In some cases, wlroots will destroy the output when it fails to enable. When this happens, it was possible for output_enable to call apply_output_config again for the destroyed output. Since this is a use-after-free, the wlr_output has already been reset to NULL before freeing. This could results in wlr_output_enable or any of the other wlr_output_* calls being called with NULL as the wlr_output. --- sway/config/output.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sway/config/output.c b/sway/config/output.c index ec21b5127..241e2743f 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -328,7 +328,10 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { if (!oc || oc->dpms_state != DPMS_OFF) { sway_log(SWAY_DEBUG, "Enabling output %s", oc->name); wlr_output_enable(wlr_output, true); - wlr_output_commit(wlr_output); + if (!wlr_output_commit(wlr_output)) { + sway_log(SWAY_ERROR, "Failed to enable output %s", oc->name); + return false; + } } return output_enable(output, oc); } @@ -421,7 +424,10 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) { if (oc && oc->dpms_state == DPMS_OFF) { sway_log(SWAY_DEBUG, "Turning off output %s", oc->name); wlr_output_enable(wlr_output, false); - wlr_output_commit(wlr_output); + if (!wlr_output_commit(wlr_output)) { + sway_log(SWAY_ERROR, "Failed to turn off output %s", oc->name); + return false; + } } if (oc && oc->max_render_time >= 0) {