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: a977049dacde ('[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>

authored by Doron Tsur and committed by Doug Ledford 0ca81a28 ab3964ad

Changed files
+9 -1
drivers
infiniband
core
+9 -1
drivers/infiniband/core/cm.c
··· 835 835 case IB_CM_SIDR_REQ_RCVD: 836 836 spin_unlock_irq(&cm_id_priv->lock); 837 837 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); 838 843 break; 839 844 case IB_CM_REQ_SENT: 840 845 case IB_CM_MRA_REQ_RCVD: ··· 3177 3172 spin_unlock_irqrestore(&cm_id_priv->lock, flags); 3178 3173 3179 3174 spin_lock_irqsave(&cm.lock, flags); 3180 - rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table); 3175 + if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) { 3176 + rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table); 3177 + RB_CLEAR_NODE(&cm_id_priv->sidr_id_node); 3178 + } 3181 3179 spin_unlock_irqrestore(&cm.lock, flags); 3182 3180 return 0; 3183 3181