diff options
author | Mike Christie <michaelc@cs.wisc.edu> | 2011-02-16 16:04:39 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2011-02-24 12:41:20 -0500 |
commit | d8585bcd7da071f4278710f1c39e18dfe7cb0280 (patch) | |
tree | af56e750b3c09be817e9238f4507a4e59e4b0fc8 /drivers | |
parent | c71b9b669e1243623f7ed4332877d3f2beafc6ab (diff) |
[SCSI] bnx2i: fix null ptr ref in conn get param
bnx2i has some checks to try and make sure the ep
is not destroyed while the addr/port is getting
read. However, if after this check:
if (!(bnx2i_conn && bnx2i_conn->ep && bnx2i_conn->ep->hba))
goto out;
bnx2i_conn->ep is cleared by ep_disconnect then we will
oops.
This patches fixes the problem by having the driver
use the get_ep_param callback instead of get_conn_param.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/bnx2i/bnx2i_iscsi.c | 45 |
1 files changed, 22 insertions, 23 deletions
diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 05bb8086069a..1809f9ccc4ce 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c | |||
@@ -1458,42 +1458,40 @@ static void bnx2i_conn_destroy(struct iscsi_cls_conn *cls_conn) | |||
1458 | 1458 | ||
1459 | 1459 | ||
1460 | /** | 1460 | /** |
1461 | * bnx2i_conn_get_param - return iscsi connection parameter to caller | 1461 | * bnx2i_ep_get_param - return iscsi ep parameter to caller |
1462 | * @cls_conn: pointer to iscsi cls conn | 1462 | * @ep: pointer to iscsi endpoint |
1463 | * @param: parameter type identifier | 1463 | * @param: parameter type identifier |
1464 | * @buf: buffer pointer | 1464 | * @buf: buffer pointer |
1465 | * | 1465 | * |
1466 | * returns iSCSI connection parameters | 1466 | * returns iSCSI ep parameters |
1467 | */ | 1467 | */ |
1468 | static int bnx2i_conn_get_param(struct iscsi_cls_conn *cls_conn, | 1468 | static int bnx2i_ep_get_param(struct iscsi_endpoint *ep, |
1469 | enum iscsi_param param, char *buf) | 1469 | enum iscsi_param param, char *buf) |
1470 | { | 1470 | { |
1471 | struct iscsi_conn *conn = cls_conn->dd_data; | 1471 | struct bnx2i_endpoint *bnx2i_ep = ep->dd_data; |
1472 | struct bnx2i_conn *bnx2i_conn = conn->dd_data; | 1472 | struct bnx2i_hba *hba = bnx2i_ep->hba; |
1473 | int len = 0; | 1473 | int len = -ENOTCONN; |
1474 | 1474 | ||
1475 | if (!(bnx2i_conn && bnx2i_conn->ep && bnx2i_conn->ep->hba)) | 1475 | if (!hba) |
1476 | goto out; | 1476 | return -ENOTCONN; |
1477 | 1477 | ||
1478 | switch (param) { | 1478 | switch (param) { |
1479 | case ISCSI_PARAM_CONN_PORT: | 1479 | case ISCSI_PARAM_CONN_PORT: |
1480 | mutex_lock(&bnx2i_conn->ep->hba->net_dev_lock); | 1480 | mutex_lock(&hba->net_dev_lock); |
1481 | if (bnx2i_conn->ep->cm_sk) | 1481 | if (bnx2i_ep->cm_sk) |
1482 | len = sprintf(buf, "%hu\n", | 1482 | len = sprintf(buf, "%hu\n", bnx2i_ep->cm_sk->dst_port); |
1483 | bnx2i_conn->ep->cm_sk->dst_port); | 1483 | mutex_unlock(&hba->net_dev_lock); |
1484 | mutex_unlock(&bnx2i_conn->ep->hba->net_dev_lock); | ||
1485 | break; | 1484 | break; |
1486 | case ISCSI_PARAM_CONN_ADDRESS: | 1485 | case ISCSI_PARAM_CONN_ADDRESS: |
1487 | mutex_lock(&bnx2i_conn->ep->hba->net_dev_lock); | 1486 | mutex_lock(&hba->net_dev_lock); |
1488 | if (bnx2i_conn->ep->cm_sk) | 1487 | if (bnx2i_ep->cm_sk) |
1489 | len = sprintf(buf, "%pI4\n", | 1488 | len = sprintf(buf, "%pI4\n", &bnx2i_ep->cm_sk->dst_ip); |
1490 | &bnx2i_conn->ep->cm_sk->dst_ip); | 1489 | mutex_unlock(&hba->net_dev_lock); |
1491 | mutex_unlock(&bnx2i_conn->ep->hba->net_dev_lock); | ||
1492 | break; | 1490 | break; |
1493 | default: | 1491 | default: |
1494 | return iscsi_conn_get_param(cls_conn, param, buf); | 1492 | return -ENOSYS; |
1495 | } | 1493 | } |
1496 | out: | 1494 | |
1497 | return len; | 1495 | return len; |
1498 | } | 1496 | } |
1499 | 1497 | ||
@@ -2204,7 +2202,7 @@ struct iscsi_transport bnx2i_iscsi_transport = { | |||
2204 | .bind_conn = bnx2i_conn_bind, | 2202 | .bind_conn = bnx2i_conn_bind, |
2205 | .destroy_conn = bnx2i_conn_destroy, | 2203 | .destroy_conn = bnx2i_conn_destroy, |
2206 | .set_param = iscsi_set_param, | 2204 | .set_param = iscsi_set_param, |
2207 | .get_conn_param = bnx2i_conn_get_param, | 2205 | .get_conn_param = iscsi_conn_get_param, |
2208 | .get_session_param = iscsi_session_get_param, | 2206 | .get_session_param = iscsi_session_get_param, |
2209 | .get_host_param = bnx2i_host_get_param, | 2207 | .get_host_param = bnx2i_host_get_param, |
2210 | .start_conn = bnx2i_conn_start, | 2208 | .start_conn = bnx2i_conn_start, |
@@ -2213,6 +2211,7 @@ struct iscsi_transport bnx2i_iscsi_transport = { | |||
2213 | .xmit_task = bnx2i_task_xmit, | 2211 | .xmit_task = bnx2i_task_xmit, |
2214 | .get_stats = bnx2i_conn_get_stats, | 2212 | .get_stats = bnx2i_conn_get_stats, |
2215 | /* TCP connect - disconnect - option-2 interface calls */ | 2213 | /* TCP connect - disconnect - option-2 interface calls */ |
2214 | .get_ep_param = bnx2i_ep_get_param, | ||
2216 | .ep_connect = bnx2i_ep_connect, | 2215 | .ep_connect = bnx2i_ep_connect, |
2217 | .ep_poll = bnx2i_ep_poll, | 2216 | .ep_poll = bnx2i_ep_poll, |
2218 | .ep_disconnect = bnx2i_ep_disconnect, | 2217 | .ep_disconnect = bnx2i_ep_disconnect, |