The serialize_value function in src/webcore/global_arena.rs contains a critical memory safety bug that causes undefined behavior when called for the first time with an uninitialized global arena.
|
pub fn serialize_value< 'a >( value: Value ) -> SerializedValue< 'a > { |
|
unsafe { |
|
let mut vec = Vec::from_raw_parts( VALUE_ARENA.memory as *mut Value, VALUE_ARENA.length, VALUE_ARENA.capacity ); |
|
vec.push( value ); |
|
let pointer = vec.last().unwrap() as *const Value; |
|
VALUE_ARENA.memory = vec.as_mut_ptr() as *mut u8; |
|
VALUE_ARENA.length = vec.len(); |
|
VALUE_ARENA.capacity = vec.capacity(); |
|
mem::forget( vec ); |
|
|
|
JsSerialize::_into_js( &*pointer ) |
The function uses Vec::from_raw_parts() to reconstruct a Vec<Value> from the global VALUE_ARENA without checking if the arena has been properly initialized. When VALUE_ARENA is in its initial state (zeroed or uninitialized), this creates a Vec from invalid memory addresses, leading to undefined behavior.
Proof of Concept
#[test]
fn poc_multiple_value_types() {
use stdweb::Value;
use stdweb::private::serialize_value;
let test_cases = vec![
("Null", Value::Null),
("Boolean", Value::Bool(true)),
("Number", Value::Number(42.0.into())),
("String", Value::String("test".into())),
];
for (name, value) in test_cases.into_iter().take(1) {
let _serialized = serialize_value(value);
break;
}
}
it triggers the following errors,
test poc_multiple_value_types ... error: Undefined Behavior: constructing invalid value: encountered 0, but expected something greater or equal to 1
--> /home/rafael/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/unique.rs:89:36
|
89 | unsafe { Unique { pointer: NonNull::new_unchecked(ptr), _marker: PhantomData } }
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
|
= 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: this is on thread `poc_multiple_va`
The
serialize_valuefunction insrc/webcore/global_arena.rscontains a critical memory safety bug that causes undefined behavior when called for the first time with an uninitialized global arena.stdweb/src/webcore/global_arena.rs
Lines 54 to 64 in 9b418d9
The function uses
Vec::from_raw_parts()to reconstruct aVec<Value>from the globalVALUE_ARENAwithout checking if the arena has been properly initialized. WhenVALUE_ARENAis in its initial state (zeroed or uninitialized), this creates a Vec from invalid memory addresses, leading to undefined behavior.Proof of Concept
it triggers the following errors,