mirror of
https://github.com/swaywm/sway.git
synced 2026-04-16 08:21:30 -04:00
sway/desktop/transaction: skip freeing dirty nodes
This fixes a race that causes UAF when turning on multiple outputs after they've been off for a while. When output_begin_destroy is called while a transaction that references the output is in-flight, node_set_dirty adds the node to server.dirty_nodes list and ntxnrefs is still held by that transaction. Once the transaction completes and ntxnrefs drops to 0, transaction_destroy frees the output, leaving a dangling pointer in server.dirty_nodes. The next transaction_commit_dirty call then walks the dirty_nodes list and crashes The fix is to skip the free in transaction_destroy if node->dirty is set, this means transaction_commit_dirty hasn't processed this node yet and will bump ntxnrefs shortly. The free will happen once that transaction completes and ntxnrefs reaches 0 again and transaction_commit_dirty will allocate a fresh instruction and increment ntxnrefs again when it processes the node.
This commit is contained in:
parent
909a2ddb5f
commit
306ad8b4b7
1 changed files with 1 additions and 1 deletions
|
|
@ -59,7 +59,7 @@ static void transaction_destroy(struct sway_transaction *transaction) {
|
|||
if (node->instruction == instruction) {
|
||||
node->instruction = NULL;
|
||||
}
|
||||
if (node->destroying && node->ntxnrefs == 0) {
|
||||
if (node->destroying && node->ntxnrefs == 0 && !node->dirty) {
|
||||
switch (node->type) {
|
||||
case N_ROOT:
|
||||
sway_assert(false, "Never reached");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue