lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <DFBFMTS0ZRDB.30O3L4GMYW4XJ@kernel.org>
Date: Tue, 30 Dec 2025 10:09:51 +0100
From: "Benno Lossin" <lossin@...nel.org>
To: "Jesung Yang" <y.j3ms.n@...il.com>
Cc: "Miguel Ojeda" <ojeda@...nel.org>, "Boqun Feng" <boqun.feng@...il.com>,
 "Gary Guo" <gary@...yguo.net>, Björn Roy Baron
 <bjorn3_gh@...tonmail.com>, "Andreas Hindborg" <a.hindborg@...nel.org>,
 "Alice Ryhl" <aliceryhl@...gle.com>, "Trevor Gross" <tmgross@...ch.edu>,
 "Danilo Krummrich" <dakr@...nel.org>, "Alexandre Courbot"
 <acourbot@...dia.com>, <linux-kernel@...r.kernel.org>,
 <rust-for-linux@...r.kernel.org>, <nouveau@...ts.freedesktop.org>
Subject: Re: [PATCH v4 1/4] rust: macros: add derive macro for `Into`

On Mon Dec 29, 2025 at 1:29 PM CET, Jesung Yang wrote:
> On Sat, Dec 27, 2025 at 1:57 PM Benno Lossin <lossin@...nel.org> wrote:
>> On Fri Dec 26, 2025 at 10:36 AM CET, Jesung Yang wrote:
>> > On Fri, Dec 26, 2025 at 2:40 AM Benno Lossin <lossin@...nel.org> wrote:
>> >> On Thu Dec 25, 2025 at 9:37 AM CET, Jesung Yang via B4 Relay wrote:
>> >> > +    // Note on field-less `repr(C)` enums (quote from [1]):
>> >> > +    //
>> >> > +    //   In C, enums with discriminants that do not all fit into an `int` or all fit into an
>> >> > +    //   `unsigned int` are a portability hazard: such enums are only permitted since C23, and not
>> >> > +    //   supported e.g. by MSVC.
>> >> > +    //
>> >> > +    //   Furthermore, Rust interprets the discriminant values of `repr(C)` enums as expressions of
>> >> > +    //   type `isize`. This makes it impossible to implement the C23 behavior of enums where the
>> >> > +    //   enum discriminants have no predefined type and instead the enum uses a type large enough
>> >> > +    //   to hold all discriminants.
>> >> > +    //
>> >> > +    //   Therefore, `repr(C)` enums in Rust require that either all discriminants to fit into a C
>> >> > +    //   `int` or they all fit into an `unsigned int`.
>> >> > +    //
>> >> > +    // As such, `isize` is a reasonable representation for `repr(C)` enums, as it covers the range
>> >> > +    //  of both `int` and `unsigned int`.
>> >> > +    //
>> >> > +    // For more information, see:
>> >> > +    // - https://github.com/rust-lang/rust/issues/124403
>> >> > +    // - https://github.com/rust-lang/rust/pull/147017
>> >> > +    // - https://github.com/rust-lang/rust/blob/2ca7bcd03b87b52f7055a59b817443b0ac4a530d/compiler/rustc_lint_defs/src/builtin.rs#L5251-L5263 [1]
>> >> > +
>> >> > +    // Extract the representation passed by `#[repr(...)]` if present. If nothing is
>> >> > +    // specified, the default is `Rust` representation, which uses `isize` for its
>> >> > +    // discriminant type.
>> >> > +    // See: https://doc.rust-lang.org/reference/items/enumerations.html#r-items.enum.discriminant.repr-rust
>> >>
>> >> I think we should error when no `#[repr({integer})]` attribute is
>> >> specified.
>> >
>> > Not a blocker but just out of curiosity: are you concerned that the
>> > default size might change in the future, leading to silent side
>> > effects?
>>
>> `isize` already changes size when you switch between 64 and 32 bit
>> architectures. I think the author of an enum they want to convert into
>> integers should think about which size the enum should be.
>>
>> They already can choose `repr(isize)` if that is correct in that case.
>> As a default, I would have choosen `i32` (but that conflicts with Rust's
>> default, so we can't do it).
>
> On second thought, I've realized that enforcing an error when
> `#[repr({integer})]` is missing would prevent users from deriving
> traits for `#[repr(C)]` enums. This is because rustc currently rejects
> the combined `#[repr(C, {integer})]` syntax. For example, a user might

It's only rejected for field-less enums, but those are what we're
interested here.

> want to do this:
>
>     #[derive(Into)]
>     #[into(u8)]
>     #[repr(C)]
>     enum Foo {
>         A,
>         B,
>     }
>
> In this case, the code wouldn't compile if we strictly require
> `#[repr({integer})]`, even if the user carefully picked `u8`, keeping
> the enum's size (more precisely, the discriminant range) in mind.
>
> Since we already perform a compile-time check to ensure all
> discriminants fit within the types specified in the helper attributes,
> I believe `#[repr({integer})]` isn't strictly required. Even with
> `isize` changing size across architectures, our compile-time check
> remains effective and will catch any overflows.

Hmm that's true.

> To sum up, I see three options:
>
>     1. Drop support for `#[repr(C)]` enums entirely.
>     2. Special-case `#[repr(C)]` enums: allow them to default to
>        `isize`, otherwise require `#[repr({integer})]`.
>     3. Permit missing `#[repr({integer})]` generally.
>
> I am personally leaning toward Option 3, since our existing
> compile-time check provides a sufficient safety margin to allow this
> flexibility.
>
> Thoughts on these?

Looking at the nomicon documentation [1] again, I found the following:

    repr(C) is equivalent to one of repr(u*) (see the next section) for
    fieldless enums. The chosen size and sign is the default enum size
    and sign for the target platform's C application binary interface
    (ABI). Note that enum representation in C is implementation defined,
    so this is really a "best guess". In particular, this may be
    incorrect when the C code of interest is compiled with certain
    flags.

Which to me reads as "don't use `repr(C)`, if you want to know which
repr the enum gets". Especially the last part is concerning to me, as
the kernel uses lots of (bespoke) compiler flags. So I'm thinking we
should just drop `repr(C)` enum support. Any thoughts from others?

[1]: https://doc.rust-lang.org/nomicon/other-reprs.html

Cheers,
Benno

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ