From: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
To: Paolo Bonzini <pbonzini@redhat.com>
Cc: qemu-devel <qemu-devel@nongnu.org>,
"Stefan Hajnoczi" <stefanha@redhat.com>,
"Mads Ynddal" <mads@ynddal.dk>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Alex Benné e" <alex.bennee@linaro.org>,
"Daniel P. Berrangé " <berrange@redhat.com>,
"Marc-André Lureau" <marcandre.lureau@redhat.com>,
"Thomas Huth" <thuth@redhat.com>,
"Markus Armbruster" <armbru@redhat.com>,
"Philippe Mathieu-Daudé " <philmd@linaro.org>,
"Zhao Liu" <zhao1.liu@intel.com>,
"Gustavo Romero" <gustavo.romero@linaro.org>,
"Pierrick Bouvier" <pierrick.bouvier@linaro.org>,
rowan.hart@intel.com,
"Richard Henderson" <richard.henderson@linaro.org>
Subject: Re: [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011
Date: Fri, 26 Jul 2024 10:12:19 +0300 [thread overview]
Message-ID: <h7zb4.aog50x8tfxkp@linaro.org> (raw)
In-Reply-To: <CABgObfb27wbwgErFsMdsuSo1BxQVBoRfbrUmK2k-x5Ya3ez0TA@mail.gmail.com>
On Thu, 25 Jul 2024 18:15, Paolo Bonzini <pbonzini@redhat.com> wrote:
>On Thu, Jul 25, 2024 at 4:48 PM Manos Pitsidianakis
><manos.pitsidianakis@linaro.org> wrote:
>> > pl011_receive (called by qemu_chr_fe_accept_input) creates a mutable
>> > reference that *overlaps* the lifetime of the outer reference created
>> > by pl011_read. This is undefined behavior. You're effectively writing:
>>
>> There is no overlap there, sorry. Once qemu_chr_fe_accept_input
>> returns, any references it created do not exist anymore.
>
>read |-------------|
>receive |-----|
>
>That's the overlap. Maybe you're thinking that the outer &mut "goes to
>sleep" and is reborn when qemu_chr_fe_accept_input() returns, but
>there's no such thing in the language.
There's no overlap, because the read scope is not live while receive is
active. References are linear types, when you give `&mut sth` as an
argument to a function call, you can model it in your mind as "giving
the mutual reference to the function call" and "receiving it back" when
it returns.
There'd be an overlap if qemu_chr_fe_accept_input got two mutual
references of the same memory location, such as calling foo(&mut self,
&mut self) with foo being `fn foo(a: &mut T, b: &mut T)`.
>
>You can do it within a function:
>
These examples you provide are not really equivalent.
>Honestly I don't see how I can provide a proof or explanation that is
>more definitive than miri. If some specific documentation or
>discussions gives you the perception that there is no undefined
>behavior, I'm happy to check them out and provide an explanation in
>that context. But otherwise, I don't think it's useful to keep
>debating *whether* it is undefined behavior.
Agreed! but thank you for taking the time to discuss this :)
Manos
PS: I will explain why your good/bad example behaves like it does:
>// MIRIFLAGS=-Zmiri-ignore-leaks cargo +nightly miri run
>use std::mem::MaybeUninit;
>
>struct S {
> me: *mut S,
> them: *mut S
>}
>
>impl S {
> pub fn chardev_receive(&mut self) {
> println!("in chardev_receive with &mut");
> }
>
> pub fn memory_write_good(&mut self) {
> println!("in memory_write_good, calling qemu_chr_fe_accept_input()");
> qemu_chr_fe_accept_input_good(self);
> }
>
> pub fn memory_write_bad(&mut self) {
> println!("in memory_write_bad, calling qemu_chr_fe_accept_input()");
> qemu_chr_fe_accept_input_bad(self);
> }
>}
>
>fn qemu_chr_fe_accept_input_good(c: &S) {
> // you can still go from *mut to &mut in _another_ instance of struct S
> (unsafe { &mut *c.them }).chardev_receive();
`them` is an uninitialized value, so you are dereferencing it and
passing a mutable reference to it, while
>}
>
>fn qemu_chr_fe_accept_input_bad(c: &S) {
> // you cannot go from *mut to &mut when it points to _this_ instance;
> // creating the &mut that is passed to memory_write_bad() has
> // effectively made that *mut unusable!
> (unsafe { &mut *c.me }).chardev_receive();
>}
`me` is the same memory location as `c`, which is passed as read only
(&S) here.
>
>fn main() {
> let p: &mut MaybeUninit<S> = Box::leak(Box::new(MaybeUninit::uninit()));
> let q: &mut MaybeUninit<S> = Box::leak(Box::new(MaybeUninit::uninit()));
>
> unsafe {
> let p_mut_ptr = p.as_mut_ptr();
> let q_mut_ptr = q.as_mut_ptr();
> *(&mut *p_mut_ptr) = S { me: p_mut_ptr, them: q_mut_ptr };
> (&mut *p_mut_ptr).memory_write_bad();
> (&mut *p_mut_ptr).memory_write_good();
> }
>}
>
next prev parent reply other threads:[~2024-07-26 7:26 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-22 11:43 [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 1/8] build-sys: Add rust feature option Manos Pitsidianakis
2024-07-23 6:37 ` Zhao Liu
2024-07-23 10:13 ` Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 2/8] build deps: update lcitool to include rust bits Manos Pitsidianakis
2024-07-23 8:31 ` Richard Henderson
2024-07-23 10:11 ` Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 3/8] CI: Add build-system-rust-debian job Manos Pitsidianakis
2024-07-23 8:32 ` Richard Henderson
2024-07-23 8:39 ` Daniel P. Berrangé
2024-07-23 10:06 ` Manos Pitsidianakis
2024-07-23 10:11 ` Daniel P. Berrangé
2024-07-23 10:24 ` Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 4/8] rust: add bindgen step as a meson dependency Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 5/8] .gitattributes: add Rust diff and merge attributes Manos Pitsidianakis
2024-07-23 8:38 ` Zhao Liu
2024-07-22 11:43 ` [RFC PATCH v5 6/8] rust: add crate to expose bindings and interfaces Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 7/8] rust: add PL011 device model Manos Pitsidianakis
2024-07-22 11:43 ` [RFC PATCH v5 8/8] rust/pl011: vendor dependencies Manos Pitsidianakis
2024-07-23 8:37 ` Zhao Liu
2024-07-23 10:19 ` Manos Pitsidianakis
2024-07-23 15:07 ` [RFC PATCH v5 0/8] Add Rust support, implement ARM PL011 Paolo Bonzini
2024-07-24 9:14 ` Manos Pitsidianakis
2024-07-24 10:34 ` Paolo Bonzini
2024-07-25 5:47 ` Manos Pitsidianakis
2024-07-25 9:50 ` Paolo Bonzini
2024-07-25 10:02 ` Manos Pitsidianakis
2024-07-25 11:19 ` Paolo Bonzini
2024-07-25 14:48 ` Manos Pitsidianakis
2024-07-25 15:15 ` Paolo Bonzini
2024-07-26 7:12 ` Manos Pitsidianakis [this message]
2024-07-26 8:19 ` Paolo Bonzini
2024-07-26 9:26 ` Manos Pitsidianakis
2024-07-31 9:41 ` Manos Pitsidianakis
2024-07-31 10:35 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=h7zb4.aog50x8tfxkp@linaro.org \
--to=manos.pitsidianakis@linaro.org \
--cc=alex.bennee@linaro.org \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=gustavo.romero@linaro.org \
--cc=mads@ynddal.dk \
--cc=marcandre.lureau@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@linaro.org \
--cc=pierrick.bouvier@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=rowan.hart@intel.com \
--cc=stefanha@redhat.com \
--cc=thuth@redhat.com \
--cc=zhao1.liu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).