All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Gary Guo" <gary@garyguo.net>
Cc: dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
	conor+dt@kernel.org, robh@kernel.org, linux-pci@vger.kernel.org,
	"Danilo Krummrich" <dakr@kernel.org>,
	ojeda@kernel.org, "Alexandre Courbot" <acourbot@nvidia.com>
Subject: Re: [PATCH 07/10] rust: driver: store pointers in `DeviceId`
Date: Fri, 19 Jun 2026 17:05:08 +0000	[thread overview]
Message-ID: <20260619170508.8E9351F00A3E@smtp.kernel.org> (raw)
In-Reply-To: <20260618-id_info-v1-7-96af1e559ef9@garyguo.net>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Critical] Arbitrary Memory Dereference / Privilege Escalation via PCI dynamic IDs (`new_id`)
- [High] Undefined Behavior via unconditional null reference creation when `driver_data` is 0
--

commit 01871465d12a97f7be006ca329ebda24f458cf1e
Author: Gary Guo <gary@garyguo.net>

rust: driver: store pointers in `DeviceId`

This commit changes Rust device IDs to store pointers directly in the
driver_data field, matching the behavior of C drivers. It works around
the limitation of missing provenance during const evaluation by wrapping
raw IDs in MaybeUninit.

> diff --git a/rust/kernel/device_id.rs b/rust/kernel/device_id.rs
> index 84852a2d9ad78..59453588df0e7 100644
> --- a/rust/kernel/device_id.rs
> +++ b/rust/kernel/device_id.rs
[ ... ]
> @@ -47,15 +50,48 @@ pub unsafe trait RawDeviceIdIndex: RawDeviceId {
>      /// The offset (in bytes) to the context/data field in the raw device ID.
>      const DRIVER_DATA_OFFSET: usize;
>  
> -    /// The index stored at `DRIVER_DATA_OFFSET` of the implementor of the [`RawDeviceIdIndex`]
> -    /// trait.
> -    fn index(&self) -> usize;
> +    /// Obtain the data pointer stored inside the device ID.
> +    ///
> +    /// # Safety
> +    ///
> +    /// `&Self` must be stored inside a `IdArray<Self, U>`.
> +    unsafe fn info_unchecked<U>(&self) -> &'static U {
> +        // SAFETY: By safety requirement of the trait, this is `self.driver_data as *const U` and by
> +        // the safety requirement of the function, this is stored in `IdArray<Self, U>` so is
> +        // convertible to `&'static U`.
> +        unsafe {
> +            core::ptr::from_ref(self)
> +                .byte_add(Self::DRIVER_DATA_OFFSET)
> +                .cast::<&U>()
> +                .read()
> +        }
> +    }

[Severity: High]
Does this code create an unconditional null reference in Rust if the
driver_data or driver_info field is 0?

Creating a null reference is immediate undefined behavior in Rust, even for
zero-sized types. This 0 value can occur in paths like:

1. IdArray::new_without_index() leaving driver_data fields as 0.

2. When userspace adds a dynamic USB ID via the sysfs new_id interface using
fewer than 5 fields (omitting refVendor), USB core initializes driver_info
to 0.

[ ... ]
> diff --git a/rust/kernel/pci.rs b/rust/kernel/pci.rs
> index a3dd48f763532..a630c7fc6a853 100644
> --- a/rust/kernel/pci.rs
> +++ b/rust/kernel/pci.rs
[ ... ]
> @@ -110,10 +110,13 @@ extern "C" fn probe_callback(
>          // SAFETY: `DeviceId` is a `#[repr(transparent)]` wrapper of `struct pci_device_id` and
>          // does not add additional invariants, so it's safe to transmute.
>          let id = unsafe { &*id.cast::<DeviceId>() };
> -        let info = T::ID_TABLE.info(id.index());
> +
> +        // SAFETY: `id` comes from `T::ID_TABLE` which is of type `IdArray<_, T::IdInfo>` or
> +        // `pci_device_id_any` which has 0 as driver_data.
> +        let info = unsafe { id.info_unchecked_opt::<T::IdInfo>() };

[Severity: Critical]
Can this allow an arbitrary memory dereference or bypass kernel lockdown?

The PCI subsystem supports dynamic IDs via the sysfs new_id interface
(drivers/pci/pci-driver.c), which parses up to 7 arguments, the last being
driver_data (%lx).

This allows a privileged user (root) to supply an arbitrary pointer value.
The code here will blindly cast this integer to an Option<&'static U> via
info_unchecked_opt() and dereference it if non-zero, allowing arbitrary
kernel memory access.

[ ... ]
> diff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs
> index 500b5e0ba4ea9..8aeff50117552 100644
> --- a/rust/kernel/usb.rs
> +++ b/rust/kernel/usb.rs
[ ... ]
> @@ -89,7 +89,8 @@ extern "C" fn probe_callback(
>              // does not add additional invariants, so it's safe to transmute.
>              let id = unsafe { &*id.cast::<DeviceId>() };
>  
> -            let info = T::ID_TABLE.info(id.index());
> +            // SAFETY: `id` comes from `T::ID_TABLE` which is of type `IdArray<_, T::IdInfo>`.
> +            let info = unsafe { id.info_unchecked::<T::IdInfo>() };
>              let data = T::probe(intf, id, info);

[Severity: High]
Does this code trigger undefined behavior when the underlying USB device ID
driver_info field is 0?

When the id is constructed using IdArray::new_without_index() or when
dynamically added via sysfs new_id with fewer fields, the driver_info is 0.

This probe unconditionally expects a valid non-null reference and creates
one even for 0-initialized IDs via info_unchecked().

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260618-id_info-v1-0-96af1e559ef9@garyguo.net?part=7

  reply	other threads:[~2026-06-19 17:05 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-18 17:03 [PATCH 00/10] rust: driver: use pointers instead of indices for ID info Gary Guo
2026-06-18 17:03 ` Gary Guo
2026-06-18 17:03 ` [PATCH 01/10] rust: driver: remove `IdTable::id` Gary Guo
2026-06-18 17:03   ` Gary Guo
2026-06-19 17:05   ` sashiko-bot
2026-06-18 17:03 ` [PATCH 02/10] rust: driver: simplify `IdArray::new_without_index` Gary Guo
2026-06-18 17:03   ` Gary Guo
2026-06-19 17:05   ` sashiko-bot
2026-06-18 17:03 ` [PATCH 03/10] rust: pci: use `Option<&IdInfo>` for device ID info Gary Guo
2026-06-18 17:03   ` Gary Guo
2026-06-19 17:05   ` sashiko-bot
2026-06-18 17:03 ` [PATCH 04/10] rust: net/phy: remove expansion from doc Gary Guo
2026-06-18 17:03   ` Gary Guo
2026-06-19 17:05   ` sashiko-bot
2026-06-18 17:03 ` [PATCH 05/10] rust: driver: centralize device ID handling Gary Guo
2026-06-18 17:03   ` Gary Guo
2026-06-19 17:05   ` sashiko-bot
2026-06-18 17:03 ` [PATCH 06/10] rust: driver: remove `$module_table_name` from `module_device_table` Gary Guo
2026-06-18 17:03   ` Gary Guo
2026-06-19 17:05   ` sashiko-bot
2026-06-18 17:03 ` [PATCH 07/10] rust: driver: store pointers in `DeviceId` Gary Guo
2026-06-18 17:03   ` Gary Guo
2026-06-19 17:05   ` sashiko-bot [this message]
2026-06-19 17:12     ` Gary Guo
2026-06-18 17:03 ` [PATCH 08/10] rust: driver: remove open-coded matching logic Gary Guo
2026-06-18 17:03   ` Gary Guo
2026-06-19 17:05   ` sashiko-bot
2026-06-18 17:03 ` [PATCH 09/10] rust: driver: remove duplicate ID table Gary Guo
2026-06-18 17:03   ` Gary Guo
2026-06-19 17:05   ` sashiko-bot
2026-06-18 17:03 ` [PATCH 10/10] RFC: rust: driver: support map-like syntax for " Gary Guo
2026-06-18 17:03   ` Gary Guo
2026-06-19 17:05   ` 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=20260619170508.8E9351F00A3E@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=acourbot@nvidia.com \
    --cc=conor+dt@kernel.org \
    --cc=dakr@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gary@garyguo.net \
    --cc=linux-pci@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=robh@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.