Linux-PCI Archive mirror
 help / color / mirror / Atom feed
From: Alistair Francis <alistair23@gmail.com>
To: sashiko@lists.linux.dev, Lukas Wunner <lukas@wunner.de>
Cc: linux-pci@vger.kernel.org, ojeda@kernel.org
Subject: Re: [PATCH 10/18] PCI/CMA: Validate Subject Alternative Name in certificates
Date: Thu, 14 May 2026 12:45:46 +1000	[thread overview]
Message-ID: <CAKmqyKMti4wxuU-uRcLXLnXpXTHGajHkx=7zt54FDLUry+mP6Q@mail.gmail.com> (raw)
In-Reply-To: <20260508035806.0EE8DC2BCB0@smtp.kernel.org>

On Fri, May 8, 2026 at 1:58 PM <sashiko-bot@kernel.org> wrote:
>
> Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
> - [High] Valid devices with a DSN of 0 are incorrectly rejected
> - [High] SSVID and SSID fields are incorrectly omitted for PCIe bridges
> - [High] Torn read of device identity prevents reauthentication after runtime mutations
> - [High] Kbuild linkage failure when compiled as a loadable module
> - [Medium] Chaining `snprintf` without length checks risks logic errors and out-of-bounds stack reads
> - [Medium] Strict case-sensitive comparison of the Subject Alternative Name risks rejecting valid certificates
> --

+ Lukas

>
> commit 72435325efe665bb825f47731ca5c0081b7acc14
> Author: Lukas Wunner <lukas@wunner.de>
> Subject: PCI/CMA: Validate Subject Alternative Name in certificates
>
> This commit introduces functionality to validate the Subject Alternative Name
> (SAN) in PCIe Leaf Certificates. It parses the SAN using an ASN.1 decoder
> and verifies that the identity encoded in the certificate matches the
> device's identity in Config Space.
>
> > diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
> > index 16abfd0e17e19..15512512fce7d 100644
> > --- a/drivers/pci/Makefile
> > +++ b/drivers/pci/Makefile
> [ ... ]
> > -obj-$(CONFIG_PCI_CMA)                += cma.o
> > +obj-$(CONFIG_PCI_CMA)                += cma.o cma.asn1.o
> > +$(obj)/cma.o:                        $(obj)/cma.asn1.h
> > +$(obj)/cma.asn1.o:           $(obj)/cma.asn1.c $(obj)/cma.asn1.h
>
> If CONFIG_PCI_CMA is configured as a loadable module, will Kbuild compile
> two separate modules (cma.ko and cma.asn1.ko)?
>
> Because the ASN.1 compiler does not export the cma_decoder symbol, would
> the cma.ko module fail to link during modpost with an undefined symbol
> error?
>
> Should these objects be bundled into a composite object instead? For
> example:
>
> cma_module-y := cma.o cma.asn1.o
> obj-$(CONFIG_PCI_CMA) += cma_module.o

This seems correct

>
> > diff --git a/drivers/pci/cma.c b/drivers/pci/cma.c
> > index 998fde6366fb8..ee186f3619409 100644
> > --- a/drivers/pci/cma.c
> > +++ b/drivers/pci/cma.c
> [ ... ]
> > +int pci_cma_note_san(void *context, size_t hdrlen, unsigned char tag,
> > +                  const void *value, size_t vlen)
> > +{
> > +     struct pci_cma_x509_context *ctx = context;
> > +
> > +     /* These aren't the drOIDs we're looking for. */
> > +     if (ctx->last_oid != OID_CMA)
> > +             return 0;
> > +
> > +     if (tag != ASN1_UTF8STR ||
> > +         vlen != ctx->expected_len ||
> > +         memcmp(value, ctx->expected_name, vlen) != 0) {
>
> Does this perform a strict case-sensitive comparison of the Subject
> Alternative Name?
>
> If a device vendor provisions the certificate using uppercase hexadecimal
> letters (a common standard for hardware IDs), could this strict memcmp()
> erroneously reject a valid device?

This is incorrect though, as the case is specified in the PCI spec

>
> > +             pci_err(ctx->pdev, "Leaf certificate of slot %u "
> > +                     "has invalid Subject Alternative Name\n", ctx->slot);
> > +             return -EINVAL;
> > +     }
> > +
> > +     ctx->found = true;
> > +
> > +     return 0;
> > +}
> > +
> > +static unsigned int pci_cma_construct_san(struct pci_dev *pdev, char *name)
> > +{
> > +     unsigned int len;
> > +     u64 serial;
> > +
> > +     len = snprintf(name, CMA_NAME_MAX,
> > +                    "Vendor=%04hx:Device=%04hx:CC=%06x:REV=%02hhx",
> > +                    pdev->vendor, pdev->device, pdev->class, pdev->revision);
>
> The commit message mentions handling devices that mutate their identity
> at runtime, but this string is constructed using cached software state
> from probe time (like pdev->vendor).

This I'm not clear on. Do we need to call pci_bus_read_dev_vendor_id()
to get updated values?

>
> Since pci_get_dsn() reads the live hardware state, could a mutated device
> result in an inconsistent string containing a stale vendor/device ID but
> a new DSN? Will reauthentication fail without a full PCI rescan?
>
> Additionally, snprintf() returns the number of characters that would have
> been written, not the actual bytes written.

This is true

>
> If the inputs ever exceed the 79-byte CMA_NAME_MAX buffer (for instance,
> if a quirk mutates pdev->class to exceed 6 hex characters), the string
> will be truncated but len will reflect the untruncated size.

That's true, but I don't see how the fixed length format string could
exceed the size.

So I don't think this is an actual issue, but...

>
> Could this cause the later memcmp() check in pci_cma_note_san() to read
> out of bounds of the ctx->expected_name stack buffer? Should scnprintf()
> be used here instead to track the actual length written?

scnprintf() should be used instead, just in case.

>
> > +
> > +     if (pdev->hdr_type == PCI_HEADER_TYPE_NORMAL)
> > +             len += snprintf(name + len, CMA_NAME_MAX - len,
> > +                             ":SSVID=%04hx:SSID=%04hx",
> > +                             pdev->subsystem_vendor, pdev->subsystem_device);
>
> PCIe Type 1 devices (bridges) can also implement the Subsystem Vendor ID
> capability.
>
> If a Type 1 bridge implements this capability and includes these fields in
> its certificate as required by the specification, will this condition
> unconditionally omit them and cause validation to fail?
>
> > +
> > +     serial = pci_get_dsn(pdev);
> > +     if (serial)
> > +             len += snprintf(name + len, CMA_NAME_MAX - len,
> > +                             ":%016llx", serial);
> > +
> > +     return len;
> > +}
>
> Looking at pci_get_dsn(), it returns 0 both when the DSN capability is
> missing and when the device's legitimate serial number is 0.
>
> If a device implements the capability with a valid DSN of 0, will this
> check evaluate to false, omit the field, and reject a valid device?
>
> Would it be safer to explicitly check for the capability's presence via
> pci_find_ext_capability() instead?

I see your point, but I don't think so.

>
> Also, pci_get_dsn() performs two separate 32-bit reads without a lock:
>
> pci_read_config_dword(dev, pos, &dword);
> dsn = (u64)dword;
> pci_read_config_dword(dev, pos + 4, &dword);
> dsn |= ((u64)dword) << 32;
>
> Could a concurrent mutation of the device identity result in a torn
> 64-bit read during this check?

Really?

Alistair

>
> --
> Sashiko AI review · https://sashiko.dev/#/patchset/20260508031710.514574-1-alistair.francis@wdc.com?part=10

  reply	other threads:[~2026-05-14  2:46 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-08  3:16 [PATCH 00/18] lib: Rust implementation of SPDM alistair23
2026-05-08  3:16 ` [PATCH 01/18] rust: add untrusted data abstraction alistair23
2026-05-08  3:52   ` sashiko-bot
2026-05-08  5:17   ` Dirk Behme
2026-05-15  5:49     ` Alistair Francis
2026-05-08  3:16 ` [PATCH 02/18] X.509: Make certificate parser public alistair23
2026-05-08  3:45   ` sashiko-bot
2026-05-14  7:22     ` Lukas Wunner
2026-05-08  3:16 ` [PATCH 03/18] X.509: Parse Subject Alternative Name in certificates alistair23
2026-05-08  3:16 ` [PATCH 04/18] X.509: Move certificate length retrieval into new helper alistair23
2026-05-08  3:39   ` sashiko-bot
2026-05-14  6:59     ` Lukas Wunner
2026-05-08  3:16 ` [PATCH 05/18] rust: add bindings for hash.h alistair23
2026-05-08  3:43   ` sashiko-bot
2026-05-08  3:16 ` [PATCH 06/18] rust: error: impl From<FromBytesWithNulError> for Kernel Error alistair23
2026-05-08  3:51   ` sashiko-bot
2026-05-08  3:16 ` [PATCH 07/18] lib: rspdm: Initial commit of Rust SPDM alistair23
2026-05-08  3:41   ` sashiko-bot
2026-05-08  3:17 ` [PATCH 08/18] PCI/TSM: Support connecting to PCIe CMA devices alistair23
2026-05-20  5:56   ` Alistair Francis
2026-06-18  2:04     ` Alistair Francis
2026-06-18 22:51       ` Dan Williams (nvidia)
2026-05-08  3:17 ` [PATCH 09/18] PCI/CMA: Add a PCI TSM CMA driver using SPDM alistair23
2026-05-08  5:02   ` sashiko-bot
2026-05-08  3:17 ` [PATCH 10/18] PCI/CMA: Validate Subject Alternative Name in certificates alistair23
2026-05-08  3:58   ` sashiko-bot
2026-05-14  2:45     ` Alistair Francis [this message]
2026-05-14 13:14       ` Lukas Wunner
2026-05-08  3:17 ` [PATCH 11/18] lib: rspdm: Support SPDM get_version alistair23
2026-05-08  3:50   ` sashiko-bot
2026-05-08  3:17 ` [PATCH 12/18] lib: rspdm: Support SPDM get_capabilities alistair23
2026-05-08  4:05   ` sashiko-bot
2026-05-08  3:17 ` [PATCH 13/18] lib: rspdm: Support SPDM negotiate_algorithms alistair23
2026-05-08  4:05   ` sashiko-bot
2026-05-08  3:17 ` [PATCH 14/18] lib: rspdm: Support SPDM get_digests alistair23
2026-05-08  4:06   ` sashiko-bot
2026-05-08  3:17 ` [PATCH 15/18] lib: rspdm: Support SPDM get_certificate alistair23
2026-05-08  4:23   ` sashiko-bot
2026-05-08  3:17 ` [PATCH 16/18] lib: rspdm: Support SPDM certificate validation alistair23
2026-05-08  4:25   ` sashiko-bot
2026-05-08  3:17 ` [PATCH 17/18] rust: allow extracting the buffer from a CString alistair23
2026-05-08  3:17 ` [PATCH 18/18] lib: rspdm: Support SPDM challenge alistair23
2026-05-08  4:19   ` sashiko-bot
2026-05-17  8:09   ` Dirk Behme

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='CAKmqyKMti4wxuU-uRcLXLnXpXTHGajHkx=7zt54FDLUry+mP6Q@mail.gmail.com' \
    --to=alistair23@gmail.com \
    --cc=linux-pci@vger.kernel.org \
    --cc=lukas@wunner.de \
    --cc=ojeda@kernel.org \
    --cc=sashiko@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;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).