From 7f9f2d6abc40f79e802b4063859eda343043b85c Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Sun, 18 Oct 2026 11:55:04 +0900 Subject: [PATCH] firewire: core: fix race condition in split transaction handling For a split transaction, either fw_core_handle_response() or split_transaction_timeout_callback() may manipulate the same transaction entry in the pending transaction list. The return value of timer_delete() is used to determine which function handles the entry. If the transaction is a split transaction and timer_delete() returns zero, the timeout callback may already be running. In this case, the response handler must leave the entry in the list for the timeout callback to remove. A previous code refactoring broke this behavior, introducing a race condition in which both functions could process the same transaction. This could lead to a use-after-free on the transaction initiator side. Fix the regression by ensuring that the response handler does not process the transaction when timer_delete() returns zero. The timeout callback is responsible for removing the entry from the pending transaction list. Fixes: fa2dc2710076 ("firewire: core: code refactoring to find and pop transaction entry") Link: https://lore.kernel.org/r/20261018025504.290598-1-o-takashi@sakamocchi.jp Signed-off-by: Takashi Sakamoto --- drivers/firewire/core-transaction.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index 22ae387ae03c..016070560c74 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c @@ -89,8 +89,12 @@ void fw_cancel_pending_transactions(struct fw_card *card) break; \ } \ } \ - if (t && try_cancel_split_timeout(t)) \ - remove_transaction_entry(card, t); \ + if (t) { \ + if (try_cancel_split_timeout(t)) \ + remove_transaction_entry(card, t); \ + else \ + t = NULL; \ + } \ t; \ })