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: <87o7bfr7bt.fsf@metaspace.dk>
Date: Fri, 15 Mar 2024 13:46:30 +0100
From: Andreas Hindborg <nmi@...aspace.dk>
To: Ming Lei <ming.lei@...hat.com>
Cc: Miguel Ojeda <miguel.ojeda.sandonis@...il.com>,  Jens Axboe
 <axboe@...nel.dk>,  Keith Busch <kbusch@...nel.org>,  Boqun Feng
 <boqun.feng@...il.com>,  Christoph Hellwig <hch@....de>,  Damien Le Moal
 <Damien.LeMoal@....com>,  Bart Van Assche <bvanassche@....org>,  Hannes
 Reinecke <hare@...e.de>,  "linux-block@...r.kernel.org"
 <linux-block@...r.kernel.org>,  Andreas Hindborg <a.hindborg@...sung.com>,
  Wedson Almeida Filho <wedsonaf@...il.com>,  Niklas Cassel
 <Niklas.Cassel@....com>,  Greg KH <gregkh@...uxfoundation.org>,  Matthew
 Wilcox <willy@...radead.org>,  Miguel Ojeda <ojeda@...nel.org>,  Alex
 Gaynor <alex.gaynor@...il.com>,  Gary Guo <gary@...yguo.net>,
  Björn Roy
 Baron <bjorn3_gh@...tonmail.com>,  Benno Lossin <benno.lossin@...ton.me>,
  Alice Ryhl <aliceryhl@...gle.com>,  Chaitanya Kulkarni
 <chaitanyak@...dia.com>,  Luis Chamberlain <mcgrof@...nel.org>,  Yexuan
 Yang <1182282462@...t.edu.cn>,  Sergio González Collado
 <sergio.collado@...il.com>,  Joel Granados <j.granados@...sung.com>,
  "Pankaj Raghav (Samsung)" <kernel@...kajraghav.com>,  Daniel Gomez
 <da.gomez@...sung.com>,  open list <linux-kernel@...r.kernel.org>,
  "rust-for-linux@...r.kernel.org" <rust-for-linux@...r.kernel.org>,
  "lsf-pc@...ts.linux-foundation.org" <lsf-pc@...ts.linux-foundation.org>,
  "gost.dev@...sung.com" <gost.dev@...sung.com>
Subject: Re: [RFC PATCH 1/5] rust: block: introduce `kernel::block::mq` module

Ming Lei <ming.lei@...hat.com> writes:
> On Fri, Mar 15, 2024 at 08:52:46AM +0100, Andreas Hindborg wrote:
>> Miguel Ojeda <miguel.ojeda.sandonis@...il.com> writes:
>> 
>> > On Thu, Mar 14, 2024 at 8:23 PM Andreas Hindborg <nmi@...aspace.dk> wrote:
>> >>
>> >> The way the current code compiles, <kernel::block::mq::Request as
>> >> kernel::types::AlwaysRefCounted>::dec_ref` is inlined into the `rnull`
>> >> module. A relocation for `rust_helper_blk_mq_free_request_internal`
>> >> appears in `rnull_mod.ko`. I didn't test it yet, but if
>> >> `__blk_mq_free_request` (or the helper) is not exported, I don't think
>> >> this would be possible?
>> >
>> > Yeah, something needs to be exported since there is a generic
>> > involved, but even if you want to go the route of exporting only a
>> > different symbol, you would still want to put it in the C header so
>> > that you don't get the C missing declaration warning and so that we
>> > don't have to write the declaration manually in the helper.
>> 
>> That is what I did:
>> 
>> @@ -703,6 +703,7 @@ int blk_mq_alloc_sq_tag_set(struct blk_mq_tag_set *set,
>>  		unsigned int set_flags);
>>  void blk_mq_free_tag_set(struct blk_mq_tag_set *set);
>>  
>> +void __blk_mq_free_request(struct request *rq);
>>  void blk_mq_free_request(struct request *rq);
>>  int blk_rq_poll(struct request *rq, struct io_comp_batch *iob,
>>  		unsigned int poll_flags);
>
> Can you explain in detail why one block layer internal helper is
> called into rnull driver directly? It never happens in C driver code.

It is not the rust null block driver that calls this symbol directly. It
is called by the Rust block device driver API. But because of inlining,
the symbol is referenced from the loadable object.

The reason we have to call this symbol directly is to ensure proper
lifetime of the `struct request`. For example in C, when a driver
converts a tag to a request, the developer makes sure to only ask for
requests which are outstanding in the driver. In Rust, for the API to be
sound, we must ensure that the developer cannot write safe code that
obtains a reference to a request that is not owned by the driver.

A similar issue exists in the null block driver when timer completions
are enabled. If the request is cancelled and the timer fires after the
request has been recycled, there is a problem because the timer holds a
reference to the request private data area.

To that end, I use the `atomic_t ref` field of the C `struct request`
and implement the `AlwaysRefCounted` Rust trait for the request type.
This is a smart pointer that owns a reference to the pointee. In this
way, the request is not freed and recycled until the smart pointer is
dropped. But if the smart pointer holds the last reference when it is
dropped, it must be able to free the request, and hence it has to call
`__blk_mq_free_request`.

We could tag the function with `#[inline(never)]`, but that would impact
performance.

Best regards,
Andreas

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ