From: sashiko-bot@kernel.org
To: "Niklas Schnelle" <schnelle@linux.ibm.com>
Cc: "Vasily Gorbik" <gor@linux.ibm.com>,
"Heiko Carstens" <hca@linux.ibm.com>,
"Alexander Gordeev" <agordeev@linux.ibm.com>,
linux-s390@vger.kernel.org,
"Christian Borntraeger" <borntraeger@linux.ibm.com>
Subject: Re: [PATCH] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX
Date: Tue, 18 Aug 2026 19:37:48 +0000 [thread overview]
Message-ID: <20260818193748.B503E1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260818-iommu_fix_iova_to_phys-v1-1-1cd76d2a55b8@linux.ibm.com>
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
next prev parent reply other threads:[~2026-08-18 19:37 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
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 [this message]
2026-08-18 20:00 ` Farhan Ali
2026-08-18 20:16 ` Matthew Rosato
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260818193748.B503E1F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=agordeev@linux.ibm.com \
--cc=borntraeger@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=linux-s390@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=schnelle@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox