Commit 16d990a1 authored by Junrui Luo's avatar Junrui Luo Committed by Christian Borntraeger
Browse files

KVM: s390: pci: fix GAIT table indexing due to double-scaling pointer arithmetic



kvm_s390_pci_aif_enable(), kvm_s390_pci_aif_disable(), and
aen_host_forward() index the GAIT by manually multiplying the index
with sizeof(struct zpci_gaite).

Since aift->gait is already a struct zpci_gaite pointer, this
double-scales the offset, accessing element aisb*16 instead of aisb.

This causes out-of-bounds accesses when aisb >= 32 (with
ZPCI_NR_DEVICES=512)

Fix by removing the erroneous sizeof multiplication.

Fixes: 3c5a1b6f ("KVM: s390: pci: provide routines for enabling/disabling interrupt forwarding")
Fixes: 73f91b00 ("KVM: s390: pci: enable host forwarding of Adapter Event Notifications")
Reported-by: default avatarYuhao Jiang <danisjiang@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: default avatarJunrui Luo <moonafterrain@outlook.com>
Reviewed-by: default avatarChristian Borntraeger <borntraeger@linux.ibm.com>
Reviewed-by: default avatarMatthew Rosato <mjrosato@linux.ibm.com>
Tested-by: default avatarMatthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@linux.ibm.com>
parent 028ef9c9
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -3307,8 +3307,7 @@ static void aen_host_forward(unsigned long si)
	struct zpci_gaite *gaite;
	struct kvm *kvm;

	gaite = (struct zpci_gaite *)aift->gait +
		(si * sizeof(struct zpci_gaite));
	gaite = aift->gait + si;
	if (gaite->count == 0)
		return;
	if (gaite->aisb != 0)
+2 −4
Original line number Diff line number Diff line
@@ -290,8 +290,7 @@ static int kvm_s390_pci_aif_enable(struct zpci_dev *zdev, struct zpci_fib *fib,
				    phys_to_virt(fib->fmt0.aibv));

	spin_lock_irq(&aift->gait_lock);
	gaite = (struct zpci_gaite *)aift->gait + (zdev->aisb *
						   sizeof(struct zpci_gaite));
	gaite = aift->gait + zdev->aisb;

	/* If assist not requested, host will get all alerts */
	if (assist)
@@ -357,8 +356,7 @@ static int kvm_s390_pci_aif_disable(struct zpci_dev *zdev, bool force)
	if (zdev->kzdev->fib.fmt0.aibv == 0)
		goto out;
	spin_lock_irq(&aift->gait_lock);
	gaite = (struct zpci_gaite *)aift->gait + (zdev->aisb *
						   sizeof(struct zpci_gaite));
	gaite = aift->gait + zdev->aisb;
	isc = gaite->gisc;
	gaite->count--;
	if (gaite->count == 0) {