Skip to content

Commit 921d439

Browse files
Quinn Trangregkh
authored andcommitted
qla2xxx: Fix stale pointer access.
commit cb43285 upstream. [ Upstream Commit 84e32a0 ] Commit 84e32a0 ("qla2xxx: Use pci_enable_msix_range() instead of pci_enable_msix()") introduced a regression when target mode is enabled. In qla24xx_enable_msix(), ha->max_rsp_queues was incorrectly set to a value higher than the number of response queues allocated causing an invalid dereference. Specifically here in qla2x00_init_rings(): *rsp->in_ptr = 0; Add additional check to make sure the pointer is valid. following call stack will be seen ---- 8< ---- RIP: 0010:[<ffffffffa02ccadc>] [<ffffffffa02ccadc>] qla2x00_init_rings+0xdc/0x320 [qla2xxx] RSP: 0018:ffff880429447dd8 EFLAGS: 00010082 .... Call Trace: [<ffffffffa02ceb40>] qla2x00_abort_isp+0x170/0x6b0 [qla2xxx] [<ffffffffa02c6f77>] qla2x00_do_dpc+0x357/0x7f0 [qla2xxx] [<ffffffffa02c6c20>] ? qla2x00_relogin+0x260/0x260 [qla2xxx] [<ffffffff8107d2c9>] kthread+0xc9/0xe0 [<ffffffff8107d200>] ? flush_kthread_worker+0x90/0x90 [<ffffffff8172cc6f>] ret_from_fork+0x3f/0x70 [<ffffffff8107d200>] ? flush_kthread_worker+0x90/0x90 ---- 8< ---- Signed-off-by: Quinn Tran <[email protected]> Signed-off-by: Himanshu Madhani <[email protected]> Signed-off-by: Nicholas Bellinger <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 44c7d76 commit 921d439

File tree

5 files changed

+31
-9
lines changed

5 files changed

+31
-9
lines changed

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2192,7 +2192,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
21922192
/* Clear outstanding commands array. */
21932193
for (que = 0; que < ha->max_req_queues; que++) {
21942194
req = ha->req_q_map[que];
2195-
if (!req)
2195+
if (!req || !test_bit(que, ha->req_qid_map))
21962196
continue;
21972197
req->out_ptr = (void *)(req->ring + req->length);
21982198
*req->out_ptr = 0;
@@ -2209,7 +2209,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
22092209

22102210
for (que = 0; que < ha->max_rsp_queues; que++) {
22112211
rsp = ha->rsp_q_map[que];
2212-
if (!rsp)
2212+
if (!rsp || !test_bit(que, ha->rsp_qid_map))
22132213
continue;
22142214
rsp->in_ptr = (void *)(rsp->ring + rsp->length);
22152215
*rsp->in_ptr = 0;
@@ -4961,7 +4961,7 @@ qla25xx_init_queues(struct qla_hw_data *ha)
49614961

49624962
for (i = 1; i < ha->max_rsp_queues; i++) {
49634963
rsp = ha->rsp_q_map[i];
4964-
if (rsp) {
4964+
if (rsp && test_bit(i, ha->rsp_qid_map)) {
49654965
rsp->options &= ~BIT_0;
49664966
ret = qla25xx_init_rsp_que(base_vha, rsp);
49674967
if (ret != QLA_SUCCESS)
@@ -4976,8 +4976,8 @@ qla25xx_init_queues(struct qla_hw_data *ha)
49764976
}
49774977
for (i = 1; i < ha->max_req_queues; i++) {
49784978
req = ha->req_q_map[i];
4979-
if (req) {
4980-
/* Clear outstanding commands array. */
4979+
if (req && test_bit(i, ha->req_qid_map)) {
4980+
/* Clear outstanding commands array. */
49814981
req->options &= ~BIT_0;
49824982
ret = qla25xx_init_req_que(base_vha, req);
49834983
if (ret != QLA_SUCCESS)

drivers/scsi/qla2xxx/qla_isr.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3018,9 +3018,9 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
30183018
"MSI-X: Failed to enable support "
30193019
"-- %d/%d\n Retry with %d vectors.\n",
30203020
ha->msix_count, ret, ret);
3021+
ha->msix_count = ret;
3022+
ha->max_rsp_queues = ha->msix_count - 1;
30213023
}
3022-
ha->msix_count = ret;
3023-
ha->max_rsp_queues = ha->msix_count - 1;
30243024
ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) *
30253025
ha->msix_count, GFP_KERNEL);
30263026
if (!ha->msix_entries) {

drivers/scsi/qla2xxx/qla_mid.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@ qla25xx_delete_queues(struct scsi_qla_host *vha)
600600
/* Delete request queues */
601601
for (cnt = 1; cnt < ha->max_req_queues; cnt++) {
602602
req = ha->req_q_map[cnt];
603-
if (req) {
603+
if (req && test_bit(cnt, ha->req_qid_map)) {
604604
ret = qla25xx_delete_req_que(vha, req);
605605
if (ret != QLA_SUCCESS) {
606606
ql_log(ql_log_warn, vha, 0x00ea,
@@ -614,7 +614,7 @@ qla25xx_delete_queues(struct scsi_qla_host *vha)
614614
/* Delete response queues */
615615
for (cnt = 1; cnt < ha->max_rsp_queues; cnt++) {
616616
rsp = ha->rsp_q_map[cnt];
617-
if (rsp) {
617+
if (rsp && test_bit(cnt, ha->rsp_qid_map)) {
618618
ret = qla25xx_delete_rsp_que(vha, rsp);
619619
if (ret != QLA_SUCCESS) {
620620
ql_log(ql_log_warn, vha, 0x00eb,

drivers/scsi/qla2xxx/qla_os.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,13 +397,19 @@ static void qla2x00_free_queues(struct qla_hw_data *ha)
397397
int cnt;
398398

399399
for (cnt = 0; cnt < ha->max_req_queues; cnt++) {
400+
if (!test_bit(cnt, ha->req_qid_map))
401+
continue;
402+
400403
req = ha->req_q_map[cnt];
401404
qla2x00_free_req_que(ha, req);
402405
}
403406
kfree(ha->req_q_map);
404407
ha->req_q_map = NULL;
405408

406409
for (cnt = 0; cnt < ha->max_rsp_queues; cnt++) {
410+
if (!test_bit(cnt, ha->rsp_qid_map))
411+
continue;
412+
407413
rsp = ha->rsp_q_map[cnt];
408414
qla2x00_free_rsp_que(ha, rsp);
409415
}

drivers/scsi/qla2xxx/qla_tmpl.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,10 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
395395
if (ent->t263.queue_type == T263_QUEUE_TYPE_REQ) {
396396
for (i = 0; i < vha->hw->max_req_queues; i++) {
397397
struct req_que *req = vha->hw->req_q_map[i];
398+
399+
if (!test_bit(i, vha->hw->req_qid_map))
400+
continue;
401+
398402
if (req || !buf) {
399403
length = req ?
400404
req->length : REQUEST_ENTRY_CNT_24XX;
@@ -408,6 +412,10 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
408412
} else if (ent->t263.queue_type == T263_QUEUE_TYPE_RSP) {
409413
for (i = 0; i < vha->hw->max_rsp_queues; i++) {
410414
struct rsp_que *rsp = vha->hw->rsp_q_map[i];
415+
416+
if (!test_bit(i, vha->hw->rsp_qid_map))
417+
continue;
418+
411419
if (rsp || !buf) {
412420
length = rsp ?
413421
rsp->length : RESPONSE_ENTRY_CNT_MQ;
@@ -634,6 +642,10 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
634642
if (ent->t274.queue_type == T274_QUEUE_TYPE_REQ_SHAD) {
635643
for (i = 0; i < vha->hw->max_req_queues; i++) {
636644
struct req_que *req = vha->hw->req_q_map[i];
645+
646+
if (!test_bit(i, vha->hw->req_qid_map))
647+
continue;
648+
637649
if (req || !buf) {
638650
qla27xx_insert16(i, buf, len);
639651
qla27xx_insert16(1, buf, len);
@@ -645,6 +657,10 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
645657
} else if (ent->t274.queue_type == T274_QUEUE_TYPE_RSP_SHAD) {
646658
for (i = 0; i < vha->hw->max_rsp_queues; i++) {
647659
struct rsp_que *rsp = vha->hw->rsp_q_map[i];
660+
661+
if (!test_bit(i, vha->hw->rsp_qid_map))
662+
continue;
663+
648664
if (rsp || !buf) {
649665
qla27xx_insert16(i, buf, len);
650666
qla27xx_insert16(1, buf, len);

0 commit comments

Comments
 (0)