diff options
author | Jitendra Bhivare <jitendra.bhivare@broadcom.com> | 2017-10-10 13:48:15 +0300 |
---|---|---|
committer | Martin K. Petersen <martin.petersen@oracle.com> | 2017-10-11 21:18:29 +0300 |
commit | c5905bf82287a9aada3e4b0b1d3425c6e1a91828 (patch) | |
tree | 05ab69e30d23377ac4ad387968cabcc57d4992bd | |
parent | a39e9f71e5ed718256681f73740e866c8e572ec6 (diff) | |
download | linux-c5905bf82287a9aada3e4b0b1d3425c6e1a91828.tar.xz |
scsi: be2iscsi: Fix _get_initname buffer overflow
be_cmd_get_initname pulls GET_HBA_NAME response of 276 bytes in embedded
WRB buffer of 236 bytes.
Use non-embedded functions to issue the IOCTL.
Signed-off-by: Jitendra Bhivare <jitendra.bhivare@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 44 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 57 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.h | 2 |
4 files changed, 35 insertions, 70 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 22ddfe918cfd..4f1ac97d9921 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h @@ -793,8 +793,6 @@ int beiscsi_cmd_mccq_create(struct beiscsi_hba *phba, struct be_queue_info *mccq, struct be_queue_info *cq); -unsigned int be_cmd_get_initname(struct beiscsi_hba *phba); - void free_mcc_wrb(struct be_ctrl_info *ctrl, unsigned int tag); int beiscsi_modify_eq_delay(struct beiscsi_hba *phba, struct be_set_eqd *, diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index 43a80ce5ce6a..512c52aecb33 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c @@ -684,41 +684,6 @@ int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, } /** - * beiscsi_get_initname - Read Initiator Name from flash - * @buf: buffer bointer - * @phba: The device priv structure instance - * - * returns number of bytes - */ -static int beiscsi_get_initname(char *buf, struct beiscsi_hba *phba) -{ - int rc; - unsigned int tag; - struct be_mcc_wrb *wrb; - struct be_cmd_hba_name *resp; - - tag = be_cmd_get_initname(phba); - if (!tag) { - beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, - "BS_%d : Getting Initiator Name Failed\n"); - - return -EBUSY; - } - - rc = beiscsi_mccq_compl_wait(phba, tag, &wrb, NULL); - if (rc) { - beiscsi_log(phba, KERN_ERR, - BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, - "BS_%d : Initiator Name MBX Failed\n"); - return rc; - } - - resp = embedded_payload(wrb); - rc = sprintf(buf, "%s\n", resp->initiator_name); - return rc; -} - -/** * beiscsi_get_port_state - Get the Port State * @shost : pointer to scsi_host structure * @@ -772,7 +737,6 @@ static void beiscsi_get_port_speed(struct Scsi_Host *shost) * @param: parameter type identifier * @buf: buffer pointer * - * returns host parameter */ int beiscsi_get_host_param(struct Scsi_Host *shost, enum iscsi_host_param param, char *buf) @@ -783,7 +747,7 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, if (!beiscsi_hba_is_online(phba)) { beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, "BS_%d : HBA in error 0x%lx\n", phba->state); - return -EBUSY; + return 0; } beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG, "BS_%d : In beiscsi_get_host_param, param = %d\n", param); @@ -794,15 +758,15 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, if (status < 0) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, "BS_%d : beiscsi_get_macaddr Failed\n"); - return status; + return 0; } break; case ISCSI_HOST_PARAM_INITIATOR_NAME: - status = beiscsi_get_initname(buf, phba); + status = beiscsi_get_initiator_name(phba, buf); if (status < 0) { beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_CONFIG, "BS_%d : Retreiving Initiator Name Failed\n"); - return status; + return 0; } break; case ISCSI_HOST_PARAM_PORT_STATE: diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 2117ac08382a..0c25c105e44f 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c @@ -335,6 +335,35 @@ int beiscsi_modify_eq_delay(struct beiscsi_hba *phba, __beiscsi_eq_delay_compl, NULL, 0); } +/** + * beiscsi_get_initiator_name - read initiator name from flash + * @phba: device priv structure + * @name: buffer pointer + * + */ +int beiscsi_get_initiator_name(struct beiscsi_hba *phba, char *name) +{ + struct be_dma_mem nonemb_cmd; + struct be_cmd_hba_name resp; + int rc; + + rc = beiscsi_prep_nemb_cmd(phba, &nonemb_cmd, CMD_SUBSYSTEM_ISCSI_INI, + OPCODE_ISCSI_INI_CFG_GET_HBA_NAME, sizeof(resp)); + if (rc) + return rc; + + rc = beiscsi_exec_nemb_cmd(phba, &nonemb_cmd, NULL, + &resp, sizeof(resp)); + if (rc) { + beiscsi_log(phba, KERN_ERR, + BEISCSI_LOG_CONFIG | BEISCSI_LOG_MBOX, + "BS_%d : Initiator Name MBX Failed\n"); + return rc; + } + rc = sprintf(name, "%s\n", resp.initiator_name); + return rc; +} + unsigned int beiscsi_if_get_handle(struct beiscsi_hba *phba) { struct be_ctrl_info *ctrl = &phba->ctrl; @@ -763,34 +792,6 @@ int mgmt_get_nic_conf(struct beiscsi_hba *phba, nic, sizeof(*nic)); } - - -unsigned int be_cmd_get_initname(struct beiscsi_hba *phba) -{ - unsigned int tag; - struct be_mcc_wrb *wrb; - struct be_cmd_hba_name *req; - struct be_ctrl_info *ctrl = &phba->ctrl; - - if (mutex_lock_interruptible(&ctrl->mbox_lock)) - return 0; - wrb = alloc_mcc_wrb(phba, &tag); - if (!wrb) { - mutex_unlock(&ctrl->mbox_lock); - return 0; - } - - req = embedded_payload(wrb); - be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); - be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, - OPCODE_ISCSI_INI_CFG_GET_HBA_NAME, - sizeof(*req)); - - be_mcc_notify(phba, tag); - mutex_unlock(&ctrl->mbox_lock); - return tag; -} - static void beiscsi_boot_process_compl(struct beiscsi_hba *phba, unsigned int tag) { diff --git a/drivers/scsi/be2iscsi/be_mgmt.h b/drivers/scsi/be2iscsi/be_mgmt.h index 06ddc5ad6874..665fd893509f 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.h +++ b/drivers/scsi/be2iscsi/be_mgmt.h @@ -178,6 +178,8 @@ int beiscsi_mgmt_invalidate_icds(struct beiscsi_hba *phba, struct invldt_cmd_tbl *inv_tbl, unsigned int nents); +int beiscsi_get_initiator_name(struct beiscsi_hba *phba, char *name); + int beiscsi_if_en_dhcp(struct beiscsi_hba *phba, u32 ip_type); int beiscsi_if_en_static(struct beiscsi_hba *phba, u32 ip_type, |