Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miri checks ptr.read() but not dereferencing a pointer (*ptr) #1526

Closed
elichai opened this issue Aug 26, 2020 · 7 comments
Closed

Miri checks ptr.read() but not dereferencing a pointer (*ptr) #1526

elichai opened this issue Aug 26, 2020 · 7 comments
Labels
C-support Category: Not necessarily a bug, but someone asking for support

Comments

@elichai
Copy link
Contributor

elichai commented Aug 26, 2020

Hi,
miri complains on this:

fn main() {
    unsafe {
        let a = [1u8,2,3];
        let b = &a[0] as *const u8;
        println!("{}", b.add(1).read());
    }
}

https://play.rust-lang.org/?gist=5af194a447ac5e0d38796c809e3a0e6f
but not on this:

fn main() {
    unsafe {
        let a = [1u8,2,3];
        let b = &a[0] as *const u8;
        println!("{}", *b.add(1));
    }
}

https://play.rust-lang.org/?gist=6b7d13c8b77d8e14e06d9133a19e992f

@RalfJung
Copy link
Member

RalfJung commented Aug 26, 2020

I just tried on the playground, and I do get an error for the second example as well:

error: Undefined Behavior: trying to reborrow for SharedReadOnly, but parent tag <untagged> does not have an appropriate item in the borrow stack
 --> src/main.rs:5:24
  |
5 |         println!("{}", *b.add(1));
  |                        ^^^^^^^^^ trying to reborrow for SharedReadOnly, but parent tag <untagged> does not have an appropriate item in the borrow stack
  |
  = help: this indicates a potential bug in the program: it performed an invalid operation, but the rules it violated are still experimental
  = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information

@RalfJung RalfJung added the C-support Category: Not necessarily a bug, but someone asking for support label Aug 26, 2020
@elichai
Copy link
Contributor Author

elichai commented Aug 26, 2020

Ha, you're right, this is weird.
This on the other hand doesn't give an error:

fn main() {
    unsafe {
        let a = [1u8, 2, 3];
        let b = &a[0] as *const u8;
        if !a.is_empty() {
            println!("{}", *b.add(1));
        }
    }
}

@RalfJung
Copy link
Member

But neither does this:

fn main() {
    unsafe {
        let a = [1u8, 2, 3];
        let b = &a[0] as *const u8;
        if !a.is_empty() {
            println!("{}", b.add(1).read());
        }
    }
}

@RalfJung
Copy link
Member

This has nothing to do with deref vs read. This is caused by is_empty creating a raw pointer and Stacked Borrows not tracking raw pointers in detail -- so it "confuses" the raw pointer created there with b. That is currently expected behavior, though I would like to do more precise tracking of raw pointers eventually (but this might completely kill performance... and we'll have to see how compatible it is with real code).

@elichai
Copy link
Contributor Author

elichai commented Aug 26, 2020

@RalfJung Yes. this is a completely different issue than what I was describing,
what happened is that I had a complex function, saw that it didn't error, I removed a lot of code, replaced with read() and it did, so I wrongly assumed it was the read() change. sorry.

@elichai
Copy link
Contributor Author

elichai commented Aug 26, 2020

So together with my confusion and the fact that this is expected behavior I'll close this issue.
if you're curious this was the code snippet that got me here: rust-lang/rust#75943 (trying to minimize that down in the playground got me to accidentally assume deref was the problem)

@RalfJung
Copy link
Member

I opened rust-lang/unsafe-code-guidelines#248 to track the underlying problem.

pietroalbini added a commit to pietroalbini/rust that referenced this issue Aug 28, 2020
…alfJung

Fix potential UB in align_offset doc examples

Currently it takes a pointer only to the first element in the array, this changes the code to take a pointer to the whole array.
miri can't catch this right now because it later calls `x.len()` which re-tags the pointer for the whole array.

rust-lang/miri#1526 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-support Category: Not necessarily a bug, but someone asking for support
Projects
None yet
Development

No branches or pull requests

2 participants