lkml.org 
[lkml]   [2016]   [Mar]   [1]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.4 285/342] qla2xxx: Fix stale pointer access.
    Date
    4.4-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Quinn Tran <quinn.tran@qlogic.com>

    commit cb43285ff7039fe3c4b0bc476e6d6569c31104f3 upstream.

    [ Upstream Commit 84e32a06f4f8756ce9ec3c8dc7e97896575f0771 ]

    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 <quinn.tran@qlogic.com>
    Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
    Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/scsi/qla2xxx/qla_init.c | 10 +++++-----
    drivers/scsi/qla2xxx/qla_isr.c | 4 ++--
    drivers/scsi/qla2xxx/qla_mid.c | 4 ++--
    drivers/scsi/qla2xxx/qla_os.c | 6 ++++++
    drivers/scsi/qla2xxx/qla_tmpl.c | 16 ++++++++++++++++
    5 files changed, 31 insertions(+), 9 deletions(-)

    --- a/drivers/scsi/qla2xxx/qla_init.c
    +++ b/drivers/scsi/qla2xxx/qla_init.c
    @@ -2192,7 +2192,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
    /* Clear outstanding commands array. */
    for (que = 0; que < ha->max_req_queues; que++) {
    req = ha->req_q_map[que];
    - if (!req)
    + if (!req || !test_bit(que, ha->req_qid_map))
    continue;
    req->out_ptr = (void *)(req->ring + req->length);
    *req->out_ptr = 0;
    @@ -2209,7 +2209,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)

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

    for (i = 1; i < ha->max_rsp_queues; i++) {
    rsp = ha->rsp_q_map[i];
    - if (rsp) {
    + if (rsp && test_bit(i, ha->rsp_qid_map)) {
    rsp->options &= ~BIT_0;
    ret = qla25xx_init_rsp_que(base_vha, rsp);
    if (ret != QLA_SUCCESS)
    @@ -4976,8 +4976,8 @@ qla25xx_init_queues(struct qla_hw_data *
    }
    for (i = 1; i < ha->max_req_queues; i++) {
    req = ha->req_q_map[i];
    - if (req) {
    - /* Clear outstanding commands array. */
    + if (req && test_bit(i, ha->req_qid_map)) {
    + /* Clear outstanding commands array. */
    req->options &= ~BIT_0;
    ret = qla25xx_init_req_que(base_vha, req);
    if (ret != QLA_SUCCESS)
    --- a/drivers/scsi/qla2xxx/qla_isr.c
    +++ b/drivers/scsi/qla2xxx/qla_isr.c
    @@ -3018,9 +3018,9 @@ qla24xx_enable_msix(struct qla_hw_data *
    "MSI-X: Failed to enable support "
    "-- %d/%d\n Retry with %d vectors.\n",
    ha->msix_count, ret, ret);
    + ha->msix_count = ret;
    + ha->max_rsp_queues = ha->msix_count - 1;
    }
    - ha->msix_count = ret;
    - ha->max_rsp_queues = ha->msix_count - 1;
    ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) *
    ha->msix_count, GFP_KERNEL);
    if (!ha->msix_entries) {
    --- a/drivers/scsi/qla2xxx/qla_mid.c
    +++ b/drivers/scsi/qla2xxx/qla_mid.c
    @@ -600,7 +600,7 @@ qla25xx_delete_queues(struct scsi_qla_ho
    /* Delete request queues */
    for (cnt = 1; cnt < ha->max_req_queues; cnt++) {
    req = ha->req_q_map[cnt];
    - if (req) {
    + if (req && test_bit(cnt, ha->req_qid_map)) {
    ret = qla25xx_delete_req_que(vha, req);
    if (ret != QLA_SUCCESS) {
    ql_log(ql_log_warn, vha, 0x00ea,
    @@ -614,7 +614,7 @@ qla25xx_delete_queues(struct scsi_qla_ho
    /* Delete response queues */
    for (cnt = 1; cnt < ha->max_rsp_queues; cnt++) {
    rsp = ha->rsp_q_map[cnt];
    - if (rsp) {
    + if (rsp && test_bit(cnt, ha->rsp_qid_map)) {
    ret = qla25xx_delete_rsp_que(vha, rsp);
    if (ret != QLA_SUCCESS) {
    ql_log(ql_log_warn, vha, 0x00eb,
    --- a/drivers/scsi/qla2xxx/qla_os.c
    +++ b/drivers/scsi/qla2xxx/qla_os.c
    @@ -397,6 +397,9 @@ static void qla2x00_free_queues(struct q
    int cnt;

    for (cnt = 0; cnt < ha->max_req_queues; cnt++) {
    + if (!test_bit(cnt, ha->req_qid_map))
    + continue;
    +
    req = ha->req_q_map[cnt];
    qla2x00_free_req_que(ha, req);
    }
    @@ -404,6 +407,9 @@ static void qla2x00_free_queues(struct q
    ha->req_q_map = NULL;

    for (cnt = 0; cnt < ha->max_rsp_queues; cnt++) {
    + if (!test_bit(cnt, ha->rsp_qid_map))
    + continue;
    +
    rsp = ha->rsp_q_map[cnt];
    qla2x00_free_rsp_que(ha, rsp);
    }
    --- a/drivers/scsi/qla2xxx/qla_tmpl.c
    +++ b/drivers/scsi/qla2xxx/qla_tmpl.c
    @@ -395,6 +395,10 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_
    if (ent->t263.queue_type == T263_QUEUE_TYPE_REQ) {
    for (i = 0; i < vha->hw->max_req_queues; i++) {
    struct req_que *req = vha->hw->req_q_map[i];
    +
    + if (!test_bit(i, vha->hw->req_qid_map))
    + continue;
    +
    if (req || !buf) {
    length = req ?
    req->length : REQUEST_ENTRY_CNT_24XX;
    @@ -408,6 +412,10 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_
    } else if (ent->t263.queue_type == T263_QUEUE_TYPE_RSP) {
    for (i = 0; i < vha->hw->max_rsp_queues; i++) {
    struct rsp_que *rsp = vha->hw->rsp_q_map[i];
    +
    + if (!test_bit(i, vha->hw->rsp_qid_map))
    + continue;
    +
    if (rsp || !buf) {
    length = rsp ?
    rsp->length : RESPONSE_ENTRY_CNT_MQ;
    @@ -634,6 +642,10 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_
    if (ent->t274.queue_type == T274_QUEUE_TYPE_REQ_SHAD) {
    for (i = 0; i < vha->hw->max_req_queues; i++) {
    struct req_que *req = vha->hw->req_q_map[i];
    +
    + if (!test_bit(i, vha->hw->req_qid_map))
    + continue;
    +
    if (req || !buf) {
    qla27xx_insert16(i, buf, len);
    qla27xx_insert16(1, buf, len);
    @@ -645,6 +657,10 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_
    } else if (ent->t274.queue_type == T274_QUEUE_TYPE_RSP_SHAD) {
    for (i = 0; i < vha->hw->max_rsp_queues; i++) {
    struct rsp_que *rsp = vha->hw->rsp_q_map[i];
    +
    + if (!test_bit(i, vha->hw->rsp_qid_map))
    + continue;
    +
    if (rsp || !buf) {
    qla27xx_insert16(i, buf, len);
    qla27xx_insert16(1, buf, len);
    \
     
     \ /
      Last update: 2016-03-02 02:01    [W:4.091 / U:0.652 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site