[added to the 4.1 stable tree] s390/pci: fix use after free in dma_init

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Sebastian Ott <sebott@xxxxxxxxxxxxxxxxxx>

This patch has been added to the  stable tree. If you have any
objections, please let us know.

===============

[ Upstream commit dba599091c191d209b1499511a524ad9657c0e5a ]

After a failure during registration of the dma_table (because of the
function being in error state) we free its memory but don't reset the
associated pointer to zero.

When we then receive a notification from firmware (about the function
being in error state) we'll try to walk and free the dma_table again.

Fix this by resetting the dma_table pointer. In addition to that make
sure that we free the iommu_bitmap when appropriate.

Signed-off-by: Sebastian Ott <sebott@xxxxxxxxxxxxxxxxxx>
Reviewed-by: Gerald Schaefer <gerald.schaefer@xxxxxxxxxx>
Signed-off-by: Martin Schwidefsky <schwidefsky@xxxxxxxxxx>
Signed-off-by: Sasha Levin <alexander.levin@xxxxxxxxxxxxx>
---
 arch/s390/pci/pci_dma.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index 6fd8d5836138..888cc878efaa 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -432,7 +432,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
 	zdev->dma_table = dma_alloc_cpu_table();
 	if (!zdev->dma_table) {
 		rc = -ENOMEM;
-		goto out_clean;
+		goto out;
 	}
 
 	zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET;
@@ -440,7 +440,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
 	zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8);
 	if (!zdev->iommu_bitmap) {
 		rc = -ENOMEM;
-		goto out_reg;
+		goto free_dma_table;
 	}
 
 	rc = zpci_register_ioat(zdev,
@@ -449,12 +449,16 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
 				zdev->start_dma + zdev->iommu_size - 1,
 				(u64) zdev->dma_table);
 	if (rc)
-		goto out_reg;
-	return 0;
+		goto free_bitmap;
 
-out_reg:
+	return 0;
+free_bitmap:
+	vfree(zdev->iommu_bitmap);
+	zdev->iommu_bitmap = NULL;
+free_dma_table:
 	dma_free_cpu_table(zdev->dma_table);
-out_clean:
+	zdev->dma_table = NULL;
+out:
 	return rc;
 }
 
-- 
2.11.0




[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]