Merge tag 'firewire-fixes-6.19-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394

Pull firewire fix from Takashi Sakamoto:
"Fix a race condition introduced in v6.18.

Andreas Persson discovered this issue while working with Focusrite
Saffire Pro 40 (TCD33070). The fw_card instance maintains a linked
list of pending transactions, which must be protected against
concurrent access.

However, a commit b5725cfa4120 ("firewire: core: use spin lock
specific to timer for split transaction") unintentionally allowed
concurrent accesses to this list.

Fix this by adjusting the relevant critical sections to properly
serialize access"

* tag 'firewire-fixes-6.19-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux1394:
firewire: core: fix race condition against transaction list

+10 -9
+10 -9
drivers/firewire/core-transaction.c
··· 173 173 } 174 174 } 175 175 176 - static void start_split_transaction_timeout(struct fw_transaction *t, 177 - struct fw_card *card) 176 + // card->transactions.lock should be acquired in advance for the linked list. 177 + static void start_split_transaction_timeout(struct fw_transaction *t, unsigned int delta) 178 178 { 179 - unsigned long delta; 180 - 181 179 if (list_empty(&t->link) || WARN_ON(t->is_split_transaction)) 182 180 return; 183 181 184 182 t->is_split_transaction = true; 185 183 186 - // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for 187 - // local destination never runs in any type of IRQ context. 188 - scoped_guard(spinlock_irqsave, &card->split_timeout.lock) 189 - delta = card->split_timeout.jiffies; 190 184 mod_timer(&t->split_timeout_timer, jiffies + delta); 191 185 } 192 186 ··· 201 207 break; 202 208 case ACK_PENDING: 203 209 { 210 + unsigned int delta; 211 + 204 212 // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for 205 213 // local destination never runs in any type of IRQ context. 206 214 scoped_guard(spinlock_irqsave, &card->split_timeout.lock) { 207 215 t->split_timeout_cycle = 208 216 compute_split_timeout_timestamp(card, packet->timestamp) & 0xffff; 217 + delta = card->split_timeout.jiffies; 209 218 } 210 - start_split_transaction_timeout(t, card); 219 + 220 + // NOTE: This can be without irqsave when we can guarantee that __fw_send_request() for 221 + // local destination never runs in any type of IRQ context. 222 + scoped_guard(spinlock_irqsave, &card->transactions.lock) 223 + start_split_transaction_timeout(t, delta); 211 224 break; 212 225 } 213 226 case ACK_BUSY_X: