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: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CANiq72kSdPvh81uOm=N-=37f7NT7udRV-PozfO2pcfbT6aaWyw@mail.gmail.com>
Date: Tue, 25 Feb 2025 23:45:09 +0100
From: Miguel Ojeda <miguel.ojeda.sandonis@...il.com>
To: Linus Torvalds <torvalds@...ux-foundation.org>
Cc: Kent Overstreet <kent.overstreet@...ux.dev>, Alice Ryhl <aliceryhl@...gle.com>, 
	Ventura Jack <venturajack85@...il.com>, Gary Guo <gary@...yguo.net>, airlied@...il.com, 
	boqun.feng@...il.com, david.laight.linux@...il.com, ej@...i.de, 
	gregkh@...uxfoundation.org, hch@...radead.org, hpa@...or.com, 
	ksummit@...ts.linux.dev, linux-kernel@...r.kernel.org, 
	rust-for-linux@...r.kernel.org, Ralf Jung <post@...fj.de>
Subject: Re: C aggregate passing (Rust kernel policy)

On Tue, Feb 25, 2025 at 9:25 PM Linus Torvalds
<torvalds@...ux-foundation.org> wrote:
>
> No, that's most definitely NOT the whole point of unsafe.

There are a few viewpoints here, which can be understood as correct in
different senses.

It is true that unsafe Rust is supposed to be used when you cannot
implement something in safe Rust (be it because the safe subset does
not support it or for performance reasons). In that sense, the point
of unsafe is indeed to expand on what you can implement.

It is also true that `unsafe` blocks in Rust are just a marker, and
that they don't change any particular rule -- they "only" enable a few
more operations (i.e the only "rule" they change is that you can call
those operations). Of course, with those extra operations one can then
implement things that normally one would not be able to.

So, for instance, the aliasing rules apply the same way within
`unsafe` blocks or outside them, and Rust currently passes LLVM the
information which does get used to optimize accordingly. In fact, Rust
generally passes so much aliasing information that it surfaced LLVM
bugs in the past that had to be fixed, since nobody else was
attempting that.

Now, the thing is that one can use pointer types that do not have
aliasing requirements, like raw pointers, especially when dealing with
`unsafe` things. And then one can wrap that into a nice API that
exposes safe (and unsafe) operations itself, e.g. an implementation of
`Vec` internally may use raw pointers, but expose a safe API.

As an example:

    fn f(p: &mut i32, q: &mut i32) -> i32 {
        *p = 42;
        *q = 24;
        *p
    }

optimizes exactly the same way as:

    fn f(p: &mut i32, q: &mut i32) -> i32 {
        unsafe {
            *p = 42;
            *q = 24;
            *p
        }
    }

Both of them are essentially `restrict`/`noalias`, and thus no load is
performed, with a constant 42 returned.

However, the following performs a load, because it uses raw pointers instead:

    fn f(p: *mut i32, q: *mut i32) -> i32 {
        unsafe {
            *p = 42;
            *q = 24;
            *p
        }
    }

The version with raw pointers without `unsafe` does not compile,
because dereferencing raw pointers is one of those things that unsafe
Rust unblocks.

One can also define types for which `&mut T` will behave like a raw
point here, too. That is one of the things we do when we wrap C
structs that the C side has access to.

Cheers,
Miguel

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ