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
| ||
|
Message-Id: <20250510-rust_unsafe_pinned-v3-3-57ce151123f9@gmail.com> Date: Sat, 10 May 2025 11:32:28 +0200 From: Christian Schrefl <chrisi.schrefl@...il.com> To: Sky <sky@...9.dev>, Miguel Ojeda <ojeda@...nel.org>, Alex Gaynor <alex.gaynor@...il.com>, Boqun Feng <boqun.feng@...il.com>, Gary Guo <gary@...yguo.net>, Björn Roy Baron <bjorn3_gh@...tonmail.com>, Benno Lossin <benno.lossin@...ton.me>, Andreas Hindborg <a.hindborg@...nel.org>, Alice Ryhl <aliceryhl@...gle.com>, Trevor Gross <tmgross@...ch.edu>, Danilo Krummrich <dakr@...nel.org>, Gerald Wisböck <gerald.wisboeck@...ther.ink>, Nathan Chancellor <nathan@...nel.org>, Nick Desaulniers <nick.desaulniers+lkml@...il.com>, Bill Wendling <morbo@...gle.com>, Justin Stitt <justinstitt@...gle.com> Cc: linux-kernel@...r.kernel.org, rust-for-linux@...r.kernel.org, llvm@...ts.linux.dev, Christian Schrefl <chrisi.schrefl@...il.com>, Benno Lossin <lossin@...nel.org> Subject: [PATCH v3 3/3] rust: use `UnsafePinned` in the implementation of `Opaque` Make the semantics of the `Opaque` implementation clearer and prepare for the switch to the upstream rust `UnsafePinned` type in the future. `Opaque` still uses `UnsafeCell` even though the kernel implementation of `UnsafePinned` already includes it, since the current upstream version does not. Reviewed-by: Gerald Wisböck <gerald.wisboeck@...ther.ink> Reviewed-by: Alice Ryhl <aliceryhl@...gle.com> Reviewed-by: Benno Lossin <lossin@...nel.org> Signed-off-by: Christian Schrefl <chrisi.schrefl@...il.com> --- rust/kernel/types.rs | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/rust/kernel/types.rs b/rust/kernel/types.rs index f06e8720e012102e5c41e79fd97b0607e927d71c..e32905c42453132fbea49d37a6457547d42465ce 100644 --- a/rust/kernel/types.rs +++ b/rust/kernel/types.rs @@ -4,12 +4,12 @@ use core::{ cell::UnsafeCell, - marker::{PhantomData, PhantomPinned}, + marker::PhantomData, mem::{ManuallyDrop, MaybeUninit}, ops::{Deref, DerefMut}, ptr::NonNull, }; -use pin_init::{PinInit, Wrapper, Zeroable}; +use pin_init::{cast_pin_init, PinInit, Wrapper, Zeroable}; /// Used to transfer ownership to and from foreign (non-Rust) languages. /// @@ -308,8 +308,10 @@ fn drop(&mut self) { /// ``` #[repr(transparent)] pub struct Opaque<T> { - value: UnsafeCell<MaybeUninit<T>>, - _pin: PhantomPinned, + // The kernel implementation of `UnsafePinned` uses `UnsafeCell` internally, but the + // upstream rust `UnsafePinned` will not. So to make sure this is compatible with + // the upstream version use `UnsafeCell` here. + value: UnsafePinned<UnsafeCell<MaybeUninit<T>>>, } // SAFETY: `Opaque<T>` allows the inner value to be any bit pattern, including all zeros. @@ -319,16 +321,14 @@ impl<T> Opaque<T> { /// Creates a new opaque value. pub const fn new(value: T) -> Self { Self { - value: UnsafeCell::new(MaybeUninit::new(value)), - _pin: PhantomPinned, + value: UnsafePinned::new(UnsafeCell::new(MaybeUninit::new(value))), } } /// Creates an uninitialised value. pub const fn uninit() -> Self { Self { - value: UnsafeCell::new(MaybeUninit::uninit()), - _pin: PhantomPinned, + value: UnsafePinned::new(UnsafeCell::new(MaybeUninit::uninit())), } } @@ -371,7 +371,7 @@ pub fn try_ffi_init<E>( /// Returns a raw pointer to the opaque data. pub const fn get(&self) -> *mut T { - UnsafeCell::get(&self.value).cast::<T>() + UnsafeCell::raw_get(self.value.get()).cast::<T>() } /// Gets the value behind `this`. @@ -384,14 +384,12 @@ pub const fn raw_get(this: *const Self) -> *mut T { } impl<T> Wrapper<T> for Opaque<T> { /// Create an opaque pin-initializer from the given pin-initializer. - fn pin_init<E>(slot: impl PinInit<T, E>) -> impl PinInit<Self, E> { - Self::try_ffi_init(|ptr: *mut T| { - // SAFETY: - // - `ptr` is a valid pointer to uninitialized memory, - // - `slot` is not accessed on error; the call is infallible, - // - `slot` is pinned in memory. - unsafe { PinInit::<T, E>::__pinned_init(slot, ptr) } - }) + fn pin_init<E>(value_init: impl PinInit<T, E>) -> impl PinInit<Self, E> { + let value_init = + UnsafePinned::pin_init(UnsafeCell::pin_init(MaybeUninit::pin_init(value_init))); + // SAFETY: `Opaque<T>` is a `repr(transparent)` wrapper around + // `UnsafePinned<UnsafeCell<MabeUninit<T>>>` so the memory representation is compatible. + unsafe { cast_pin_init(value_init) } } } -- 2.49.0
Powered by blists - more mailing lists