There is a potential race in ib_register_mad_agent() where the struct
ib_mad_agent_private is not fully initialized before it is added
to the list of agents per IB port. This means the ib_mad_agent_private
could be seen before the refcount, spin locks, and linked lists
are initialized.  The fix is to initialize the structure earlier.

Signed-off-by: Ralph Campbell <[email protected]>

diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 735ad4e..dbcd285 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -301,6 +301,16 @@ struct ib_mad_agent *ib_register_mad_agent(struct 
ib_device *device,
        mad_agent_priv->agent.context = context;
        mad_agent_priv->agent.qp = port_priv->qp_info[qpn].qp;
        mad_agent_priv->agent.port_num = port_num;
+       spin_lock_init(&mad_agent_priv->lock);
+       INIT_LIST_HEAD(&mad_agent_priv->send_list);
+       INIT_LIST_HEAD(&mad_agent_priv->wait_list);
+       INIT_LIST_HEAD(&mad_agent_priv->done_list);
+       INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
+       INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
+       INIT_LIST_HEAD(&mad_agent_priv->local_list);
+       INIT_WORK(&mad_agent_priv->local_work, local_completions);
+       atomic_set(&mad_agent_priv->refcount, 1);
+       init_completion(&mad_agent_priv->comp);
 
        spin_lock_irqsave(&port_priv->reg_lock, flags);
        mad_agent_priv->agent.hi_tid = ++ib_mad_client_id;
@@ -350,17 +360,6 @@ struct ib_mad_agent *ib_register_mad_agent(struct 
ib_device *device,
        list_add_tail(&mad_agent_priv->agent_list, &port_priv->agent_list);
        spin_unlock_irqrestore(&port_priv->reg_lock, flags);
 
-       spin_lock_init(&mad_agent_priv->lock);
-       INIT_LIST_HEAD(&mad_agent_priv->send_list);
-       INIT_LIST_HEAD(&mad_agent_priv->wait_list);
-       INIT_LIST_HEAD(&mad_agent_priv->done_list);
-       INIT_LIST_HEAD(&mad_agent_priv->rmpp_list);
-       INIT_DELAYED_WORK(&mad_agent_priv->timed_work, timeout_sends);
-       INIT_LIST_HEAD(&mad_agent_priv->local_list);
-       INIT_WORK(&mad_agent_priv->local_work, local_completions);
-       atomic_set(&mad_agent_priv->refcount, 1);
-       init_completion(&mad_agent_priv->comp);
-
        return &mad_agent_priv->agent;
 
 error4:


_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to