GithubHelp home page GithubHelp logo

Tests fails under miri about smallbox HOT 15 CLOSED

andylokandy avatar andylokandy commented on June 19, 2024
Tests fails under miri

from smallbox.

Comments (15)

GoldsteinE avatar GoldsteinE commented on June 19, 2024 4

I don’t think ptr-int-ptr roundtrips are the only problem here. Consider this patch:

Patch
diff --git a/src/smallbox.rs b/src/smallbox.rs
index 499dd7b..8308f99 100644
--- a/src/smallbox.rs
+++ b/src/smallbox.rs
@@ -182,8 +182,8 @@ impl<T: ?Sized, Space> SmallBox<T, Space> {

         // Overwrite the pointer but retain any extra data inside the fat pointer.
         let mut ptr = ptr;
-        let ptr_ptr = &mut ptr as *mut _ as *mut usize;
-        ptr_ptr.write(ptr_addr as usize);
+        let ptr_ptr = &mut ptr as *mut _ as *mut *const u8;
+        ptr_ptr.write(ptr_addr);

         ptr::copy_nonoverlapping(val as *const _ as *const u8, ptr_copy, size);

@@ -221,11 +221,9 @@ impl<T: ?Sized, Space> SmallBox<T, Space> {
     unsafe fn as_ptr(&self) -> *const T {
         let mut ptr = self.ptr;

-        if !self.is_heap() {
-            // Overwrite the pointer but retain any extra data inside the fat pointer.
-            let ptr_ptr = &mut ptr as *mut _ as *mut usize;
-            ptr_ptr.write(self.space.as_ptr() as *const () as usize);
-        }
+        // Overwrite the pointer but retain any extra data inside the fat pointer.
+        let ptr_ptr = &mut ptr as *mut *const T as *mut *const Space;
+        ptr_ptr.write(self.space.as_ptr());

         ptr
     }

It gets rid of such roundtrips and tests still fail under Miri, with both Stacked Borrows and Tree Borrows.

Error with Stacked Borrows
test smallbox::tests::test_basic ... error: Undefined Behavior: trying to retag from <167105> for SharedReadOnly permission at alloc63930[0x8], but that tag does not exist in the borrow stack for this location
   --> src/smallbox.rs:357:18
    |
357 |         unsafe { &*self.as_ptr() }
    |                  ^^^^^^^^^^^^^^^
    |                  |
    |                  trying to retag from <167105> for SharedReadOnly permission at alloc63930[0x8], but that tag does not exist in the borrow stack for this location
    |                  this error occurs as part of retag at alloc63930[0x0..0x10]
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows 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
help: <167105> was created by a SharedReadOnly retag at offsets [0x0..0x8]
   --> src/smallbox.rs:226:23
    |
226 |         ptr_ptr.write(self.space.as_ptr());
    |                       ^^^^^^^^^^^^^^^^^^^
    = note: BACKTRACE (of the first span):
    = note: inside `<smallbox::SmallBox<(usize, usize), space::S1> as std::ops::Deref>::deref` at src/smallbox.rs:357:18: 357:33
note: inside `smallbox::tests::test_basic`
   --> src/smallbox.rs:463:17
    |
463 |         assert!(*heaped == (0, 1));
    |                 ^^^^^^^
note: inside closure
   --> src/smallbox.rs:458:21
    |
457 |     #[test]
    |     ------- in this procedural macro expansion
458 |     fn test_basic() {
    |                     ^
    = note: this error originates in the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to previous error

error: test failed, to rerun pass `--lib`
Error with Tree Borrows
test smallbox::tests::test_basic ... error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
    --> /nix/store/dc9whnls6hmwbja38fny60xn1apl97np-rust-default-1.70.0-nightly-2023-04-10/lib/rustlib/src/rust/library/core/src/cmp.rs:1330:5
     |
1330 | /     partial_eq_impl! {
1331 | |         bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
1332 | |     }
     | |_____^ using uninitialized data, but this operation requires initialized memory
     |
     = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
     = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
     = note: BACKTRACE:
     = note: inside `std::cmp::impls::<impl std::cmp::PartialEq for usize>::eq` at /nix/store/dc9whnls6hmwbja38fny60xn1apl97np-rust-default-1.70.0-nightly-2023-04-10/lib/rustlib/src/rust/library/core/src/cmp.rs:1310:52: 1310:59
     = note: inside `std::tuple::<impl std::cmp::PartialEq for (usize, usize)>::eq` at /nix/store/dc9whnls6hmwbja38fny60xn1apl97np-rust-default-1.70.0-nightly-2023-04-10/lib/rustlib/src/rust/library/core/src/tuple.rs:32:37: 32:72
note: inside `smallbox::tests::test_basic`
    --> src/smallbox.rs:463:17
     |
463  |         assert!(*heaped == (0, 1));
     |                 ^^^^^^^^^^^^^^^^^
note: inside closure
    --> src/smallbox.rs:458:21
     |
457  |     #[test]
     |     ------- in this procedural macro expansion
458  |     fn test_basic() {
     |                     ^
     = note: this error originates in the macro `partial_eq_impl` which comes from the expansion of the attribute macro `test` (in Nightly builds, run with -Z macro-backtrace for more info)

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to previous error

error: test failed, to rerun pass `--lib`

Interestingly, Miri with Tree Borrows mentions reading uninitialized memory, which is certainly UB, regardless of which borrowing model will be adopted at the end. I haven’t been able to pinpoint why this happens though, and it might be a bug in Miri.

Anyway, I think that deserves further investigation.

from smallbox.

andylokandy avatar andylokandy commented on June 19, 2024 2

Miri fails because Smallbox employs a technique called "pointer-usize-pointer roundtrips", which cannot be expressed within the constraints of Strict Provenance. This doesn't necessarily indicate that the code has undefined behavior, but it means that tools like MIRI cannot prove that it doesn't. The changes required to comply with Strict Provenance rules are currently under the nightly feature gate #[feature(strict_provenance)], so we are unable to act at this time.

from smallbox.

andylokandy avatar andylokandy commented on June 19, 2024 2

It gets rid of such roundtrips and tests still fail under Miri, with both Stacked Borrows and Tree Borrows.

@GoldsteinE I believe that this patch doesn't satisfy the 'strict provenance' requirement, which necessitates manipulating the pointer using the API associated with #[feature(strict_provenance)]. Otherwise, information about the memory to which the pointer is directed will be lost in the miri context (when built with miri, the pointers do carry extra information about the memory, and the strict_provenance API preserves that information).

from smallbox.

GoldsteinE avatar GoldsteinE commented on June 19, 2024 1

Strict provenance requirements aren’t checked by Miri by default AFAIK, so SB/TB failures can’t be caused by them. Miri treats as casts as behaving with “angelic non-determinism”, so if there is any “exposed” provenance that can be used without causing UB, it will be used.

from smallbox.

GoldsteinE avatar GoldsteinE commented on June 19, 2024 1

Oops, fair enough. I’ll try to make a working patch without sptr APIs later today.

from smallbox.

GoldsteinE avatar GoldsteinE commented on June 19, 2024 1

@andylokandy Could you provide your sptr patch as a file? I’ll try to tinker with it some more.

from smallbox.

GoldsteinE avatar GoldsteinE commented on June 19, 2024

I’m also not sure which strict provenance APIs you’re talking about. It seems like there’s no roundtrip at all, so no special APIs are needed?

from smallbox.

andylokandy avatar andylokandy commented on June 19, 2024

Yeah, I know talk is cheap. Therefore, I tested the new feature-gated ptr APIs and as expected, Miri passed without any issues.

from smallbox.

GoldsteinE avatar GoldsteinE commented on June 19, 2024

That’s cool! Does it work with sptr backport?

from smallbox.

andylokandy avatar andylokandy commented on June 19, 2024

Here are the changes:
image


image

from smallbox.

andylokandy avatar andylokandy commented on June 19, 2024

That’s cool! Does it work with sptr backport?

It needs an additional #![feature(set_ptr_value)] feature gate, but I didn't find a polyfill for it yet.

from smallbox.

GoldsteinE avatar GoldsteinE commented on June 19, 2024

I also feel like “works with strict provenance APIs, but not ptr-to-ptr casts” could be a bug in Miri. Maybe it’s worth reporting this case to Miri and/or UCG.

from smallbox.

andylokandy avatar andylokandy commented on June 19, 2024

In your patch, the address of ptr is still directly derived from an usize ptr_addr. This is a ptr-usize-ptr roundtrip.

let ptr_ptr = &mut ptr as *mut _ as *mut *const u8;
ptr_ptr.write(ptr_addr);

from smallbox.

andylokandy avatar andylokandy commented on June 19, 2024

Oh my bad, ptr_addr is indeed a pointer...

from smallbox.

andylokandy avatar andylokandy commented on June 19, 2024

@GoldsteinE You can see this #22

from smallbox.

Related Issues (13)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.