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: a977049dac
('[PATCH] IB: Add the kernel CM implementation')
Signed-off-by: Doron Tsur <doront@mellanox.com>
Signed-off-by: Matan Barak <matanb@mellanox.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
Родитель
ab3964ad2a
Коммит
0ca81a2840
|
@ -835,6 +835,11 @@ retest:
|
|||
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);
|
||||
rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
|
||||
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;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче