Re: [PATCH v4 2/3] rust: ptr: add projection infrastructure
From: Benno Lossin
Date: Mon Mar 02 2026 - 14:03:09 EST
On Mon Mar 2, 2026 at 5:42 PM CET, Gary Guo wrote:
> From: Gary Guo <gary@xxxxxxxxxxx>
>
> Add a generic infrastructure for performing field and index projections on
> raw pointers. This will form the basis of performing I/O projections.
>
> Pointers manipulations are intentionally using the safe wrapping variants
> instead of the unsafe variants, as the latter requires pointers to be
> inside an allocation which is not necessarily true for I/O pointers.
>
> This projection macro protects against rogue `Deref` implementation, which
> can causes the projected pointer to be outside the bounds of starting
> pointer. This is extremely unlikely and Rust has a lint to catch this, but
> is unsoundness regardless. The protection works by inducing type inference
> ambiguity when `Deref` is implemented.
>
> This projection macro also stops projecting into unaligned fields (i.e.
> fields of `#[repr(packed)]` structs), as misaligned pointers require
> special handling. This is implemented by attempting to create reference to
> projected field inside a `if false` block. Despite being unreachable, Rust
> still checks that they're not unaligned fields.
>
> The projection macro supports both fallible and infallible index
> projections. These are described in detail inside the documentation.
>
> Signed-off-by: Gary Guo <gary@xxxxxxxxxxx>
I have a naming concern with `ProjectIndex::get`, but that's only used
from the module & macro and unlikely to be used from the outside. So
renaming later should be easy.
Reviewed-by: Benno Lossin <lossin@xxxxxxxxxx>
Great work :)
Also found a typo below.
> ---
> rust/kernel/lib.rs | 3 +
> rust/kernel/ptr.rs | 3 +
> rust/kernel/ptr/projection.rs | 294 ++++++++++++++++++++++++++++++++++
> scripts/Makefile.build | 4 +-
> 4 files changed, 303 insertions(+), 1 deletion(-)
> create mode 100644 rust/kernel/ptr/projection.rs
> +/// A helper trait to perform field projection.
> +///
> +/// This trait has a `DEREF` generic parameter so it can be implemented twice for types that
> +/// implement `Deref`. This will cause an ambiguity error and thus block `Deref` types being used
> +/// as base of projection, as they can inject unsoundness. Users therefore must not specify `DEREF`
> +/// and should always leave it to be inferred.
> +///
> +/// # Safety
> +///
> +/// `proj` may only invoke `f` with a valid allocation, as documentation described.
s/described/describes/
Cheers,
Benno
> +#[doc(hidden)]
> +pub unsafe trait ProjectField<const DEREF: bool> {
> + /// Project a pointer to a type to a pointer of a field.
> + ///
> + /// `f` may only be invoked with a valid allocation so it can safely obtain raw pointers to
> + /// fields using `&raw mut`.
> + ///
> + /// This is needed because `base` might not point to a valid allocation, while `&raw mut`
> + /// requires pointers to be in bounds of a valid allocation.
> + ///
> + /// # Safety
> + ///
> + /// `f` must return a pointer in bounds of the provided pointer.
> + unsafe fn proj<F>(base: *mut Self, f: impl FnOnce(*mut Self) -> *mut F) -> *mut F;
> +}