Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ca81a28 authored by Doron Tsur's avatar Doron Tsur Committed by Doug Ledford
Browse files

IB/cm: Fix rb-tree duplicate free and use-after-free



ib_send_cm_sidr_rep could sometimes erase the node from the sidr
(depending on errors in the process). Since ib_send_cm_sidr_rep is
called both from cm_sidr_req_handler and cm_destroy_id, cm_id_priv
could be either erased from the rb_tree twice or not erased at all.
Fixing that by making sure it's erased only once before freeing
cm_id_priv.

Fixes: a977049d ('[PATCH] IB: Add the kernel CM implementation')
Signed-off-by: default avatarDoron Tsur <doront@mellanox.com>
Signed-off-by: default avatarMatan Barak <matanb@mellanox.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
parent ab3964ad
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -835,6 +835,11 @@ static void cm_destroy_id(struct ib_cm_id *cm_id, int err)
	case IB_CM_SIDR_REQ_RCVD:
		spin_unlock_irq(&cm_id_priv->lock);
		cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT);
		spin_lock_irq(&cm.lock);
		if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node))
			rb_erase(&cm_id_priv->sidr_id_node,
				 &cm.remote_sidr_table);
		spin_unlock_irq(&cm.lock);
		break;
	case IB_CM_REQ_SENT:
	case IB_CM_MRA_REQ_RCVD:
@@ -3172,7 +3177,10 @@ int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id,
	spin_unlock_irqrestore(&cm_id_priv->lock, flags);

	spin_lock_irqsave(&cm.lock, flags);
	if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) {
		rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
		RB_CLEAR_NODE(&cm_id_priv->sidr_id_node);
	}
	spin_unlock_irqrestore(&cm.lock, flags);
	return 0;