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

Dan Williams
2024-07-11T17:50:39Z

Lukas Wunner wrote:
> 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.

Agree it is useful. The use case of signed device inventory at a CSP,
that I understand storage vendors are interested, does not demand
aggressive forced authentication of all PCI devices in early init. As far
as I understand the non PCI-CMA consumers of lib/spdm/ are going to be
drivers possibly built as modules.

> > 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.

Init, sure.

> CMA is no different than any of the other capabilities.

It is a dynamic command protocol with a state machine, the state is free
to transition post-init.

> 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.

Look, if someone wants to build an aggressive policy they can, just set
the tristate option to 'Y'. It's the "all or nothing forced kernel
policy" that is awkward.

> > 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.

Again, this is conflating the init mechanism from the state transition.
TSM will also be initialized at subsys_initcall() level.

> 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.

Yes, and no. TSM is going to be the only mechanism to enable IDE on
multiple platforms. I can imagine hyper-vigilant use cases that want to
deploy a policy of delaying driver probing until IDE is established
*and* wanting that to happen without loadable modules. That should be
possible with CONFIG_PCI_TSM=y and some EPROBE_DEFER dance with the
low-level TSM driver.

At no point is the TSM driver forcing IDE to be enabled on all devices
just because it is there. It remains an optional policy of the distro.

> > 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

Hold on, "cripple"!? Just because the authenticated state might be
delayed due to distro policy?

> 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.

No mechanism is injured. This is only a question of optionality in
policy.

> > 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.

Now, *that* is true, and that is what keeps me from outright NAKing this
approach.

I see no justification for the hard coded aggressive default policy, but
I will defer to Bjorn on whether this goes in as is with a plan to fix
it later, or fix it now.

> But systems need to be "secure by default":
> https://en.wikipedia.org/wiki/Secure_by_default

That's policy. Distros manage questions of security vs
user-friendliness, and I continue to have user friendliness concerns
relative to the security value that PCI-CMA offers.

> > 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.

As far as I understand that can still be on the order of seconds, and
pathological cases that could be longer. So the choice is wait to see
who screams, or plan for non-ideal devices. The worst case is distros
start shipping CONFIG_PCI_CMA=n because it causes too many problems,

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

Yeah, driver probing is async though, so if initial authentication moves
to be done in or around pci_enable_device() then it achieves async init
while also allowing for drivers to not be exposed to unauthenticated
devices.

> > 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.

Up to Bjorn whether to pull that thread now or not.

> > 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...

All of these are mitigated by pushing authentication management to
drivers. "Just re-authenticate" makes the latency problem worse. How bad
is that latency problem in practice? I do not know.