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
next prev parent 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).