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: <20230202142421.7ab724dc.gary@garyguo.net> Date: Thu, 2 Feb 2023 14:24:21 +0000 From: Gary Guo <gary@...yguo.net> To: Boqun Feng <boqun.feng@...il.com> Cc: rust-for-linux@...r.kernel.org, linux-kernel@...r.kernel.org, Will Deacon <will@...nel.org>, Peter Zijlstra <peterz@...radead.org>, Mark Rutland <mark.rutland@....com>, Miguel Ojeda <ojeda@...nel.org>, Alex Gaynor <alex.gaynor@...il.com>, Wedson Almeida Filho <wedsonaf@...il.com>, Björn Roy Baron <bjorn3_gh@...tonmail.com>, Vincenzo Palazzo <vincenzopalazzodev@...il.com> Subject: Re: [RFC 3/5] rust: sync: Arc: Introduces Arc::get_inner() helper On Wed, 1 Feb 2023 15:22:42 -0800 Boqun Feng <boqun.feng@...il.com> wrote: > Getting a `&ArcInner<T>` should always be safe from a `Arc<T>`, > therefore add this helper function to avoid duplicate unsafe > `ptr.as_ref()`. > > Signed-off-by: Boqun Feng <boqun.feng@...il.com> Reviewed-by: Gary Guo <gary@...yguo.net> > --- > rust/kernel/sync/arc.rs | 19 ++++++++++--------- > 1 file changed, 10 insertions(+), 9 deletions(-) > > diff --git a/rust/kernel/sync/arc.rs b/rust/kernel/sync/arc.rs > index fbfceaa3096e..4d8de20c996f 100644 > --- a/rust/kernel/sync/arc.rs > +++ b/rust/kernel/sync/arc.rs > @@ -201,6 +201,13 @@ impl<T: ?Sized> Arc<T> { > // reference can be created. > unsafe { ArcBorrow::new(self.ptr) } > } > + > + /// Returns a reference to the internal [`ArcInner`]. > + fn get_inner(&self) -> &ArcInner<T> { > + // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is > + // safe to dereference it. > + unsafe { self.ptr.as_ref() } > + } > } > > impl<T: 'static> ForeignOwnable for Arc<T> { > @@ -233,9 +240,7 @@ impl<T: ?Sized> Deref for Arc<T> { > type Target = T; > > fn deref(&self) -> &Self::Target { > - // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is > - // safe to dereference it. > - unsafe { &self.ptr.as_ref().data } > + &self.get_inner().data > } > } > > @@ -244,7 +249,7 @@ impl<T: ?Sized> Clone for Arc<T> { > // INVARIANT: C `refcount_inc` saturates the refcount, so it cannot overflow to zero. > // SAFETY: By the type invariant, there is necessarily a reference to the object, so it is > // safe to increment the refcount. > - unsafe { bindings::refcount_inc(self.ptr.as_ref().refcount.get()) }; > + unsafe { bindings::refcount_inc(self.get_inner().refcount.get()) }; > > // SAFETY: We just incremented the refcount. This increment is now owned by the new `Arc`. > unsafe { Self::from_inner(self.ptr) } > @@ -253,11 +258,7 @@ impl<T: ?Sized> Clone for Arc<T> { > > impl<T: ?Sized> Drop for Arc<T> { > fn drop(&mut self) { > - // SAFETY: By the type invariant, there is necessarily a reference to the object. We cannot > - // touch `refcount` after it's decremented to a non-zero value because another thread/CPU > - // may concurrently decrement it to zero and free it. It is ok to have a raw pointer to > - // freed/invalid memory as long as it is never dereferenced. > - let refcount = unsafe { self.ptr.as_ref() }.refcount.get(); > + let refcount = self.get_inner().refcount.get(); > > // INVARIANT: If the refcount reaches zero, there are no other instances of `Arc`, and > // this instance is being dropped, so the broken invariant is not observable.
Powered by blists - more mailing lists