Commit fe049608 authored by Sebastian Ott's avatar Sebastian Ott Committed by Jiri Slaby

s390/pci: fix use after free in dma_init

commit dba59909 upstream.

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: default avatarSebastian Ott <sebott@linux.vnet.ibm.com>
Reviewed-by: default avatarGerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Sumit Semwal <sumit.semwal@linaro.org>
Signed-off-by: default avatarJiri Slaby <jslaby@suse.cz>
parent c244d3d0
...@@ -416,7 +416,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev) ...@@ -416,7 +416,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
zdev->dma_table = dma_alloc_cpu_table(); zdev->dma_table = dma_alloc_cpu_table();
if (!zdev->dma_table) { if (!zdev->dma_table) {
rc = -ENOMEM; rc = -ENOMEM;
goto out_clean; goto out;
} }
zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET; zdev->iommu_size = (unsigned long) high_memory - PAGE_OFFSET;
...@@ -424,7 +424,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev) ...@@ -424,7 +424,7 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8); zdev->iommu_bitmap = vzalloc(zdev->iommu_pages / 8);
if (!zdev->iommu_bitmap) { if (!zdev->iommu_bitmap) {
rc = -ENOMEM; rc = -ENOMEM;
goto out_reg; goto free_dma_table;
} }
rc = zpci_register_ioat(zdev, rc = zpci_register_ioat(zdev,
...@@ -433,12 +433,16 @@ int zpci_dma_init_device(struct zpci_dev *zdev) ...@@ -433,12 +433,16 @@ int zpci_dma_init_device(struct zpci_dev *zdev)
zdev->start_dma + zdev->iommu_size - 1, zdev->start_dma + zdev->iommu_size - 1,
(u64) zdev->dma_table); (u64) zdev->dma_table);
if (rc) if (rc)
goto out_reg; goto free_bitmap;
return 0;
out_reg: return 0;
free_bitmap:
vfree(zdev->iommu_bitmap);
zdev->iommu_bitmap = NULL;
free_dma_table:
dma_free_cpu_table(zdev->dma_table); dma_free_cpu_table(zdev->dma_table);
out_clean: zdev->dma_table = NULL;
out:
return rc; return rc;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment