aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire
diff options
context:
space:
mode:
authorStefan Richter <stefanr@s5r6.in-berlin.de>2008-03-19 17:02:40 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2009-01-20 13:29:51 -0500
commita5c7f4710fba334bf613d705f97b4471b36446f8 (patch)
tree85deaf0584aea866a976245bae3c0d99bbca579f /drivers/firewire
parent1de9e8e70f5acc441550ca75433563d91b269bbe (diff)
firewire: insist on successive self ID complete events
The whole topology code only works if the old and new topologies which are compared come from immediately successive self ID complete events. If there happened bus resets without self ID complete events in the meantime, or self ID complete events with invalid selfIDs, the topology comparison could identify nodes wrongly, or more likely just corrupt kernel memory or panic right away. We now discard all nodes of the old topology and treat all current nodes as new ones if the current self ID generation is not the previous one plus 1. Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de> Signed-off-by: Jarod Wilson <jwilson@redhat.com>
Diffstat (limited to 'drivers/firewire')
-rw-r--r--drivers/firewire/fw-topology.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/drivers/firewire/fw-topology.c b/drivers/firewire/fw-topology.c
index c9be6e6948c4..e7520e4bd6bc 100644
--- a/drivers/firewire/fw-topology.c
+++ b/drivers/firewire/fw-topology.c
@@ -518,6 +518,18 @@ fw_core_handle_bus_reset(struct fw_card *card,
518 struct fw_node *local_node; 518 struct fw_node *local_node;
519 unsigned long flags; 519 unsigned long flags;
520 520
521 /*
522 * If the selfID buffer is not the immediate successor of the
523 * previously processed one, we cannot reliably compare the
524 * old and new topologies.
525 */
526 if ((generation & 0xff) != ((card->generation + 1) & 0xff) &&
527 card->local_node != NULL) {
528 fw_notify("skipped bus generations, destroying all nodes\n");
529 fw_destroy_nodes(card);
530 card->bm_retries = 0;
531 }
532
521 spin_lock_irqsave(&card->lock, flags); 533 spin_lock_irqsave(&card->lock, flags);
522 534
523 card->node_id = node_id; 535 card->node_id = node_id;