Author: will
Date: Wed Jan 21 20:03:46 2015
New Revision: 277508
URL: https://svnweb.freebsd.org/changeset/base/277508

Log:
  Fix panic in firewire and creation of invalid config ROM.
  
  sys/boot/i386/libfirewire/firewire.c:
  sys/dev/firewire/firewire.c:
        Fix configuration ROM generation count wrapping logic
        so that the generation count is never outside of
        allowed limits (0x2 -> 0xF).
  
  sys/dev/firewire/firewire.c:
        In fw_xfer_unload(), xfer->fc may be NULL.  Protect
        against this before taking the fc lock.
  
  Submitted by: gibbs
  MFC after:    1 week
  Sponsored by: Spectra Logic
  MFSpectraBSD: 1110685 on 2015/01/05

Modified:
  head/sys/dev/firewire/firewire.c

Modified: head/sys/dev/firewire/firewire.c
==============================================================================
--- head/sys/dev/firewire/firewire.c    Wed Jan 21 20:02:16 2015        
(r277507)
+++ head/sys/dev/firewire/firewire.c    Wed Jan 21 20:03:46 2015        
(r277508)
@@ -761,8 +761,15 @@ fw_busreset(struct firewire_comm *fc, ui
        src = &fc->crom_src_buf->src;
        crom_load(src, newrom, CROMSIZE);
        if (bcmp(newrom, fc->config_rom, CROMSIZE) != 0) {
-               if (src->businfo.generation++ > FW_MAX_GENERATION)
+               /* Bump generation and reload. */
+               src->businfo.generation++;
+
+               /* Handle generation count wraps. */
+               if (src->businfo.generation < FW_GENERATION_CHANGEABLE)
                        src->businfo.generation = FW_GENERATION_CHANGEABLE;
+
+               /* Recalculate CRC to account for generation change. */
+               crom_load(src, newrom, CROMSIZE);
                bcopy(newrom, fc->config_rom, CROMSIZE);
        }
        free(newrom, M_FW);
@@ -1156,16 +1163,18 @@ fw_xfer_unload(struct fw_xfer *xfer)
 
        if (xfer == NULL)
                return;
-       FW_GLOCK(xfer->fc);
-       if (xfer->flag & FWXF_INQ) {
-               STAILQ_REMOVE(&xfer->q->q, xfer, fw_xfer, link);
-               xfer->flag &= ~FWXF_INQ;
-#if 0
-               xfer->q->queued--;
-#endif
-       }
-       FW_GUNLOCK(xfer->fc);
+
        if (xfer->fc != NULL) {
+               FW_GLOCK(xfer->fc);
+               if (xfer->flag & FWXF_INQ) {
+                       STAILQ_REMOVE(&xfer->q->q, xfer, fw_xfer, link);
+                       xfer->flag &= ~FWXF_INQ;
+       #if 0
+                       xfer->q->queued--;
+       #endif
+               }
+               FW_GUNLOCK(xfer->fc);
+
                /*
                 * Ensure that any tlabel owner can't access this
                 * xfer after it's freed.
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to