diff mbox

[Xenial,SRU] s390/pci: fix use after free in dma_init

Message ID 1464023732-17384-1-git-send-email-tim.gardner@canonical.com
State New
Headers show

Commit Message

Tim Gardner May 23, 2016, 5:15 p.m. UTC
From: Sebastian Ott <sebott@linux.vnet.ibm.com>

BugLink: http://bugs.launchpad.net/bugs/1584828

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@linux.vnet.ibm.com>
Reviewed-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
(cherry picked from commit dba599091c191d209b1499511a524ad9657c0e5a)
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
---
 arch/s390/pci/pci_dma.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

Comments

Kamal Mostafa May 23, 2016, 8:04 p.m. UTC | #1

Andy Whitcroft May 25, 2016, 7:13 a.m. UTC | #2
On Mon, May 23, 2016 at 11:15:32AM -0600, Tim Gardner wrote:
> From: Sebastian Ott <sebott@linux.vnet.ibm.com>
> 
> BugLink: http://bugs.launchpad.net/bugs/1584828
> 
> 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@linux.vnet.ibm.com>
> Reviewed-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
> (cherry picked from commit dba599091c191d209b1499511a524ad9657c0e5a)
> Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
> ---
>  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 a06ce80..309d5e0 100644
> --- a/arch/s390/pci/pci_dma.c
> +++ b/arch/s390/pci/pci_dma.c
> @@ -457,7 +457,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;
>  	}
>  
>  	/*
> @@ -477,18 +477,22 @@ 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, 0, zdev->start_dma, zdev->end_dma,
>  				(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;
>  }

Acked-by: Andy Whitcroft <apw@canonical.com>

-apw
Kamal Mostafa May 25, 2016, 5:59 p.m. UTC | #3

diff mbox

Patch

diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index a06ce80..309d5e0 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -457,7 +457,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;
 	}
 
 	/*
@@ -477,18 +477,22 @@  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, 0, zdev->start_dma, zdev->end_dma,
 				(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;
 }