Skip to content

Commit 0ca81a2

Browse files
Doron Tsurdledford
authored andcommitted
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: a977049 ('[PATCH] IB: Add the kernel CM implementation') Signed-off-by: Doron Tsur <[email protected]> Signed-off-by: Matan Barak <[email protected]> Signed-off-by: Doug Ledford <[email protected]>
1 parent ab3964a commit 0ca81a2

File tree

1 file changed

+9
-1
lines changed
  • drivers/infiniband/core

1 file changed

+9
-1
lines changed

drivers/infiniband/core/cm.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -835,6 +835,11 @@ static void cm_destroy_id(struct ib_cm_id *cm_id, int err)
835835
case IB_CM_SIDR_REQ_RCVD:
836836
spin_unlock_irq(&cm_id_priv->lock);
837837
cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT);
838+
spin_lock_irq(&cm.lock);
839+
if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node))
840+
rb_erase(&cm_id_priv->sidr_id_node,
841+
&cm.remote_sidr_table);
842+
spin_unlock_irq(&cm.lock);
838843
break;
839844
case IB_CM_REQ_SENT:
840845
case IB_CM_MRA_REQ_RCVD:
@@ -3172,7 +3177,10 @@ int ib_send_cm_sidr_rep(struct ib_cm_id *cm_id,
31723177
spin_unlock_irqrestore(&cm_id_priv->lock, flags);
31733178

31743179
spin_lock_irqsave(&cm.lock, flags);
3175-
rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
3180+
if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) {
3181+
rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
3182+
RB_CLEAR_NODE(&cm_id_priv->sidr_id_node);
3183+
}
31763184
spin_unlock_irqrestore(&cm.lock, flags);
31773185
return 0;
31783186

0 commit comments

Comments
 (0)