aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2010-07-21 19:36:52 -0400
committerRoland Dreier <rolandd@cisco.com>2010-07-28 18:18:24 -0400
commit50a025c69ee749d822c301f9bf63dee13c113680 (patch)
tree132eccb57ef6c10cc96e50a3b53306d6e84887a1 /drivers/infiniband
parentf400e5b38a5eeb8a91b481e4f3059611fa4ddce2 (diff)
IB/cm: Check LAP state before sending an MRA
NULL pointer dereferences in ib_cm_init_qp_attr() were seen by some users. From a crash dump, I determined that we died in cm_init_qp_rts_attr() (it's inlined, so it doesn't show up in the traceback) on the line labeled below: static int cm_init_qp_rts_attr(struct cm_id_private *cm_id_priv, struct ib_qp_attr *qp_attr, int *qp_attr_mask) { ........ if (cm_id_priv->id.lap_state == IB_CM_LAP_UNINIT) { ..... } else { *qp_attr_mask = IB_QP_ALT_PATH | IB_QP_PATH_MIG_STATE; qp_attr->alt_port_num = cm_id_priv->alt_av.port->port_num; <-die The problem is that the rdma_cm can call ib_send_cm_mra() after a connection has been established. The ib_cm incorrectly assumes that the MRA is in response to a LAP (load alternate path) message, even though no LAP message has been received. The ib_cm needs to check the lap_state before sending an MRA if the cm_id state is established. Reported-by: Arthur Kepner <akepner@sgi.com> Reported-by: Josh England <jjengla@gmail.com> Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/cm.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index ad63b79afac1..64e0903091a8 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -2409,10 +2409,12 @@ int ib_send_cm_mra(struct ib_cm_id *cm_id,
2409 msg_response = CM_MSG_RESPONSE_REP; 2409 msg_response = CM_MSG_RESPONSE_REP;
2410 break; 2410 break;
2411 case IB_CM_ESTABLISHED: 2411 case IB_CM_ESTABLISHED:
2412 cm_state = cm_id->state; 2412 if (cm_id->lap_state == IB_CM_LAP_RCVD) {
2413 lap_state = IB_CM_MRA_LAP_SENT; 2413 cm_state = cm_id->state;
2414 msg_response = CM_MSG_RESPONSE_OTHER; 2414 lap_state = IB_CM_MRA_LAP_SENT;
2415 break; 2415 msg_response = CM_MSG_RESPONSE_OTHER;
2416 break;
2417 }
2416 default: 2418 default:
2417 ret = -EINVAL; 2419 ret = -EINVAL;
2418 goto error1; 2420 goto error1;