aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-07-28 22:13:13 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-07-28 22:41:24 +1000
commit84cd22c8cb722daaa9250a792da0f44930accfae (patch)
tree598a024d300d4bdb700dff328a919b94b06a1e29
parentMerge pull request #2372 from RyanDwyer/fix-use-after-free-v2 (diff)
downloadsway-84cd22c8cb722daaa9250a792da0f44930accfae.tar.gz
sway-84cd22c8cb722daaa9250a792da0f44930accfae.tar.zst
sway-84cd22c8cb722daaa9250a792da0f44930accfae.zip
Fix crash when a deferred command destroys a workspace
Example config that produces the crash (with a single output): workspace 1 workspace 2 Prior to this commit, container_workspace_free would manually mark the L_FLOATING container as destroying and free it. This assumed the L_FLOATING container would never be involved in a transaction. This was a safe assumption when it was implemented, but became an incorrect assumption once parent/child relationships became transactionised. This commit removes the L_FLOATING free from container_workspace_free. When the workspace is destroyed, it starts the normal destroy process on the L_FLOATING container so it can be freed via transactions.
-rw-r--r--sway/tree/container.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 6ebf2653..01387636 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -142,8 +142,6 @@ struct sway_container *container_create(enum sway_container_type type) {
142static void container_workspace_free(struct sway_workspace *ws) { 142static void container_workspace_free(struct sway_workspace *ws) {
143 list_foreach(ws->output_priority, free); 143 list_foreach(ws->output_priority, free);
144 list_free(ws->output_priority); 144 list_free(ws->output_priority);
145 ws->floating->destroying = true;
146 container_free(ws->floating);
147 free(ws); 145 free(ws);
148} 146}
149 147
@@ -196,6 +194,9 @@ void container_free(struct sway_container *cont) {
196 free(cont); 194 free(cont);
197} 195}
198 196
197static struct sway_container *container_destroy_noreaping(
198 struct sway_container *con);
199
199static struct sway_container *container_workspace_destroy( 200static struct sway_container *container_workspace_destroy(
200 struct sway_container *workspace) { 201 struct sway_container *workspace) {
201 if (!sway_assert(workspace, "cannot destroy null workspace")) { 202 if (!sway_assert(workspace, "cannot destroy null workspace")) {
@@ -240,6 +241,8 @@ static struct sway_container *container_workspace_destroy(
240 } 241 }
241 } 242 }
242 243
244 container_destroy_noreaping(workspace->sway_workspace->floating);
245
243 return output; 246 return output;
244} 247}
245 248