mirror of
https://github.com/swaywm/sway.git
synced 2026-04-28 06:46:26 -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.
(cherry picked from commit 1084d2e87a)
This commit is contained in:
parent
7afe37fcf3
commit
655b9a7e55
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