Linux Security Modules development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
Cc: linux-security-module@vger.kernel.org
Subject: Re: [PATCH 1/2] iommu: Add iommu_is_available() API
Date: Mon, 02 Nov 2026 14:11:28 +0000	[thread overview]
Message-ID: <sashiko-outbox-193537@kernel.org> (raw)
In-Reply-To: <20261102-lockdown-iommu-v1-1-00f3c2be4c9f@kernel.org>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] iommu: iommu_available never cleared in iommu_device_unregister()
- [Medium] iommu: iommu_device_register() marks non-translating IOMMUs available
- [Low] iommu: unnecessary export and wrong doc for iommu_set_available()
- [Low] iommu: unmarked lockless access to iommu_available
--

commit 994e0def279fa954a8ab08056b43fb15157b3edd
Author: Mario Limonciello (AMD) <superm1@kernel.org>

iommu: Add iommu_is_available() API

This commit introduces iommu_is_available() and iommu_set_available() so
that security subsystems such as lockdown can query whether an IOMMU driver
has registered and probed on the platform.

> diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
> index b486b8bbd1fcd..d042944713ab4 100644
> --- a/drivers/iommu/iommu.c
> +++ b/drivers/iommu/iommu.c
> @@ -309,6 +309,13 @@ int iommu_device_register(struct iommu_device *iommu,
>  		iommu_device_unregister(iommu);
>  	else
>  		WRITE_ONCE(iommu->ready, true);
> +	/*
> +	 * Mark IOMMU as available if registration succeeded and bus probing
> +	 * succeeded. This enables security checks (e.g. lockdown IOMMU check)
> +	 * that depend on knowing whether hardware IOMMU isolation is present.
> +	 */
> +	if (!err)
> +		iommu_set_available();

[Severity: High]
What happens if all registered IOMMU devices are later unregistered via
iommu_device_unregister()?

Several IOMMU drivers perform additional fallible initialization steps after
calling iommu_device_register() and unwind with iommu_device_unregister() on
failure. For example, in drivers/iommu/amd/init.c:

iommu_init_pci()
  iommu_device_register()
  pci_enable_device()

and later in state_next():

state_next()
  amd_iommu_enable_interrupts()
  free_iommu_resources()
    free_iommu_all()
      free_iommu_one()
        free_sysfs()
          iommu_device_unregister(&iommu->iommu);

Similar post-registration error paths exist in mtk_iommu_probe() (when
component_master_add_with_match() fails) and sprd_iommu_probe() (when
sprd_iommu_clk_enable() or sprd_iommu_get_version() fails), as well as
driver unbind and hot-unplug paths.

Because iommu_device_unregister() removes the instance from
iommu_device_list without clearing or recalculating iommu_available when the
list becomes empty, won't iommu_is_available() permanently return true even
when no IOMMU device remains registered?

[Severity: Medium]
Could setting iommu_available unconditionally when iommu_device_register()
succeeds report true on platforms where no DMA translation or isolation is
actually active?

In drivers/iommu/iommu.c, probe_iommu_group() converts -ENODEV from
__iommu_probe_device() into 0, so bus_iommu_probe() succeeds even when an
IOMMU driver rejects all devices or provides no DMA translation:

1. In drivers/iommu/amd/init.c, iommu_init_pci() calls
   iommu_device_register() even when amd_iommu_pgtable == PD_MODE_NONE
   (where DMA translation is unsupported and only interrupt remapping is
   used, causing amd_iommu_probe_device() to return ERR_PTR(-ENODEV) for
   every device):

	ret = iommu_device_register(&iommu->iommu, &amd_iommu_ops, NULL);
	if (ret || amd_iommu_pgtable == PD_MODE_NONE) {
		iommu_device_sysfs_remove(&iommu->iommu);
	}

2. In drivers/xen/grant-dma-iommu.c, grant_dma_iommu_probe() registers
   grant_dma_iommu_ops, whose probe_device callback unconditionally returns
   ERR_PTR(-ENODEV) without providing hardware DMA isolation.

3. When default passthrough mode is active (iommu_default_passthrough() is
   true via iommu=pt, iommu.passthrough=1, or
   CONFIG_IOMMU_DEFAULT_PASSTHROUGH=y), internal PCI/PCIe devices are placed
   in IOMMU_DOMAIN_IDENTITY domains with unrestricted DMA access to physical
   memory.

Should iommu_is_available() account for whether active DMA translation is
present rather than only checking if iommu_device_register() was called?

>  	return err;
>  }
>  EXPORT_SYMBOL_GPL(iommu_device_register);
> @@ -2961,6 +2968,47 @@ static int __init iommu_init(void)
>  }
>  core_initcall(iommu_init);
>  
> +static bool iommu_available __read_mostly;
> +
> +/**
> + * iommu_is_available() - Check if IOMMU subsystem is available

[ ... ]

> + */
> +bool iommu_is_available(void)
> +{
> +	return iommu_available;
> +}
> +EXPORT_SYMBOL_GPL(iommu_is_available);
> +
> +/**
> + * iommu_set_available() - Mark IOMMU as available
> + *
> + * Called by IOMMU drivers during probe to indicate that hardware IOMMU
> + * support is functional on this platform.
> + *
> + * Context: Called from driver probe paths.
> + */
> +void iommu_set_available(void)
> +{
> +	iommu_available = true;
> +}
> +EXPORT_SYMBOL_GPL(iommu_set_available);

[Severity: Low]
Since iommu_is_available() can be called at any time after module
initialization has begun while deferred or hotplug IOMMU driver probes may
call iommu_device_register() concurrently without holding a shared lock,
should the accesses to iommu_available use READ_ONCE() and WRITE_ONCE()
(similar to WRITE_ONCE(iommu->ready, true) in iommu_device_register()), or
check !list_empty(&iommu_device_list) under iommu_device_lock, to avoid
KCSAN data-race warnings?

[Severity: Low]
Is there any reason to declare iommu_set_available() in
include/linux/iommu.h and export it via EXPORT_SYMBOL_GPL()?

The kernel-doc comment states that it is called by IOMMU drivers during
probe, but its only caller is iommu_device_register() in
drivers/iommu/iommu.c. Could iommu_set_available() be made static (or folded
directly into iommu_device_register()) so arbitrary modules cannot flip this
security-sensitive state without registering an IOMMU device?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261102-lockdown-iommu-v1-0-00f3c2be4c9f@kernel.org?part=1

  reply	other threads:[~2026-11-02 14:11 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-02 14:00 [PATCH 0/2] lockdown: Prevent booting with lockdown enabled but IOMMU disabled Mario Limonciello (AMD)
2026-11-02 14:00 ` [PATCH 1/2] iommu: Add iommu_is_available() API Mario Limonciello (AMD)
2026-11-02 14:11   ` sashiko-bot [this message]
2026-11-02 14:00 ` [PATCH 2/2] security: lockdown: Prevent boot with lockdown but no IOMMU Mario Limonciello (AMD)
2026-11-02 14:28   ` sashiko-bot

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=sashiko-outbox-193537@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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