Commit a9b0ea1f authored by Christian Borntraeger's avatar Christian Borntraeger Committed by Guo Mengqi
Browse files

KVM: s390: vsie: fix race during shadow creation

stable inclusion
from stable-v6.1.82
commit 5df3b81a567eb565029563f26f374ae3803a1dfc
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9E2GQ
CVE: CVE-2023-52639

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



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

[ Upstream commit fe752331d4b361d43cfd0b89534b4b2176057c32 ]

Right now it is possible to see gmap->private being zero in
kvm_s390_vsie_gmap_notifier resulting in a crash.  This is due to the
fact that we add gmap->private == kvm after creation:

static int acquire_gmap_shadow(struct kvm_vcpu *vcpu,
                               struct vsie_page *vsie_page)
{
[...]
        gmap = gmap_shadow(vcpu->arch.gmap, asce, edat);
        if (IS_ERR(gmap))
                return PTR_ERR(gmap);
        gmap->private = vcpu->kvm;

Let children inherit the private field of the parent.

Reported-by: default avatarMarc Hartmayer <mhartmay@linux.ibm.com>
Fixes: a3508fbe ("KVM: s390: vsie: initial support for nested virtualization")
Cc: <stable@vger.kernel.org>
Cc: David Hildenbrand <david@redhat.com>
Reviewed-by: default avatarJanosch Frank <frankja@linux.ibm.com>
Reviewed-by: default avatarDavid Hildenbrand <david@redhat.com>
Reviewed-by: default avatarClaudio Imbrenda <imbrenda@linux.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@linux.ibm.com>
Link: https://lore.kernel.org/r/20231220125317.4258-1-borntraeger@linux.ibm.com


Signed-off-by: default avatarSasha Levin <sashal@kernel.org>

conflicts:
	arch/s390/kvm/vsie.c

Signed-off-by: default avatarCui GaoSheng <cuigaosheng1@huawei.com>
parent 1df0d53c
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -1197,7 +1197,6 @@ static int acquire_gmap_shadow(struct kvm_vcpu *vcpu,
	gmap = gmap_shadow(vcpu->arch.gmap, asce, edat);
	if (IS_ERR(gmap))
		return PTR_ERR(gmap);
	gmap->private = vcpu->kvm;
	WRITE_ONCE(vsie_page->gmap, gmap);
	return 0;
}
+1 −0
Original line number Diff line number Diff line
@@ -1663,6 +1663,7 @@ struct gmap *gmap_shadow(struct gmap *parent, unsigned long asce,
		return ERR_PTR(-ENOMEM);
	new->mm = parent->mm;
	new->parent = gmap_get(parent);
	new->private = parent->private;
	new->orig_asce = asce;
	new->edat_level = edat_level;
	new->initialized = false;