diff options
author | 2018-07-28 22:13:13 +1000 | |
---|---|---|
committer | 2018-07-28 22:41:24 +1000 | |
commit | 84cd22c8cb722daaa9250a792da0f44930accfae (patch) | |
tree | 598a024d300d4bdb700dff328a919b94b06a1e29 /sway/tree | |
parent | Merge pull request #2372 from RyanDwyer/fix-use-after-free-v2 (diff) | |
download | sway-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.
Diffstat (limited to 'sway/tree')
-rw-r--r-- | sway/tree/container.c | 7 |
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) { | |||
142 | static void container_workspace_free(struct sway_workspace *ws) { | 142 | static 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 | ||
197 | static struct sway_container *container_destroy_noreaping( | ||
198 | struct sway_container *con); | ||
199 | |||
199 | static struct sway_container *container_workspace_destroy( | 200 | static 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 | ||