Re: [PATCH 6/6] Fix unsafe fw_event_list usage
From: Calvin Owens
Date: Sun Jul 12 2015 - 00:20:43 EST
On Friday 07/03 at 09:02 -0700, Christoph Hellwig wrote:
> On Mon, Jun 08, 2015 at 08:50:56PM -0700, Calvin Owens wrote:
> > Since the fw_event deletes itself from the list, cleanup_queue() can
> > walk onto garbage pointers or walk off into freed memory.
> >
> > This refactors the code in _scsih_fw_event_cleanup_queue() to not
> > iterate over the fw_event_list without a lock.
>
> I think this really should be folded into the previous one, with the
> fixes in this one the other refcounting change don't make a whole lot
> sense.
>
> > +static struct fw_event_work *dequeue_next_fw_event(struct MPT2SAS_ADAPTER *ioc)
> > +{
> > + unsigned long flags;
> > + struct fw_event_work *fw_event = NULL;
> > +
> > + spin_lock_irqsave(&ioc->fw_event_lock, flags);
> > + if (!list_empty(&ioc->fw_event_list)) {
> > + fw_event = list_first_entry(&ioc->fw_event_list,
> > + struct fw_event_work, list);
> > + list_del_init(&fw_event->list);
> > + fw_event_work_get(fw_event);
> > + }
> > + spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
> > +
> > + return fw_event;
>
> Shouldn't we have a reference for each item on the list that gets
> transfer to whomever removes it from the list?
Yes, this was a bit weird the way I did it. I redid this in v2, hopefully
it's clearer.
> Additionally _firmware_event_work should call dequeue_next_fw_event
> first in the function so that item is off the list before we process
> it, and can then just drop the reference once it's done.
That works: cleanup_queue() won't wait on some already-running events, but
destroy_workqueue() drains the wq, so we won't run ahead and free things
from under the fw_event when unwinding.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/