diff options
| author | Sebastian Ott <sebott@linux.vnet.ibm.com> | 2016-04-15 09:41:35 +0200 | 
|---|---|---|
| committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2016-04-21 09:50:09 +0200 | 
| commit | dba599091c191d209b1499511a524ad9657c0e5a (patch) | |
| tree | 835e2a40008fcd17f7c3a18066c9c1de1d1a63c5 | |
| parent | 55f058e7574c3615dea4615573a19bdb258696c6 (diff) | |
s390/pci: fix use after free in dma_init
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>
| -rw-r--r-- | arch/s390/pci/pci_dma.c | 16 | 
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c index e595e89eac65..1ea8c07eab84 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;  }  | 
