Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion crates/bridge/src/queue_tracker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ pub enum TrackedLimit {
VmRecursiveFsDepth,
VmRecursiveFsEntries,
V8HeapBytes,
V8ArrayBufferBytes,
V8ExternalMemoryBytes,
V8CpuTimeMs,
V8WallClockMs,
WasmFuelMs,
Expand Down Expand Up @@ -132,6 +134,8 @@ impl TrackedLimit {
TrackedLimit::VmRecursiveFsDepth => "vm_recursive_fs_depth",
TrackedLimit::VmRecursiveFsEntries => "vm_recursive_fs_entries",
TrackedLimit::V8HeapBytes => "v8_heap_bytes",
TrackedLimit::V8ArrayBufferBytes => "v8_array_buffer_bytes",
TrackedLimit::V8ExternalMemoryBytes => "v8_external_memory_bytes",
TrackedLimit::V8CpuTimeMs => "v8_cpu_time_ms",
TrackedLimit::V8WallClockMs => "v8_wall_clock_ms",
TrackedLimit::WasmFuelMs => "wasm_fuel_ms",
Expand Down Expand Up @@ -166,7 +170,10 @@ impl TrackedLimit {
| TrackedLimit::VmInodes
| TrackedLimit::VmRecursiveFsDepth
| TrackedLimit::VmRecursiveFsEntries => LimitCategory::Resource,
TrackedLimit::V8HeapBytes | TrackedLimit::WasmMemoryBytes => LimitCategory::Memory,
TrackedLimit::V8HeapBytes
| TrackedLimit::V8ArrayBufferBytes
| TrackedLimit::V8ExternalMemoryBytes
| TrackedLimit::WasmMemoryBytes => LimitCategory::Memory,
TrackedLimit::V8CpuTimeMs | TrackedLimit::V8WallClockMs | TrackedLimit::WasmFuelMs => {
LimitCategory::Cpu
}
Expand Down
10 changes: 10 additions & 0 deletions crates/execution/src/javascript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,11 @@ pub struct JavascriptExecutionLimits {
/// Per-call host bridge deadline. Sidecar VMs supply
/// `limits.reactor.operationDeadlineMs`; zero is invalid.
pub bridge_call_timeout_ms: Option<u64>,
/// Stop the script when WebAssembly memory and host-provided buffers pass
/// the heap limit. The sidecar sets this for guest JavaScript only; Python
/// and the WASM runner keep their program memory in WebAssembly under their
/// own limits.
pub limit_external_memory: bool,
}

/// Per-execution guest-runtime config carried as typed fields rather than
Expand Down Expand Up @@ -2417,6 +2422,7 @@ fn register_v8_session<'a, F>(
heap_limit_mb: u32,
cpu_time_limit_ms: u32,
wall_clock_limit_ms: u32,
limit_external_memory: bool,
warm_hint: Option<WarmSessionHint>,
create_session: F,
) -> Result<PendingV8SessionRegistration<'a>, JavascriptExecutionError>
Expand All @@ -2433,6 +2439,7 @@ where
heap_limit_mb: (heap_limit_mb > 0).then_some(heap_limit_mb),
cpu_time_limit_ms: (cpu_time_limit_ms > 0).then_some(cpu_time_limit_ms),
wall_clock_limit_ms: (wall_clock_limit_ms > 0).then_some(wall_clock_limit_ms),
limit_external_memory,
warm_hint,
})
.map_err(JavascriptExecutionError::Spawn)?;
Expand Down Expand Up @@ -2782,6 +2789,7 @@ impl JavascriptExecutionEngine {
heap_limit_mb,
cpu_time_limit_ms,
wall_clock_limit_ms,
request.limits.limit_external_memory,
warm_hint,
|command| {
v8_host.create_session_from_command_with_runtime(
Expand Down Expand Up @@ -7584,6 +7592,7 @@ mod tests {
max_timers: Some(321),
reactor_work_quantum: Some(64),
bridge_call_timeout_ms: Some(15_000),
limit_external_memory: false,
},
wasm_module_bytes: None,
inline_code: None,
Expand Down Expand Up @@ -8000,6 +8009,7 @@ mod tests {
0,
0,
0,
false,
None,
|_command| {
Err(std::io::Error::new(
Expand Down
1 change: 1 addition & 0 deletions crates/execution/src/v8_host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ impl V8RuntimeHost {
heap_limit_mb: non_zero_option(heap_limit_mb),
cpu_time_limit_ms: non_zero_option(cpu_time_limit_ms),
wall_clock_limit_ms: non_zero_option(wall_clock_limit_ms),
limit_external_memory: false,
warm_hint,
})
}
Expand Down
1 change: 1 addition & 0 deletions crates/native-sidecar/src/execution/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3073,6 +3073,7 @@ pub(super) fn javascript_execution_limits(vm: &VmState) -> JavascriptExecutionLi
max_timers: Some(vm.limits.js_runtime.max_timers),
reactor_work_quantum: vm_reactor_work_quantum(&vm.limits),
bridge_call_timeout_ms: Some(bridge_call_timeout_ms(&vm.limits)),
limit_external_memory: true,
}
}

Expand Down
32 changes: 8 additions & 24 deletions crates/v8-runtime/src/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -535,23 +535,8 @@ fn cbor_to_v8_inner<'s>(
ciborium::Value::Text(s) => Ok(v8::String::new(scope, s)
.ok_or_else(|| "CBOR decode failed to allocate string".to_string())?
.into()),
ciborium::Value::Bytes(b) => {
let len = b.len();
let ab = v8::ArrayBuffer::new(scope, len);
if len > 0 {
let bs = ab.get_backing_store();
unsafe {
std::ptr::copy_nonoverlapping(
b.as_ptr(),
bs.data().unwrap().as_ptr() as *mut u8,
len,
);
}
}
Ok(v8::Uint8Array::new(scope, ab, 0, len)
.ok_or_else(|| "CBOR decode failed to allocate byte array".to_string())?
.into())
}
ciborium::Value::Bytes(b) => raw_bytes_to_uint8array(scope, b)
.ok_or_else(|| "CBOR decode failed to allocate byte array".to_string()),
ciborium::Value::Array(items) => {
cbor_container_item_count("array", items.len())?;
let arr = v8::Array::new(scope, items.len() as i32);
Expand Down Expand Up @@ -580,14 +565,13 @@ fn raw_bytes_to_uint8array<'s>(
scope: &mut v8::HandleScope<'s>,
bytes: &[u8],
) -> Option<v8::Local<'s, v8::Value>> {
// Host data uses a Rust-owned backing store. `v8::ArrayBuffer::new` draws
// from the isolate's ArrayBuffer budget and fatal-aborts the whole process
// when that budget is spent, so a guest that fills it could then crash the
// sidecar by reading a file.
let len = bytes.len();
let ab = v8::ArrayBuffer::new(scope, len);
if len > 0 {
let bs = ab.get_backing_store();
unsafe {
std::ptr::copy_nonoverlapping(bytes.as_ptr(), bs.data()?.as_ptr() as *mut u8, len);
}
}
let backing_store = v8::ArrayBuffer::new_backing_store_from_vec(bytes.to_vec());
let ab = v8::ArrayBuffer::with_backing_store(scope, &backing_store.make_shared());
v8::Uint8Array::new(scope, ab, 0, len).map(Into::into)
}

Expand Down
13 changes: 12 additions & 1 deletion crates/v8-runtime/src/embedded_runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ impl EmbeddedV8Runtime {
heap_limit_mb,
cpu_time_limit_ms,
wall_clock_limit_ms,
limit_external_memory,
warm_hint,
} => {
let output = self
Expand All @@ -260,6 +261,7 @@ impl EmbeddedV8Runtime {
heap_limit_mb,
cpu_time_limit_ms,
wall_clock_limit_ms,
limit_external_memory,
output_generation,
warm_hint,
event_tx,
Expand Down Expand Up @@ -310,6 +312,7 @@ impl EmbeddedV8Runtime {
heap_limit_mb,
cpu_time_limit_ms,
wall_clock_limit_ms,
limit_external_memory,
warm_hint,
} = command
else {
Expand Down Expand Up @@ -337,6 +340,7 @@ impl EmbeddedV8Runtime {
heap_limit_mb,
cpu_time_limit_ms,
wall_clock_limit_ms,
limit_external_memory,
output_generation,
warm_hint,
event_tx,
Expand Down Expand Up @@ -842,16 +846,19 @@ fn dispatch_runtime_command(
heap_limit_mb,
cpu_time_limit_ms,
wall_clock_limit_ms,
limit_external_memory,
warm_hint,
} => {
let mut mgr = session_mgr.lock().expect("session manager lock poisoned");
mgr.create_session_with_output_generation(
mgr.create_session_with_output_generation_and_sender(
session_id,
heap_limit_mb,
cpu_time_limit_ms,
wall_clock_limit_ms,
limit_external_memory,
None,
warm_hint,
None,
)
.map_err(other_io_error)
}
Expand Down Expand Up @@ -1286,6 +1293,7 @@ mod tests {
heap_limit_mb: None,
cpu_time_limit_ms: None,
wall_clock_limit_ms: None,
limit_external_memory: false,
warm_hint: None,
},
vm_runtime,
Expand Down Expand Up @@ -1329,6 +1337,7 @@ mod tests {
heap_limit_mb: None,
cpu_time_limit_ms: None,
wall_clock_limit_ms: None,
limit_external_memory: false,
warm_hint: None,
})
.expect("create session");
Expand Down Expand Up @@ -1708,6 +1717,7 @@ mod tests {
heap_limit_mb: None,
cpu_time_limit_ms: None,
wall_clock_limit_ms: None,
limit_external_memory: false,
warm_hint: None,
})
.expect("create first session");
Expand Down Expand Up @@ -1744,6 +1754,7 @@ mod tests {
heap_limit_mb: None,
cpu_time_limit_ms: None,
wall_clock_limit_ms: None,
limit_external_memory: false,
warm_hint: None,
})
.expect("create reused session");
Expand Down
Loading
Loading