* Re: [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX
2026-08-18 19:13 [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX Niklas Schnelle
@ 2026-08-18 19:37 ` sashiko-bot
2026-08-18 20:00 ` Farhan Ali
` (3 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-08-18 19:37 UTC (permalink / raw)
To: Niklas Schnelle
Cc: Vasily Gorbik, Heiko Carstens, Alexander Gordeev, linux-s390,
Christian Borntraeger
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] Intermediate IOMMU translation tables are dynamically allocated during map/unmap but never freed when empty, allowing an attacker to exhaust kernel memory.
- [High] IOMMU unmap operations needlessly allocate page tables with GFP_ATOMIC when unmapping unmapped regions, which wastes memory and causes unmap failures if allocation fails.
--
--- Patch [1]: [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX ---
commit 87f13b9b4d2f1a6021028f52263833bccd842526
Author: Niklas Schnelle <schnelle@linux.ibm.com>
iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX
When using a 5-level translation table via ZPCI_TABLE_TYPE_RFX,
get_rso_from_iova() can return NULL when the region-first entry is invalid.
This patch prevents a NULL pointer dereference by adding a missing NULL
check for the region-second origin before accessing it.
> diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
> index f148f559ac564..58ca7727b7f24 100644
> --- a/drivers/iommu/s390-iommu.c
> +++ b/drivers/iommu/s390-iommu.c
> @@ -974,6 +974,8 @@ static unsigned long *get_rto_from_iova(struct s390_domain *domain,
> case ZPCI_TABLE_TYPE_RFX:
> case ZPCI_TABLE_TYPE_RSX:
> rso = get_rso_from_iova(domain, iova);
> + if (!rso)
> + return NULL;
> rsx = calc_rsx(iova);
> rse = READ_ONCE(rso[rsx]);
> if (!reg_entry_isvalid(rse))
[Severity: High]
This is a pre-existing issue, but is it possible to exhaust kernel memory
with intermediate IOMMU translation tables?
Looking at dma_walk_cpu_trans() in drivers/iommu/s390-iommu.c:
drivers/iommu/s390-iommu.c:dma_walk_cpu_trans() {
...
sto = dma_get_seg_table_origin(&rto[rtx], gfp);
if (!sto)
return NULL;
sx = calc_sx(dma_addr);
pto = dma_get_page_table_origin(&sto[sx], gfp);
...
}
These intermediate tables are dynamically allocated unconditionally, but
they appear to only be freed during domain destruction:
drivers/iommu/s390-iommu.c:dma_cleanup_tables() {
...
for (rtx = 0; rtx < ZPCI_TABLE_ENTRIES; rtx++)
if (reg_entry_isvalid(domain->dma_table[rtx]))
dma_free_seg_table(domain->dma_table[rtx]);
...
}
Can an unprivileged user with VFIO access repeatedly map and unmap pages
at large strides across a huge IOVA aperture to leak these dynamically
allocated intermediate tables and cause an out of memory condition?
[Severity: High]
This is a pre-existing issue, but does unmapping an unmapped region
needlessly allocate page tables?
Looking at s390_iommu_invalidate_trans() in drivers/iommu/s390-iommu.c:
drivers/iommu/s390-iommu.c:s390_iommu_invalidate_trans() {
...
for (i = 0; i < nr_pages; i++) {
entry = dma_walk_cpu_trans(s390_domain, dma_addr, GFP_ATOMIC);
if (unlikely(!entry)) {
rc = -EINVAL;
break;
}
...
}
When encountering an unmapped hole, dma_get_seg_table_origin()
unconditionally allocates missing page table directories:
drivers/iommu/s390-iommu.c:dma_get_seg_table_origin() {
...
rte = READ_ONCE(*rtep);
if (reg_entry_isvalid(rte)) {
sto = get_rt_sto(rte);
} else {
sto = dma_alloc_cpu_table(gfp);
...
}
If this atomic allocation fails under memory pressure during a bulk unmap,
would the loop abort and return an error? Could this leave any remaining
pages in the requested range fully mapped in the IOMMU while the kernel
potentially frees the underlying physical memory?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260818-iommu_fix_iova_to_phys-v1-1-1cd76d2a55b8@linux.ibm.com?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX
2026-08-18 19:13 [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX Niklas Schnelle
2026-08-18 19:37 ` sashiko-bot
@ 2026-08-18 20:00 ` Farhan Ali
2026-08-18 20:16 ` Matthew Rosato
` (2 subsequent siblings)
4 siblings, 0 replies; 7+ messages in thread
From: Farhan Ali @ 2026-08-18 20:00 UTC (permalink / raw)
To: Niklas Schnelle, Matthew Rosato, Omar Elghoul, Gerd Bayer,
Benjamin Block, Julian Ruess, Joerg Roedel (AMD), Will Deacon,
Robin Murphy, Joerg Roedel
Cc: Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Ramesh Errabolu, Tobias Schumacher, Halil Pasic,
Peter Oberparleiter, Gerald Schaefer, Christian Borntraeger,
linux-s390, iommu, linux-kernel
On 8/18/2026 12:13 PM, Niklas Schnelle wrote:
> When using a 5-level translation table via ZPCI_TABLE_TYPE_RFX
> get_rso_from_iova() returns NULL when the region-first entry is invalid.
> Yet in get_rto_from_iova() the region-second origin rso is not checked
> to be non-NULL before accessing rso[rsx] leading to a NULL pointer
> dereference instead of a NULL return when iova_to_phys() is called on
> a unmapped IOVA. Fix this by adding the missing NULL check.
>
> Cc:stable@vger.kernel.org
> Fixes: 81244074b518 ("iommu/s390: allow larger region tables")
> Signed-off-by: Niklas Schnelle<schnelle@linux.ibm.com>
> ---
> drivers/iommu/s390-iommu.c | 2 ++
> 1 file changed, 2 insertions(+)
Reviewed-by: Farhan Ali<alifm@linux.ibm.com>
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX
2026-08-18 19:13 [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX Niklas Schnelle
2026-08-18 19:37 ` sashiko-bot
2026-08-18 20:00 ` Farhan Ali
@ 2026-08-18 20:16 ` Matthew Rosato
2026-08-21 12:39 ` Benjamin Block
2026-08-23 21:00 ` Vasily Gorbik
4 siblings, 0 replies; 7+ messages in thread
From: Matthew Rosato @ 2026-08-18 20:16 UTC (permalink / raw)
To: Niklas Schnelle, Farhan Ali, Omar Elghoul, Gerd Bayer,
Benjamin Block, Julian Ruess, Joerg Roedel (AMD), Will Deacon,
Robin Murphy, Joerg Roedel
Cc: Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Sven Schnelle,
Ramesh Errabolu, Tobias Schumacher, Halil Pasic,
Peter Oberparleiter, Gerald Schaefer, Christian Borntraeger,
linux-s390, iommu, linux-kernel
On 8/18/26 3:13 PM, Niklas Schnelle wrote:
> When using a 5-level translation table via ZPCI_TABLE_TYPE_RFX
> get_rso_from_iova() returns NULL when the region-first entry is invalid.
> Yet in get_rto_from_iova() the region-second origin rso is not checked
> to be non-NULL before accessing rso[rsx] leading to a NULL pointer
> dereference instead of a NULL return when iova_to_phys() is called on
> a unmapped IOVA. Fix this by adding the missing NULL check.
>
> Cc: stable@vger.kernel.org
> Fixes: 81244074b518 ("iommu/s390: allow larger region tables")
> Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
> ---
> drivers/iommu/s390-iommu.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
> index f148f559ac56..58ca7727b7f2 100644
> --- a/drivers/iommu/s390-iommu.c
> +++ b/drivers/iommu/s390-iommu.c
> @@ -974,6 +974,8 @@ static unsigned long *get_rto_from_iova(struct s390_domain *domain,
> case ZPCI_TABLE_TYPE_RFX:
> case ZPCI_TABLE_TYPE_RSX:
> rso = get_rso_from_iova(domain, iova);
> + if (!rso)
> + return NULL;
> rsx = calc_rsx(iova);
> rse = READ_ONCE(rso[rsx]);
> if (!reg_entry_isvalid(rse))
>
> ---
> base-commit: 8d3ae59288f1e7d58d76558a6ee96d533bc5019f
> change-id: 20260818-iommu_fix_iova_to_phys-5879275b95ec
>
> Best regards,
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX
2026-08-18 19:13 [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX Niklas Schnelle
` (2 preceding siblings ...)
2026-08-18 20:16 ` Matthew Rosato
@ 2026-08-21 12:39 ` Benjamin Block
2026-08-23 21:00 ` Vasily Gorbik
4 siblings, 0 replies; 7+ messages in thread
From: Benjamin Block @ 2026-08-21 12:39 UTC (permalink / raw)
To: Niklas Schnelle
Cc: Matthew Rosato, Farhan Ali, Omar Elghoul, Gerd Bayer,
Julian Ruess, Joerg Roedel (AMD), Will Deacon, Robin Murphy,
Joerg Roedel, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Sven Schnelle, Ramesh Errabolu, Tobias Schumacher, Halil Pasic,
Peter Oberparleiter, Gerald Schaefer, Christian Borntraeger,
linux-s390, iommu, linux-kernel
On Tue, Aug 18, 2026 at 09:13:17PM +0200, Niklas Schnelle wrote:
> When using a 5-level translation table via ZPCI_TABLE_TYPE_RFX
> get_rso_from_iova() returns NULL when the region-first entry is invalid.
> Yet in get_rto_from_iova() the region-second origin rso is not checked
> to be non-NULL before accessing rso[rsx] leading to a NULL pointer
> dereference instead of a NULL return when iova_to_phys() is called on
> a unmapped IOVA. Fix this by adding the missing NULL check.
>
> Cc: stable@vger.kernel.org
> Fixes: 81244074b518 ("iommu/s390: allow larger region tables")
> Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
> ---
> drivers/iommu/s390-iommu.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/iommu/s390-iommu.c b/drivers/iommu/s390-iommu.c
> index f148f559ac56..58ca7727b7f2 100644
> --- a/drivers/iommu/s390-iommu.c
> +++ b/drivers/iommu/s390-iommu.c
> @@ -974,6 +974,8 @@ static unsigned long *get_rto_from_iova(struct s390_domain *domain,
> case ZPCI_TABLE_TYPE_RFX:
> case ZPCI_TABLE_TYPE_RSX:
> rso = get_rso_from_iova(domain, iova);
> + if (!rso)
> + return NULL;
> rsx = calc_rsx(iova);
> rse = READ_ONCE(rso[rsx]);
> if (!reg_entry_isvalid(rse))
Looks good to me!
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
--
Best Regards, Benjamin Block / Linux on IBM Z Kernel Development
IBM Deutschland Research & Development GmbH / https://www.ibm.com/privacy
Vors. Aufs.-R.: Wolfgang Wendt / Geschäftsführung: David Faller
Sitz der Ges.: Ehningen / Registergericht: AmtsG Stuttgart, HRB 243294
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX
2026-08-18 19:13 [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX Niklas Schnelle
` (3 preceding siblings ...)
2026-08-21 12:39 ` Benjamin Block
@ 2026-08-23 21:00 ` Vasily Gorbik
2026-08-24 7:18 ` Vasily Gorbik
4 siblings, 1 reply; 7+ messages in thread
From: Vasily Gorbik @ 2026-08-23 21:00 UTC (permalink / raw)
To: Niklas Schnelle
Cc: Matthew Rosato, Farhan Ali, Omar Elghoul, Gerd Bayer,
Benjamin Block, Julian Ruess, Joerg Roedel (AMD), Will Deacon,
Robin Murphy, Joerg Roedel, Heiko Carstens, Alexander Gordeev,
Sven Schnelle, Ramesh Errabolu, Tobias Schumacher, Halil Pasic,
Peter Oberparleiter, Gerald Schaefer, Christian Borntraeger,
linux-s390, iommu, linux-kernel
On Tue, Aug 18, 2026 at 09:13:17PM +0200, Niklas Schnelle wrote:
> When using a 5-level translation table via ZPCI_TABLE_TYPE_RFX
> get_rso_from_iova() returns NULL when the region-first entry is invalid.
> Yet in get_rto_from_iova() the region-second origin rso is not checked
> to be non-NULL before accessing rso[rsx] leading to a NULL pointer
> dereference instead of a NULL return when iova_to_phys() is called on
> a unmapped IOVA. Fix this by adding the missing NULL check.
>
> Cc: stable@vger.kernel.org
> Fixes: 81244074b518 ("iommu/s390: allow larger region tables")
> Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
> ---
> drivers/iommu/s390-iommu.c | 2 ++
> 1 file changed, 2 insertions(+)
Applied, thank you!
^ permalink raw reply [flat|nested] 7+ messages in thread* Re: [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX
2026-08-23 21:00 ` Vasily Gorbik
@ 2026-08-24 7:18 ` Vasily Gorbik
0 siblings, 0 replies; 7+ messages in thread
From: Vasily Gorbik @ 2026-08-24 7:18 UTC (permalink / raw)
To: Niklas Schnelle
Cc: Matthew Rosato, Farhan Ali, Omar Elghoul, Gerd Bayer,
Benjamin Block, Julian Ruess, Joerg Roedel (AMD), Will Deacon,
Robin Murphy, Joerg Roedel, Heiko Carstens, Alexander Gordeev,
Sven Schnelle, Ramesh Errabolu, Tobias Schumacher, Halil Pasic,
Peter Oberparleiter, Gerald Schaefer, Christian Borntraeger,
linux-s390, iommu, linux-kernel
On Sun, Aug 23, 2026 at 11:00:33PM +0200, Vasily Gorbik wrote:
> On Tue, Aug 18, 2026 at 09:13:17PM +0200, Niklas Schnelle wrote:
> > When using a 5-level translation table via ZPCI_TABLE_TYPE_RFX
> > get_rso_from_iova() returns NULL when the region-first entry is invalid.
> > Yet in get_rto_from_iova() the region-second origin rso is not checked
> > to be non-NULL before accessing rso[rsx] leading to a NULL pointer
> > dereference instead of a NULL return when iova_to_phys() is called on
> > a unmapped IOVA. Fix this by adding the missing NULL check.
> >
> > Cc: stable@vger.kernel.org
> > Fixes: 81244074b518 ("iommu/s390: allow larger region tables")
> > Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
> > ---
> > drivers/iommu/s390-iommu.c | 2 ++
> > 1 file changed, 2 insertions(+)
>
> Applied, thank you!
Oh, I was too eager here. Please disregard my previous "Applied" message.
This usually goes via IOMMU subsystem tree and not s390 tree.
Joerg, Will, I'll leave this one to you. Sorry for the confusion.
^ permalink raw reply [flat|nested] 7+ messages in thread