diff options
author | James Smart <james.smart@emulex.com> | 2014-02-20 09:57:18 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2014-03-15 13:18:57 -0400 |
commit | 76fd07a632483c85ea24f383f02b92fabf468434 (patch) | |
tree | 33cba976b54c2ac9af47f65284075f49fa1546e6 /drivers/scsi/lpfc | |
parent | 6ff8556d5f86681c164fc9d05e617e160f79f264 (diff) |
[SCSI] lpfc 8.3.45: Fix sysfs buffer overrun in read of lpfc_fcp_cpu_map for 128 CPUs.
Signed-off-by: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 28 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_sli4.h | 1 |
3 files changed, 25 insertions, 6 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index ba8b77aa554d..8d5b6ceec9c9 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c | |||
@@ -4288,7 +4288,7 @@ lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr, | |||
4288 | struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; | 4288 | struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; |
4289 | struct lpfc_hba *phba = vport->phba; | 4289 | struct lpfc_hba *phba = vport->phba; |
4290 | struct lpfc_vector_map_info *cpup; | 4290 | struct lpfc_vector_map_info *cpup; |
4291 | int idx, len = 0; | 4291 | int len = 0; |
4292 | 4292 | ||
4293 | if ((phba->sli_rev != LPFC_SLI_REV4) || | 4293 | if ((phba->sli_rev != LPFC_SLI_REV4) || |
4294 | (phba->intr_type != MSIX)) | 4294 | (phba->intr_type != MSIX)) |
@@ -4316,23 +4316,39 @@ lpfc_fcp_cpu_map_show(struct device *dev, struct device_attribute *attr, | |||
4316 | break; | 4316 | break; |
4317 | } | 4317 | } |
4318 | 4318 | ||
4319 | cpup = phba->sli4_hba.cpu_map; | 4319 | while (phba->sli4_hba.curr_disp_cpu < phba->sli4_hba.num_present_cpu) { |
4320 | for (idx = 0; idx < phba->sli4_hba.num_present_cpu; idx++) { | 4320 | cpup = &phba->sli4_hba.cpu_map[phba->sli4_hba.curr_disp_cpu]; |
4321 | |||
4322 | /* margin should fit in this and the truncated message */ | ||
4321 | if (cpup->irq == LPFC_VECTOR_MAP_EMPTY) | 4323 | if (cpup->irq == LPFC_VECTOR_MAP_EMPTY) |
4322 | len += snprintf(buf + len, PAGE_SIZE-len, | 4324 | len += snprintf(buf + len, PAGE_SIZE-len, |
4323 | "CPU %02d io_chan %02d " | 4325 | "CPU %02d io_chan %02d " |
4324 | "physid %d coreid %d\n", | 4326 | "physid %d coreid %d\n", |
4325 | idx, cpup->channel_id, cpup->phys_id, | 4327 | phba->sli4_hba.curr_disp_cpu, |
4328 | cpup->channel_id, cpup->phys_id, | ||
4326 | cpup->core_id); | 4329 | cpup->core_id); |
4327 | else | 4330 | else |
4328 | len += snprintf(buf + len, PAGE_SIZE-len, | 4331 | len += snprintf(buf + len, PAGE_SIZE-len, |
4329 | "CPU %02d io_chan %02d " | 4332 | "CPU %02d io_chan %02d " |
4330 | "physid %d coreid %d IRQ %d\n", | 4333 | "physid %d coreid %d IRQ %d\n", |
4331 | idx, cpup->channel_id, cpup->phys_id, | 4334 | phba->sli4_hba.curr_disp_cpu, |
4335 | cpup->channel_id, cpup->phys_id, | ||
4332 | cpup->core_id, cpup->irq); | 4336 | cpup->core_id, cpup->irq); |
4333 | 4337 | ||
4334 | cpup++; | 4338 | phba->sli4_hba.curr_disp_cpu++; |
4339 | |||
4340 | /* display max number of CPUs keeping some margin */ | ||
4341 | if (phba->sli4_hba.curr_disp_cpu < | ||
4342 | phba->sli4_hba.num_present_cpu && | ||
4343 | (len >= (PAGE_SIZE - 64))) { | ||
4344 | len += snprintf(buf + len, PAGE_SIZE-len, "more...\n"); | ||
4345 | break; | ||
4346 | } | ||
4335 | } | 4347 | } |
4348 | |||
4349 | if (phba->sli4_hba.curr_disp_cpu == phba->sli4_hba.num_present_cpu) | ||
4350 | phba->sli4_hba.curr_disp_cpu = 0; | ||
4351 | |||
4336 | return len; | 4352 | return len; |
4337 | } | 4353 | } |
4338 | 4354 | ||
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 157ad1ceceae..f31a36827512 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -5280,6 +5280,7 @@ lpfc_sli4_driver_resource_unset(struct lpfc_hba *phba) | |||
5280 | kfree(phba->sli4_hba.cpu_map); | 5280 | kfree(phba->sli4_hba.cpu_map); |
5281 | phba->sli4_hba.num_present_cpu = 0; | 5281 | phba->sli4_hba.num_present_cpu = 0; |
5282 | phba->sli4_hba.num_online_cpu = 0; | 5282 | phba->sli4_hba.num_online_cpu = 0; |
5283 | phba->sli4_hba.curr_disp_cpu = 0; | ||
5283 | 5284 | ||
5284 | /* Free memory allocated for msi-x interrupt vector entries */ | 5285 | /* Free memory allocated for msi-x interrupt vector entries */ |
5285 | kfree(phba->sli4_hba.msix_entries); | 5286 | kfree(phba->sli4_hba.msix_entries); |
@@ -6850,6 +6851,7 @@ lpfc_sli4_queue_verify(struct lpfc_hba *phba) | |||
6850 | } | 6851 | } |
6851 | phba->sli4_hba.num_online_cpu = i; | 6852 | phba->sli4_hba.num_online_cpu = i; |
6852 | phba->sli4_hba.num_present_cpu = lpfc_present_cpu; | 6853 | phba->sli4_hba.num_present_cpu = lpfc_present_cpu; |
6854 | phba->sli4_hba.curr_disp_cpu = 0; | ||
6853 | 6855 | ||
6854 | if (i < cfg_fcp_io_channel) { | 6856 | if (i < cfg_fcp_io_channel) { |
6855 | lpfc_printf_log(phba, | 6857 | lpfc_printf_log(phba, |
diff --git a/drivers/scsi/lpfc/lpfc_sli4.h b/drivers/scsi/lpfc/lpfc_sli4.h index e43259075e92..9b8cda866176 100644 --- a/drivers/scsi/lpfc/lpfc_sli4.h +++ b/drivers/scsi/lpfc/lpfc_sli4.h | |||
@@ -607,6 +607,7 @@ struct lpfc_sli4_hba { | |||
607 | struct lpfc_vector_map_info *cpu_map; | 607 | struct lpfc_vector_map_info *cpu_map; |
608 | uint16_t num_online_cpu; | 608 | uint16_t num_online_cpu; |
609 | uint16_t num_present_cpu; | 609 | uint16_t num_present_cpu; |
610 | uint16_t curr_disp_cpu; | ||
610 | }; | 611 | }; |
611 | 612 | ||
612 | enum lpfc_sge_type { | 613 | enum lpfc_sge_type { |