qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
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: Thu, 25 Jul 2024 17:15:00 +0200	[thread overview]
Message-ID: <CABgObfb27wbwgErFsMdsuSo1BxQVBoRfbrUmK2k-x5Ya3ez0TA@mail.gmail.com> (raw)
In-Reply-To: <CAAjaMXY3jL=cVs=e+6kiJw_WrfG5vOaqaNFu74BdoK2-bO7ZLQ@mail.gmail.com>

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.

You can do it within a function:

fn main() {
  let mut x = 42u32;
  let a = &mut x;
  let b = &mut *a;
  *b = 0;
  *a = 43;
  // *b = 42;
}

But that's because the compiler _knows_ the provenance of b. So it
says "ok, 'b' is basically the same as 'a' and 'a' won't be accessed
while 'b' is live". This doesn't happen in any other case. In fact
miri points out that, the moment you create a &mut in pl011_read, the
chardev's opaque becomes effectively unusable[1]. In other words,
you're not even allowed to turn it from a *mut into a &mut!

Again: it's exactly the same as the example above

fn main() {
    let mut foo = String::from("foo");
    let x = &mut foo;                         // pl011_read has a reference
    let x_ptr: *mut String = x as *mut _;     // pl011_receive starts
    let y = &mut foo;                         // pl011_receive creates
a reference

    // at this point, x becomes invalid
    print!("{}", y);
    // pl011_receive returns

    // this is undefined behavior (shown by miri)
    print!("{}", unsafe { &mut *x_ptr });
}

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.

Paolo

[1] this is the other example I gave a few hours ago, which I'll copy
here for reference:

// 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();
}

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();
}

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();
   }
}



  reply	other threads:[~2024-07-25 15:15 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 [this message]
2024-07-26  7:12                   ` Manos Pitsidianakis
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=CABgObfb27wbwgErFsMdsuSo1BxQVBoRfbrUmK2k-x5Ya3ez0TA@mail.gmail.com \
    --to=pbonzini@redhat.com \
    --cc=alex.bennee@linaro.org \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=gustavo.romero@linaro.org \
    --cc=mads@ynddal.dk \
    --cc=manos.pitsidianakis@linaro.org \
    --cc=marcandre.lureau@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).