]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: s390: pci: fix GAIT table indexing due to double-scaling pointer arithmetic
authorJunrui Luo <moonafterrain@outlook.com>
Wed, 15 Apr 2026 09:26:55 +0000 (17:26 +0800)
committerChristian Borntraeger <borntraeger@linux.ibm.com>
Fri, 17 Apr 2026 11:12:07 +0000 (13:12 +0200)
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: 3c5a1b6f0a18 ("KVM: s390: pci: provide routines for enabling/disabling interrupt forwarding")
Fixes: 73f91b004321 ("KVM: s390: pci: enable host forwarding of Adapter Event Notifications")
Reported-by: Yuhao Jiang <danisjiang@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Junrui Luo <moonafterrain@outlook.com>
Reviewed-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Tested-by: Matthew Rosato <mjrosato@linux.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
arch/s390/kvm/interrupt.c
arch/s390/kvm/pci.c

index 7cb8ce833b625448fdc0a9329f9743a3b76d83ac..f48f25c7dc8fe41b8f6bd6367f813a4ad74f3e8d 100644 (file)
@@ -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)
index 86d93e8dddae3ebb2a2441db6f9c47a7fb71fa44..eed45af1a92d48b5aac396473959895353ed81de 100644 (file)
@@ -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) {