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: <VEhpQqgTM0U-aNYRUQ89ICIHW9Eehr66yw92DrmBZcZOah2mLqlz24HxEwDwYPVDOnaigDiZDEVl5mWqZJxoAtRheqTMjzpxuTKe0sr1uZs=@proton.me>
Date:   Wed, 25 Oct 2023 21:51:28 +0000
From:   Benno Lossin <benno.lossin@...ton.me>
To:     Boqun Feng <boqun.feng@...il.com>
Cc:     rust-for-linux@...r.kernel.org, linux-kernel@...r.kernel.org,
        linux-arch@...r.kernel.org, llvm@...ts.linux.dev,
        Miguel Ojeda <ojeda@...nel.org>,
        Alex Gaynor <alex.gaynor@...il.com>,
        Wedson Almeida Filho <wedsonaf@...il.com>,
        Gary Guo <gary@...yguo.net>,
        Björn Roy Baron <bjorn3_gh@...tonmail.com>,
        Andreas Hindborg <a.hindborg@...sung.com>,
        Alice Ryhl <aliceryhl@...gle.com>,
        Alan Stern <stern@...land.harvard.edu>,
        Andrea Parri <parri.andrea@...il.com>,
        Will Deacon <will@...nel.org>,
        Peter Zijlstra <peterz@...radead.org>,
        Nicholas Piggin <npiggin@...il.com>,
        David Howells <dhowells@...hat.com>,
        Jade Alglave <j.alglave@....ac.uk>,
        Luc Maranget <luc.maranget@...ia.fr>,
        "Paul E. McKenney" <paulmck@...nel.org>,
        Akira Yokosawa <akiyks@...il.com>,
        Daniel Lustig <dlustig@...dia.com>,
        Joel Fernandes <joel@...lfernandes.org>,
        Nathan Chancellor <nathan@...nel.org>,
        Nick Desaulniers <ndesaulniers@...gle.com>,
        Tom Rix <trix@...hat.com>,
        Alexander Viro <viro@...iv.linux.org.uk>,
        Christian Brauner <brauner@...nel.org>,
        kent.overstreet@...il.com,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
        elver@...gle.com, Matthew Wilcox <willy@...radead.org>,
        Dave Chinner <david@...morbit.com>,
        linux-fsdevel@...r.kernel.org
Subject: Re: [RFC] rust: types: Add read_once and write_once

> In theory, `read_volatile` and `write_volatile` in Rust can have UB in
> case of the data races [1]. However, kernel uses volatiles to implement

I would not write "In theory", but rather state that data races involving
`read_volatile` is documented to still be UB.

> READ_ONCE() and WRITE_ONCE(), and expects races on these marked accesses

Missing "`"?

> don't cause UB. And they are proven to have a lot of usages in kernel.
> 
> To close this gap, `read_once` and `write_once` are introduced, they
> have the same semantics as `READ_ONCE` and `WRITE_ONCE` especially
> regarding data races under the assumption that `read_volatile` and

I would separate implementation from specification. We specify
`read_once` and `write_once` to have the same semantics as `READ_ONCE`
and `WRITE_ONCE`. But we implement them using
`read_volatile`/`write_volatile`, so we might still encounter UB, but it
is still a sort of best effort. As soon as we have the actual thing in
Rust, we will switch the implementation.

> `write_volatile` have the same behavior as a volatile pointer in C from
> a compiler point of view.
> 
> Longer term solution is to work with Rust language side for a better way
> to implement `read_once` and `write_once`. But so far, it should be good
> enough.
> 
> Suggested-by: Alice Ryhl <aliceryhl@...gle.com>
> Link: https://doc.rust-lang.org/std/ptr/fn.read_volatile.html#safety [1]
> Signed-off-by: Boqun Feng <boqun.feng@...il.com>
> ---
> 
> Notice I also make the primitives only work on T: Copy, since I don't
> think Rust side and C side will use a !Copy type to communicate, but we
> can always remove that constrait later.
> 
> 
>  rust/kernel/prelude.rs |  2 ++
>  rust/kernel/types.rs   | 43 ++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 45 insertions(+)
> 
> diff --git a/rust/kernel/prelude.rs b/rust/kernel/prelude.rs
> index ae21600970b3..351ad182bc63 100644
> --- a/rust/kernel/prelude.rs
> +++ b/rust/kernel/prelude.rs
> @@ -38,3 +38,5 @@
>  pub use super::init::{InPlaceInit, Init, PinInit};
> 
>  pub use super::current;
> +
> +pub use super::types::{read_once, write_once};

Do we really want people to use these so often that they should be in
the prelude?

Sure there will not really be any name conflicts, but I think an
explicit import might make sense.

> diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs
> index d849e1979ac7..b0872f751f97 100644
> --- a/rust/kernel/types.rs
> +++ b/rust/kernel/types.rs

I don't think this should go into `types.rs`. But I do not have a good
name for the new module.

> @@ -432,3 +432,46 @@ pub enum Either<L, R> {
>      /// Constructs an instance of [`Either`] containing a value of type `R`.
>      Right(R),
>  }
> +
> +/// (Concurrent) Primitives to interact with C side, which are considered as marked access:
> +///
> +/// tools/memory-memory/Documentation/access-marking.txt
> +

Accidental empty line? Or is this meant as a comment for both
functions?

> +/// The counter part of C `READ_ONCE()`.
> +///
> +/// The semantics is exactly the same as `READ_ONCE()`, especially when used for intentional data
> +/// races.

It would be great if these semantics are either linked or spelled out
here. Ideally both.

> +///
> +/// # Safety
> +///
> +/// * `src` must be valid for reads.
> +/// * `src` must be properly aligned.
> +/// * `src` must point to a properly initialized value of value `T`.
> +#[inline(always)]
> +pub unsafe fn read_once<T: Copy>(src: *const T) -> T {

Why only `T: Copy`?

> +    // SAFETY: the read is valid because of the function's safety requirement, plus the assumption
> +    // here is that 1) a volatile pointer dereference in C and 2) a `read_volatile` in Rust have the
> +    // same semantics, so this function should have the same behavior as `READ_ONCE()` regarding
> +    // data races.

I would explicitly state that we might have UB here due to data races.
But that we have not seen any invalid codegen and thus assume there to
be no UB (you might also want to write this in the commit message).

--
Cheers,
Benno

> +    unsafe { src.read_volatile() }
> +}
> +
> +/// The counter part of C `WRITE_ONCE()`.
> +///
> +/// The semantics is exactly the same as `WRITE_ONCE()`, especially when used for intentional data
> +/// races.
> +///
> +/// # Safety
> +///
> +/// * `dst` must be valid for writes.
> +/// * `dst` must be properly aligned.
> +#[inline(always)]
> +pub unsafe fn write_once<T: Copy>(dst: *mut T, value: T) {
> +    // SAFETY: the write is valid because of the function's safety requirement, plus the assumption
> +    // here is that 1) a write to a volatile pointer dereference in C and 2) a `write_volatile` in
> +    // Rust have the same semantics, so this function should have the same behavior as
> +    // `WRITE_ONCE()` regarding data races.
> +    unsafe {
> +        core::ptr::write_volatile(dst, value);
> +    }
> +}
> --
> 2.41.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ