scsi: qla2xxx: Check the PCI info string output buffer size
authorBart Van Assche <bvanassche@acm.org>
Fri, 9 Aug 2019 03:01:55 +0000 (20:01 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Tue, 13 Aug 2019 01:34:07 +0000 (21:34 -0400)
Pass the output buffer size to the code that generates a PCI info string
and check the output buffer size while generating a PCI info string.

Cc: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Bart Van Assche <bvanassche@acm.org>
Tested-by: Himanshu Madhani <hmadhani@marvell.com>
Reviewed-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_attr.c
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_gbl.h
drivers/scsi/qla2xxx/qla_mr.c
drivers/scsi/qla2xxx/qla_os.c

index e3de209..e9c449e 100644 (file)
@@ -1125,7 +1125,8 @@ qla2x00_pci_info_show(struct device *dev, struct device_attribute *attr,
        char pci_info[30];
 
        return scnprintf(buf, PAGE_SIZE, "%s\n",
-           vha->hw->isp_ops->pci_info_str(vha, pci_info));
+                        vha->hw->isp_ops->pci_info_str(vha, pci_info,
+                                                       sizeof(pci_info)));
 }
 
 static ssize_t
index 1c6811b..8c8279e 100644 (file)
@@ -3112,7 +3112,7 @@ struct isp_operations {
        void (*update_fw_options) (struct scsi_qla_host *);
        int (*load_risc) (struct scsi_qla_host *, uint32_t *);
 
-       char * (*pci_info_str) (struct scsi_qla_host *, char *);
+       char * (*pci_info_str)(struct scsi_qla_host *, char *, size_t);
        char * (*fw_version_str)(struct scsi_qla_host *, char *, size_t);
 
        irq_handler_t intr_handler;
index fc54e7c..2d96640 100644 (file)
@@ -732,7 +732,7 @@ extern int qlafx00_initialize_adapter(struct scsi_qla_host *);
 extern int qlafx00_soft_reset(scsi_qla_host_t *);
 extern int qlafx00_chip_diag(scsi_qla_host_t *);
 extern void qlafx00_config_rings(struct scsi_qla_host *);
-extern char *qlafx00_pci_info_str(struct scsi_qla_host *, char *);
+extern char *qlafx00_pci_info_str(struct scsi_qla_host *, char *, size_t);
 extern char *qlafx00_fw_version_str(struct scsi_qla_host *, char *, size_t);
 extern irqreturn_t qlafx00_intr_handler(int, void *);
 extern void qlafx00_enable_intrs(struct qla_hw_data *);
index 9e3f2f4..759fcfe 100644 (file)
@@ -688,14 +688,12 @@ qlafx00_config_rings(struct scsi_qla_host *vha)
 }
 
 char *
-qlafx00_pci_info_str(struct scsi_qla_host *vha, char *str)
+qlafx00_pci_info_str(struct scsi_qla_host *vha, char *str, size_t str_len)
 {
        struct qla_hw_data *ha = vha->hw;
 
-       if (pci_is_pcie(ha->pdev)) {
-               strcpy(str, "PCIe iSA");
-               return str;
-       }
+       if (pci_is_pcie(ha->pdev))
+               strlcpy(str, "PCIe iSA", str_len);
        return str;
 }
 
index e91681c..a247dce 100644 (file)
@@ -536,80 +536,70 @@ static void qla2x00_free_queues(struct qla_hw_data *ha)
 }
 
 static char *
-qla2x00_pci_info_str(struct scsi_qla_host *vha, char *str)
+qla2x00_pci_info_str(struct scsi_qla_host *vha, char *str, size_t str_len)
 {
        struct qla_hw_data *ha = vha->hw;
-       static char *pci_bus_modes[] = {
+       static const char *const pci_bus_modes[] = {
                "33", "66", "100", "133",
        };
        uint16_t pci_bus;
 
-       strcpy(str, "PCI");
        pci_bus = (ha->pci_attr & (BIT_9 | BIT_10)) >> 9;
        if (pci_bus) {
-               strcat(str, "-X (");
-               strcat(str, pci_bus_modes[pci_bus]);
+               snprintf(str, str_len, "PCI-X (%s MHz)",
+                        pci_bus_modes[pci_bus]);
        } else {
                pci_bus = (ha->pci_attr & BIT_8) >> 8;
-               strcat(str, " (");
-               strcat(str, pci_bus_modes[pci_bus]);
+               snprintf(str, str_len, "PCI (%s MHz)", pci_bus_modes[pci_bus]);
        }
-       strcat(str, " MHz)");
 
-       return (str);
+       return str;
 }
 
 static char *
-qla24xx_pci_info_str(struct scsi_qla_host *vha, char *str)
+qla24xx_pci_info_str(struct scsi_qla_host *vha, char *str, size_t str_len)
 {
-       static char *pci_bus_modes[] = { "33", "66", "100", "133", };
+       static const char *const pci_bus_modes[] = {
+               "33", "66", "100", "133",
+       };
        struct qla_hw_data *ha = vha->hw;
        uint32_t pci_bus;
 
        if (pci_is_pcie(ha->pdev)) {
-               char lwstr[6];
                uint32_t lstat, lspeed, lwidth;
+               const char *speed_str;
 
                pcie_capability_read_dword(ha->pdev, PCI_EXP_LNKCAP, &lstat);
                lspeed = lstat & PCI_EXP_LNKCAP_SLS;
                lwidth = (lstat & PCI_EXP_LNKCAP_MLW) >> 4;
 
-               strcpy(str, "PCIe (");
                switch (lspeed) {
                case 1:
-                       strcat(str, "2.5GT/s ");
+                       speed_str = "2.5GT/s";
                        break;
                case 2:
-                       strcat(str, "5.0GT/s ");
+                       speed_str = "5.0GT/s";
                        break;
                case 3:
-                       strcat(str, "8.0GT/s ");
+                       speed_str = "8.0GT/s";
                        break;
                default:
-                       strcat(str, "<unknown> ");
+                       speed_str = "<unknown>";
                        break;
                }
-               snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth);
-               strcat(str, lwstr);
+               snprintf(str, str_len, "PCIe (%s x%d)", speed_str, lwidth);
 
                return str;
        }
 
-       strcpy(str, "PCI");
        pci_bus = (ha->pci_attr & CSRX_PCIX_BUS_MODE_MASK) >> 8;
-       if (pci_bus == 0 || pci_bus == 8) {
-               strcat(str, " (");
-               strcat(str, pci_bus_modes[pci_bus >> 3]);
-       } else {
-               strcat(str, "-X ");
-               if (pci_bus & BIT_2)
-                       strcat(str, "Mode 2");
-               else
-                       strcat(str, "Mode 1");
-               strcat(str, " (");
-               strcat(str, pci_bus_modes[pci_bus & ~BIT_2]);
-       }
-       strcat(str, " MHz)");
+       if (pci_bus == 0 || pci_bus == 8)
+               snprintf(str, str_len, "PCI (%s MHz)",
+                        pci_bus_modes[pci_bus >> 3]);
+       else
+               snprintf(str, str_len, "PCI-X Mode %d (%s MHz)",
+                        pci_bus & 4 ? 2 : 1,
+                        pci_bus_modes[pci_bus & 3]);
 
        return str;
 }
@@ -3460,7 +3450,8 @@ skip_dpc:
            "QLogic %s - %s.\n", ha->model_number, ha->model_desc);
        ql_log(ql_log_info, base_vha, 0x00fc,
            "ISP%04X: %s @ %s hdma%c host#=%ld fw=%s.\n",
-           pdev->device, ha->isp_ops->pci_info_str(base_vha, pci_info),
+           pdev->device, ha->isp_ops->pci_info_str(base_vha, pci_info,
+                                                      sizeof(pci_info)),
            pci_name(pdev), ha->flags.enable_64bit_addressing ? '+' : '-',
            base_vha->host_no,
            ha->isp_ops->fw_version_str(base_vha, fw_str, sizeof(fw_str)));