0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2025-01-21 21:50:20 -05:00

Avoid referencing uninitalized in Inspector API (#1164)

This commit is contained in:
Mike Mulchrone 2023-01-15 09:30:38 -05:00 committed by GitHub
parent 6c619797a5
commit 7c1b08e6a8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 5 deletions

View file

@ -271,6 +271,10 @@ where
pub trait ChannelImpl: AsChannel {
fn base(&self) -> &ChannelBase;
fn base_mut(&mut self) -> &mut ChannelBase;
/// This is used for calculating the offset to the base field, and care must be taken not to create any references in the process of creating the pointer because the *const Self pointer is not valid (thus resulting in instant UB)
unsafe fn base_ptr(this: *const Self) -> *const ChannelBase
where
Self: Sized;
fn send_response(&mut self, call_id: i32, message: UniquePtr<StringBuffer>);
fn send_notification(&mut self, message: UniquePtr<StringBuffer>);
@ -304,9 +308,7 @@ impl ChannelBase {
{
let buf = std::mem::MaybeUninit::<T>::uninit();
let embedder_ptr: *const T = buf.as_ptr();
// TODO(y21): the call to base() creates a reference to uninitialized memory (UB)
// fixing this requires changes in the ChannelImpl trait, namely ChannelImpl::base() can't take &self
let self_ptr: *const Self = unsafe { (*embedder_ptr).base() };
let self_ptr: *const Self = unsafe { T::base_ptr(embedder_ptr) };
FieldOffset::from_ptrs(embedder_ptr, self_ptr)
}
@ -384,6 +386,12 @@ mod tests {
fn base_mut(&mut self) -> &mut ChannelBase {
&mut self.base
}
unsafe fn base_ptr(_this: *const Self) -> *const ChannelBase
where
Self: Sized,
{
unsafe { addr_of!((*_this).base) }
}
fn send_response(
&mut self,
call_id: i32,
@ -520,6 +528,10 @@ where
pub trait V8InspectorClientImpl: AsV8InspectorClient {
fn base(&self) -> &V8InspectorClientBase;
fn base_mut(&mut self) -> &mut V8InspectorClientBase;
/// This is used for calculating the offset to the base field, and care must be taken not to create any references in the process of creating the pointer because the *const Self pointer is not valid (thus resulting in instant UB)
unsafe fn base_ptr(this: *const Self) -> *const V8InspectorClientBase
where
Self: Sized;
fn run_message_loop_on_pause(&mut self, context_group_id: i32) {}
fn quit_message_loop_on_pause(&mut self) {}
@ -570,7 +582,7 @@ impl V8InspectorClientBase {
{
let buf = std::mem::MaybeUninit::<T>::uninit();
let embedder_ptr: *const T = buf.as_ptr();
let self_ptr: *const Self = unsafe { (*embedder_ptr).base() };
let self_ptr: *const Self = unsafe { T::base_ptr(embedder_ptr) };
FieldOffset::from_ptrs(embedder_ptr, self_ptr)
}

View file

@ -10,11 +10,12 @@ use std::ffi::CStr;
use std::hash::Hash;
use std::mem::MaybeUninit;
use std::os::raw::c_char;
use std::ptr::NonNull;
use std::ptr::{addr_of, NonNull};
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::sync::Mutex;
use v8::fast_api;
use v8::inspector::ChannelBase;
// TODO(piscisaureus): Ideally there would be no need to import this trait.
use v8::MapFnTo;
@ -5046,6 +5047,15 @@ impl v8::inspector::V8InspectorClientImpl for ClientCounter {
&mut self.base
}
unsafe fn base_ptr(
this: *const Self,
) -> *const v8::inspector::V8InspectorClientBase
where
Self: Sized,
{
unsafe { addr_of!((*this).base) }
}
fn run_message_loop_on_pause(&mut self, context_group_id: i32) {
assert_eq!(context_group_id, 1);
self.count_run_message_loop_on_pause += 1;
@ -5093,6 +5103,12 @@ impl v8::inspector::ChannelImpl for ChannelCounter {
fn base_mut(&mut self) -> &mut v8::inspector::ChannelBase {
&mut self.base
}
unsafe fn base_ptr(_this: *const Self) -> *const ChannelBase
where
Self: Sized,
{
unsafe { addr_of!((*_this).base) }
}
fn send_response(
&mut self,
call_id: i32,
@ -5367,6 +5383,12 @@ fn inspector_console_api_message() {
&mut self.base
}
unsafe fn base_ptr(
_this: *const Self,
) -> *const v8::inspector::V8InspectorClientBase {
unsafe { addr_of!((*_this).base) }
}
fn console_api_message(
&mut self,
_context_group_id: i32,