Commit 4c0c7f59 authored by Stefan Haberland's avatar Stefan Haberland Committed by Li Zetao
Browse files

s390/dasd: fix Oops in dasd_alias_get_start_dev due to missing pavgroup

stable inclusion
from stable-v4.19.260
commit aaba5ff2742043705bc4c02fd0b2b246e2e16da1
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9KHGT
CVE: CVE-2022-48636

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=aaba5ff2742043705bc4c02fd0b2b246e2e16da1



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

commit db7ba071 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: 8e09f215 ("[S390] dasd: add hyper PAV support to DASD device driver, part 1")
Signed-off-by: default avatarStefan Haberland <sth@linux.ibm.com>
Reviewed-by: default avatarJan Hoeppner <hoeppner@linux.ibm.com>
Link: https://lore.kernel.org/r/20220919154931.4123002-2-sth@linux.ibm.com


Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: default avatarLi Zetao <lizetao1@huawei.com>
parent 6c4027e2
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -657,12 +657,12 @@ int dasd_alias_remove_device(struct dasd_device *device)
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))
@@ -679,6 +679,11 @@ struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device)
	}

	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)) {