Skip to content

Commit

Permalink
IB/sa_query: Fix AH leak due to update_sm_ah() race
Browse files Browse the repository at this point in the history
Our testing uncovered a race condition in ib_sa_event():

	spin_lock_irqsave(&port->ah_lock, flags);
	if (port->sm_ah)
		kref_put(&port->sm_ah->ref, free_sm_ah);
	port->sm_ah = NULL;
	spin_unlock_irqrestore(&port->ah_lock, flags);

	schedule_work(&sa_dev->port[event->element.port_num -
				    sa_dev->start_port].update_task);

If two events occur back-to-back (e.g., client-reregister and LID
change), both may pass the spinlock-protected code above before the
scheduled work updates the port->sm_ah handle.  Then if the scheduled
work ends up running twice, the second operation will then find a
non-NULL port->sm_ah, and will simply overwrite it in update_sm_ah --
resulting in an AH leak.

Signed-off-by: Jack Morgenstein <jackm@dev.mellanox.co.il>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
  • Loading branch information
Jack Morgenstein authored and Roland Dreier committed Mar 3, 2009
1 parent f3b8436 commit 6b708b3
Showing 1 changed file with 2 additions and 0 deletions.
2 changes: 2 additions & 0 deletions drivers/infiniband/core/sa_query.c
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,8 @@ static void update_sm_ah(struct work_struct *work)
}

spin_lock_irq(&port->ah_lock);
if (port->sm_ah)
kref_put(&port->sm_ah->ref, free_sm_ah);
port->sm_ah = new_ah;
spin_unlock_irq(&port->ah_lock);

Expand Down

0 comments on commit 6b708b3

Please sign in to comment.