1 From 0ca81a2840f77855bbad1b9f172c545c4dc9e6a4 Mon Sep 17 00:00:00 2001
2 From: Doron Tsur <doront@mellanox.com>
3 Date: Sun, 11 Oct 2015 15:58:17 +0300
4 Subject: IB/cm: Fix rb-tree duplicate free and use-after-free
6 From: Doron Tsur <doront@mellanox.com>
8 commit 0ca81a2840f77855bbad1b9f172c545c4dc9e6a4 upstream.
10 ib_send_cm_sidr_rep could sometimes erase the node from the sidr
11 (depending on errors in the process). Since ib_send_cm_sidr_rep is
12 called both from cm_sidr_req_handler and cm_destroy_id, cm_id_priv
13 could be either erased from the rb_tree twice or not erased at all.
14 Fixing that by making sure it's erased only once before freeing
17 Fixes: a977049dacde ('[PATCH] IB: Add the kernel CM implementation')
18 Signed-off-by: Doron Tsur <doront@mellanox.com>
19 Signed-off-by: Matan Barak <matanb@mellanox.com>
20 Signed-off-by: Doug Ledford <dledford@redhat.com>
21 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
24 drivers/infiniband/core/cm.c | 10 +++++++++-
25 1 file changed, 9 insertions(+), 1 deletion(-)
27 --- a/drivers/infiniband/core/cm.c
28 +++ b/drivers/infiniband/core/cm.c
29 @@ -860,6 +860,11 @@ retest:
30 case IB_CM_SIDR_REQ_RCVD:
31 spin_unlock_irq(&cm_id_priv->lock);
32 cm_reject_sidr_req(cm_id_priv, IB_SIDR_REJECT);
33 + spin_lock_irq(&cm.lock);
34 + if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node))
35 + rb_erase(&cm_id_priv->sidr_id_node,
36 + &cm.remote_sidr_table);
37 + spin_unlock_irq(&cm.lock);
40 ib_cancel_mad(cm_id_priv->av.port->mad_agent, cm_id_priv->msg);
41 @@ -3099,7 +3104,10 @@ int ib_send_cm_sidr_rep(struct ib_cm_id
42 spin_unlock_irqrestore(&cm_id_priv->lock, flags);
44 spin_lock_irqsave(&cm.lock, flags);
45 - rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
46 + if (!RB_EMPTY_NODE(&cm_id_priv->sidr_id_node)) {
47 + rb_erase(&cm_id_priv->sidr_id_node, &cm.remote_sidr_table);
48 + RB_CLEAR_NODE(&cm_id_priv->sidr_id_node);
50 spin_unlock_irqrestore(&cm.lock, flags);