lkml.org 
[lkml]   [2022]   [Sep]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 37/40] s390/dasd: fix Oops in dasd_alias_get_start_dev due to missing pavgroup
    Date
    From: Stefan Haberland <sth@linux.ibm.com>

    commit db7ba07108a48c0f95b74fabbfd5d63e924f992d upstream.

    Fix Oops in dasd_alias_get_start_dev() function caused by the pavgroup
    pointer being NULL.

    The pavgroup pointer is checked on the entrance of the function but
    without the lcu->lock being held. Therefore there is a race window
    between dasd_alias_get_start_dev() and _lcu_update() which sets
    pavgroup to NULL with the lcu->lock held.

    Fix by checking the pavgroup pointer with lcu->lock held.

    Cc: <stable@vger.kernel.org> # 2.6.25+
    Fixes: 8e09f21574ea ("[S390] dasd: add hyper PAV support to DASD device driver, part 1")
    Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
    Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
    Link: https://lore.kernel.org/r/20220919154931.4123002-2-sth@linux.ibm.com
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/s390/block/dasd_alias.c | 9 +++++++--
    1 file changed, 7 insertions(+), 2 deletions(-)

    --- a/drivers/s390/block/dasd_alias.c
    +++ b/drivers/s390/block/dasd_alias.c
    @@ -675,12 +675,12 @@ int dasd_alias_remove_device(struct dasd
    struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device)
    {
    struct dasd_eckd_private *alias_priv, *private = base_device->private;
    - struct alias_pav_group *group = private->pavgroup;
    struct alias_lcu *lcu = private->lcu;
    struct dasd_device *alias_device;
    + struct alias_pav_group *group;
    unsigned long flags;

    - if (!group || !lcu)
    + if (!lcu)
    return NULL;
    if (lcu->pav == NO_PAV ||
    lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING))
    @@ -697,6 +697,11 @@ struct dasd_device *dasd_alias_get_start
    }

    spin_lock_irqsave(&lcu->lock, flags);
    + group = private->pavgroup;
    + if (!group) {
    + spin_unlock_irqrestore(&lcu->lock, flags);
    + return NULL;
    + }
    alias_device = group->next;
    if (!alias_device) {
    if (list_empty(&group->aliaslist)) {

    \
     
     \ /
      Last update: 2022-09-26 12:27    [W:4.208 / U:0.020 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site