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: <20240815224234.561de1b5.gary@garyguo.net>
Date: Thu, 15 Aug 2024 22:42:34 +0100
From: Gary Guo <gary@...yguo.net>
To: Boqun Feng <boqun.feng@...il.com>
Cc: Alice Ryhl <aliceryhl@...gle.com>, Andreas Hindborg <nmi@...aspace.dk>,
 Jens Axboe <axboe@...nel.dk>, Miguel Ojeda <ojeda@...nel.org>, Alex Gaynor
 <alex.gaynor@...il.com>, Wedson Almeida Filho <wedsonaf@...il.com>, Andreas
 Hindborg <a.hindborg@...sung.com>, "Behme Dirk (XC-CP/ESB5)"
 <Dirk.Behme@...bosch.com>, Björn Roy Baron
 <bjorn3_gh@...tonmail.com>, Benno Lossin <benno.lossin@...ton.me>,
 "linux-block@...r.kernel.org" <linux-block@...r.kernel.org>,
 rust-for-linux@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: Re: [PATCH 2/2] rust: block: fix wrong usage of lockdep API

On Thu, 15 Aug 2024 14:32:28 -0700
Boqun Feng <boqun.feng@...il.com> wrote:

> On Thu, Aug 15, 2024 at 08:07:38PM +0100, Gary Guo wrote:
> > On Thu, 15 Aug 2024 10:04:56 +0200
> > Alice Ryhl <aliceryhl@...gle.com> wrote:
> >   
> > > On Thu, Aug 15, 2024 at 9:49 AM Andreas Hindborg <nmi@...aspace.dk> wrote:  
> > > >
> > > > From: Andreas Hindborg <a.hindborg@...sung.com>
> > > >
> > > > When allocating `struct gendisk`, `GenDiskBuilder` is using a dynamic lock
> > > > class key without registering the key. This is incorrect use of the API,
> > > > which causes a `WARN` trace. This patch fixes the issue by using a static
> > > > lock class key, which is more appropriate for the situation anyway.
> > > >
> > > > Fixes: 3253aba3408a ("rust: block: introduce `kernel::block::mq` module")
> > > > Reported-by: "Behme Dirk (XC-CP/ESB5)" <Dirk.Behme@...bosch.com>
> > > > Closes: https://rust-for-linux.zulipchat.com/#narrow/stream/288089-General/topic/6.2E11.2E0-rc1.3A.20rust.2Fkernel.2Fblock.2Fmq.2Ers.3A.20doctest.20lock.20warning
> > > > Signed-off-by: Andreas Hindborg <a.hindborg@...sung.com>    
> > > 
> > > LGTM. This makes me wonder if there's some design mistake in how we
> > > handle lock classes in Rust.
> > > 
> > > Reviewed-by: Alice Ryhl <aliceryhl@...gle.com>  
> > 
> > I agree. The API that we current have is designed without much
> > consideration into dynamically allocated keys, and we use `&'static
> > LockClassKey` in a lot of kernel crate APIs.
> > 
> > This arguably is wrong, because presence of `&'static LockClassKey`
> > doesn't mean the key is static. If we do a
> > `Box::leak(Box::new(LockClassKey::new()))`, then this is a `&'static
> > LockClassKey`, but lockdep wouldn't consider this as a static object.
> > 
> > Maybe we should make the `new` function unsafe.
> >   
> 
> I think a more proper fix is to make LockClassKey pin-init, for
> dynamically allocated LockClassKey, we just use lockdep_register_key()
> as the initializer and lockdep_unregister_key() as the desconstructor.
> And instead of a `&'static LockClassKey`, we should use `Pin<&'static
> LockClassKey>` to pass a lock class key. Of course we will need some  
> special treatment on static allocated keys (e.g. assume they are
> initialized since lockdep doesn't require initialization for them).
> 
> 
> Pin initializer:
> 
> 	impl LockClassKey {
> 	    pub fn new() -> impl PinInit<Self> {
> 		pin_init!(Self {
> 		    inner <- Opaque::ffi_init(|slot| { lockdep_register_key(slot) })
> 		})
> 	    }
> 	}
> 
> LockClassKey::new_uninit() for `static_lock_class!`:
> 
> 
> 	impl LockClassKey {
> 	    pub const fn new_uninit() -> MaybeUninit<Self> {
> 	        ....
> 	    }
> 	}
> 
> and the new `static_lock_class!`:
> 
> 	macro_rules! static_lock_class {
> 	    () => {{
> 		static CLASS: MaybeUninit<$crate::sync::LockClassKey> = $crate::sync::LockClassKey::new_uninit();

nit: this could just be `MaybeUninit::uninit()`

> 
> 	        // SAFETY: `CLASS` is pinned because it's static
> 		// allocated. And it's OK to assume it's initialized
> 		// because lockdep support uninitialized static
> 		// allocated key.
> 		unsafe { Pin::new_unchecked(CLASS.assume_init_ref()) }

nit: this could be `Pin::from_static(unsafe { CLASS.assume_init_ref() })`

> 	    }};
> 	}
> 
> Thoughts?

I think this design looks good. I suggested adding unsafe as a quick
way to address the pontential misuse, when we have no user for
dynamically allocated keys.

Best,
Gary

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ