zub-vm icon indicating copy to clipboard operation
zub-vm copied to clipboard

Broken validity invariants in `TaggedHandle::<T>::from_float/from_tag`

Open shinmao opened this issue 1 year ago • 1 comments

The source of unsoundness

https://github.com/nilq/zub-vm/blob/c82244ee9908ec3c69079854377d53c20f5cc9fc/src/vm/gc/tag.rs#L42-L48 Hi, we consider that the api has an unsound implementation. In this function, f64 can be transmuted to arbitrary types specified as T in TaggedHandle. However, this could break the validity invariants by producing invalid values for types. Broken validity invariant is considered undefined behavior in Rust. Even though decode api is provided to return Float again, but validity invariant is required to be hold anywhere in the program! Similar unsound implementation in from_tag.

To reproduce the bug

use zub::vm::gc::tag::TaggedHandle;

fn main() {
    let bool_tag = TaggedHandle::<bool>::from_float(3.7_f64);
    println!("{:?}", bool_tag);
}

Here, we first specified the handle in TaggedHandle to be Handle<bool>. When from_float is called, it will transmute the provided float to bool. With Handle<bool>,

pub struct Handle<bool> {
    gen: Generation,
    ptr: *mut bool,
}

and take a look at the printed results,

TaggedHandle { handle: Handle { gen: 0, ptr: 0x400d99999999999a } }

ptr as bool type has the value other than 0 or 1.

shinmao avatar Sep 11 '23 03:09 shinmao

I believe this crate has been unmaintained for quite a while. I would not recommend using it without first forking it and performing heavy maintenance on it.

zesterer avatar Sep 13 '23 14:09 zesterer