IB/iser: Fix possible NULL derefernce ib_conn->device in session_create
authorAriel Nahum <arieln@mellanox.com>
Sun, 7 Dec 2014 14:09:58 +0000 (16:09 +0200)
committerRoland Dreier <roland@purestorage.com>
Tue, 16 Dec 2014 02:11:44 +0000 (18:11 -0800)
If rdma_cm error event comes after ep_poll but before conn_bind, we
should protect against dereferncing the device (which may have been
terminated) in session_create and conn_create (already protected)
callbacks.

Signed-off-by: Ariel Nahum <arieln@mellanox.com>
Signed-off-by: Sagi Grimberg <sagig@mellanox.com>
Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
drivers/infiniband/ulp/iser/iscsi_iser.c

index 46028151a904f2aa07e21ceeec38064c70bde077..cc7b84a235c82445cbf924e0ebfe4f696e302d1c 100644 (file)
@@ -588,6 +588,15 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
        if (ep) {
                iser_conn = ep->dd_data;
                max_cmds = iser_conn->max_cmds;
+
+               mutex_lock(&iser_conn->state_mutex);
+               if (iser_conn->state != ISER_CONN_UP) {
+                       iser_err("iser conn %p already started teardown\n",
+                                iser_conn);
+                       mutex_unlock(&iser_conn->state_mutex);
+                       goto free_host;
+               }
+
                ib_conn = &iser_conn->ib_conn;
                if (ib_conn->pi_support) {
                        u32 sig_caps = ib_conn->device->dev_attr.sig_prot_cap;
@@ -598,14 +607,19 @@ iscsi_iser_session_create(struct iscsi_endpoint *ep,
                        else
                                scsi_host_set_guard(shost, SHOST_DIX_GUARD_CRC);
                }
+
+               if (iscsi_host_add(shost,
+                                  ib_conn->device->ib_device->dma_device)) {
+                       mutex_unlock(&iser_conn->state_mutex);
+                       goto free_host;
+               }
+               mutex_unlock(&iser_conn->state_mutex);
        } else {
                max_cmds = ISER_DEF_XMIT_CMDS_MAX;
+               if (iscsi_host_add(shost, NULL))
+                       goto free_host;
        }
 
-       if (iscsi_host_add(shost, ep ?
-                          ib_conn->device->ib_device->dma_device : NULL))
-               goto free_host;
-
        if (cmds_max > max_cmds) {
                iser_info("cmds_max changed from %u to %u\n",
                          cmds_max, max_cmds);