• Roland Dreier's avatar
    IB/mthca: Fix race in reference counting · a3285aa4
    Roland Dreier authored
    Fix races in in destroying various objects.  If a destroy routine
    waits for an object to become free by doing
    
    	wait_event(&obj->wait, !atomic_read(&obj->refcount));
    	/* now clean up and destroy the object */
    
    and another place drops a reference to the object by doing
    
    	if (atomic_dec_and_test(&obj->refcount))
    		wake_up(&obj->wait);
    
    then this is susceptible to a race where the wait_event() and final
    freeing of the object occur between the atomic_dec_and_test() and the
    wake_up().  And this is a use-after-free, since wake_up() will be
    called on part of the already-freed object.
    
    Fix this in mthca by replacing the atomic_t refcounts with plain old
    integers protected by a spinlock.  This makes it possible to do the
    decrement of the reference count and the wake_up() so that it appears
    as a single atomic operation to the code waiting on the wait queue.
    
    While touching this code, also simplify mthca_cq_clean(): the CQ being
    cleaned cannot go away, because it still has a QP attached to it.  So
    there's no reason to be paranoid and look up the CQ by number; it's
    perfectly safe to use the pointer that the callers already have.
    Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
    a3285aa4
mthca_qp.c 60.4 KB