rusty_v8 icon indicating copy to clipboard operation
rusty_v8 copied to clipboard

`BackingStore` should not be `Sync`

Open andreubotella opened this issue 4 years ago • 0 comments

SharedRef<T> implements Send if T implements Sync, so BackingStore implementing Sync means the following is possible:

let buffer: v8::Local<v8::ArrayBuffer> = run_script(
  scope,
  r#"
    let arrayBuffer = new ArrayBuffer(1024);
    globalThis.buffer = new Uint8Array(arrayBuffer);
    arrayBuffer
  "#,
);

let backing_store = buffer.get_backing_store();

std::thread::spawn(move || {
  // We can dereference the sent `backing_store` into a slice of `Cell<u8>`,
  // which allows us to mutate the backing store's bytes from this thread,
  // without any unsafe code, even though the isolate in the main thread
  // still has access to the `ArrayBuffer` object.
  let cell_slice: &[Cell<u8>] = &backing_store;
  cell_slice[0].set(42);
});

let value: v8::Local<v8::Number> = run_script(scope, "globalThis.buffer[0]");
println!("Read value: {}", value.value());

Users of BackingStore might then want to unsafely implement Send and/or Sync if they have made sure that the backing store is shared. (Though dereferencing it would still be unsound for the time being due to #711.)

This was discovered when investigating denoland/serde_v8#47.

andreubotella avatar Oct 06 '21 03:10 andreubotella