Re: [PATCH v2 08/18] PCI/CMA: Authenticate devices on enumeration

Lukas Wunner
2024-07-11T15:00:34Z

On Tue, Jul 09, 2024 at 04:31:30PM -0700, Dan Williams wrote:
> Non-authenticated operation is the status quo. CMA is a building block
> to other security features.

That's not quite correct: Products exist which support CMA but neither
IDE nor TDISP. CMA is not just a building block for IDE or TDISP,
but is useful on its own merits.

> Nothing currently cares about CMA being
> established before a driver loads and it is not clear that now is the
> time to for the kernel to paint itself into a corner to make that
> guarantee.

The PCI core initializes all of the device's capabilities upon enumeration.
CMA is no different than any of the other capabilities.

Chromebooks and many Linux distributions prevent driver binding to
Thunderbolt-attached devices unless they're authorized by the user.
I fully expect that vendors will want to additionally take advantage
of authentication. I don't want to wait for Windows or macOS to go
ahead and add automatic authentication, then follow in their footsteps.
I want Linux to lead the way here, so yes, absolutely, that's the corner
I want the kernel to paint itself in, no less.

> I think you are conflating automatic authentication and built-in
> functionality. There are counter examples of security features like
> encrypted root filesystems built on top of module drivers.

Encrypted root filesystems are mounted after all initcall levels have run
and user space has been launched. At that point it's possible to invoke
request_module(). But request_module() cannot be invoked from a
subsys_initcall(), which is when device capabilities are enumerated.

TSM can be a module because it's geared towards the passthrough use case
and passthrough only happens when user space is up and running.

> What I am trying to avoid is CMA setting unnecessary expectations that
> can not be duplicated by TSM like "all authentication capable PCI
> devices will be authenticated prior to driver attach".

I don't want to artificially cripple CMA in order to achieve only a
lowest common denominator with TSM. Both, native CMA and TSM-driven
authentication have their respective use cases and (dis)advantages.
Should we try to strive for commonalities in the ABI? Of course!
But not at the expense of reducing functionality.

> I agree that CMA should be in kernel, it's not clear that authentication
> needs to be automatic, and certainly not in a way that a driver can not
> opt-out of.

If there is a need to opt out, that feature can be retrofitted easily.
But systems need to be "secure by default":
https://en.wikipedia.org/wiki/Secure_by_default

> What if a use case cares about resume time latency?

Resume is parallelized (see dpm_noirq_resume_devices()), so the latency
is bounded by the time to authenticate a single device.

Unfortunately boot-time enumeration of the PCI bus is not parallelized
for historic reasons, we may indeed have to look into that.

> What if a driver
> knows that authentication is only needed later in the resume flow?

If authentication is not possible in the ->resume_noirq phase because
the driver needs to perform some initialization steps, it can just call
on the PCI core to reauthenticate the device after those steps.

The declaration of pci_cma_reauthenticate() can be moved from
drivers/pci/pci.h to include/linux/pci.h once that need arrives.

> At a minimum I think pci_cma_reauthenticate() should do something like:
>
> /* not previously authenticated skip authentication */
> if (!spdm_state->authenticated)
> return;
>
> ...so that spdm capable devices can opt-out of automatic reauthentication.

Unfortunately that doesn't work:

A device may have been reset due to a firmware update which adds
CMA support. Or the keyring of trusted root certificates may have
been missing the certificate for authenticating the device, but the
certificate has since been added. Or the device came back from reset
with a different certificate chain. Or it was hot-replaced with a
CMA-capable one...

Thanks,

Lukas