lkml.org 
[lkml]   [2020]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.9 714/757] scsi: qla2xxx: Warn if done() or free() are called on an already freed srb
    Date
    From: Daniel Wagner <dwagner@suse.de>

    [ Upstream commit c0014f94218ea3a312f6235febea0d626c5f2154 ]

    Emit a warning when ->done or ->free are called on an already freed
    srb. There is a hidden use-after-free bug in the driver which corrupts
    the srb memory pool which originates from the cleanup callbacks.

    An extensive search didn't bring any lights on the real problem. The
    initial fix was to set both pointers to NULL and try to catch invalid
    accesses. But instead the memory corruption was gone and the driver
    didn't crash. Since not all calling places check for NULL pointer, add
    explicitly default handlers. With this we workaround the memory
    corruption and add a debug help.

    Link: https://lore.kernel.org/r/20200908081516.8561-2-dwagner@suse.de
    Reviewed-by: Martin Wilck <mwilck@suse.com>
    Reviewed-by: Arun Easi <aeasi@marvell.com>
    Signed-off-by: Daniel Wagner <dwagner@suse.de>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/scsi/qla2xxx/qla_init.c | 10 ++++++++++
    drivers/scsi/qla2xxx/qla_inline.h | 5 +++++
    2 files changed, 15 insertions(+)

    diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
    index 0bd04a62af836..8d4b651e14422 100644
    --- a/drivers/scsi/qla2xxx/qla_init.c
    +++ b/drivers/scsi/qla2xxx/qla_init.c
    @@ -63,6 +63,16 @@ void qla2x00_sp_free(srb_t *sp)
    qla2x00_rel_sp(sp);
    }

    +void qla2xxx_rel_done_warning(srb_t *sp, int res)
    +{
    + WARN_ONCE(1, "Calling done() of an already freed srb %p object\n", sp);
    +}
    +
    +void qla2xxx_rel_free_warning(srb_t *sp)
    +{
    + WARN_ONCE(1, "Calling free() of an already freed srb %p object\n", sp);
    +}
    +
    /* Asynchronous Login/Logout Routines -------------------------------------- */

    unsigned long
    diff --git a/drivers/scsi/qla2xxx/qla_inline.h b/drivers/scsi/qla2xxx/qla_inline.h
    index 861dc522723ce..2aa6f81f87c43 100644
    --- a/drivers/scsi/qla2xxx/qla_inline.h
    +++ b/drivers/scsi/qla2xxx/qla_inline.h
    @@ -207,10 +207,15 @@ qla2xxx_get_qpair_sp(scsi_qla_host_t *vha, struct qla_qpair *qpair,
    return sp;
    }

    +void qla2xxx_rel_done_warning(srb_t *sp, int res);
    +void qla2xxx_rel_free_warning(srb_t *sp);
    +
    static inline void
    qla2xxx_rel_qpair_sp(struct qla_qpair *qpair, srb_t *sp)
    {
    sp->qpair = NULL;
    + sp->done = qla2xxx_rel_done_warning;
    + sp->free = qla2xxx_rel_free_warning;
    mempool_free(sp, qpair->srb_mempool);
    QLA_QPAIR_MARK_NOT_BUSY(qpair);
    }
    --
    2.25.1


    \
     
     \ /
      Last update: 2020-10-27 17:40    [W:3.037 / U:0.068 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site