sway/desktop/transaction: skip freeing dirty nodes#9101
Open
llyyr wants to merge 1 commit intoswaywm:masterfrom
Open
sway/desktop/transaction: skip freeing dirty nodes#9101llyyr wants to merge 1 commit intoswaywm:masterfrom
llyyr wants to merge 1 commit intoswaywm:masterfrom
Conversation
Contributor
Author
|
I verified that this works by adding a log message and this morning it did hit this case! diff --git a/sway/desktop/transaction.c b/sway/desktop/transaction.c
index 0aa841b05148..0e0d28362d42 100644
--- a/sway/desktop/transaction.c
+++ b/sway/desktop/transaction.c
@@ -61,6 +61,8 @@ static void transaction_destroy(struct sway_transaction *transaction) {
}
if (node->destroying && node->ntxnrefs == 0) {
if (node->dirty) {
+ sway_log(SWAY_ERROR, "Node %p is dirty but has no transaction references, skipping destroy",
+ node);
continue;
}
switch (node->type) { |
83fb95f to
15cf51a
Compare
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.
15cf51a to
306ad8b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 time actually the correct fix for #9060 and #8969