Change 661563 by willa@willa_SpectraBSD on 2013/03/12 17:03:21 FireWire: Don't allow a tlabel to reference an xfer after free. sys/dev/firewire/firewire.c: - fw_xfer_unload(): Since we are about to free this xfer, call fw_tl_free() to remove the xfer from its tlabel's list, if it has a tlabel. - In every occasion when a xfer is removed from a tlabel's list, reset xfer->tl to -1 while holding fc->tlabel_lock, so that the xfer isn't mis-identified as belonging to a tlabel. Index: dev/firewire/firewire.c =================================================================== --- dev/firewire/firewire.c (revision 248803) +++ dev/firewire/firewire.c (working copy) @@ -374,6 +374,7 @@ "tl=0x%x flag=0x%02x\n", i, xfer->flag); fw_dump_hdr(&xfer->send.hdr, "send"); xfer->resp = ETIMEDOUT; + xfer->tl = -1; STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel); STAILQ_INSERT_TAIL(&xfer_timeout, xfer, tlabel); } @@ -608,6 +609,7 @@ while ((xfer = STAILQ_FIRST(&fc->tlabels[i])) != NULL) { if (firewire_debug) printf("tl=%d flag=%d\n", i, xfer->flag); + xfer->tl = -1; xfer->resp = EAGAIN; STAILQ_REMOVE_HEAD(&fc->tlabels[i], tlabel); STAILQ_INSERT_TAIL(&xfer_drain, xfer, tlabel); @@ -1067,6 +1069,7 @@ #endif STAILQ_REMOVE(&fc->tlabels[xfer->tl], xfer, fw_xfer, tlabel); + xfer->tl = -1; mtx_unlock(&fc->tlabel_lock); splx(s); return; @@ -1191,6 +1194,11 @@ splx(s); } if (xfer->fc != NULL) { + /* + * Ensure that any tlabel owner can't access this + * xfer after it's freed. + */ + fw_tl_free(xfer->fc, xfer); #if 1 if(xfer->flag & FWXF_START) /*