mirror of
https://github.com/servo/servo.git
synced 2025-09-30 00:29:14 +01:00
Add trusted type checks for eval arguments (#39263)
Also bumps mozjs to the latest version that has support for `GStackVector` which is what this callback uses. Part of #36258 Fixes #38877 Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
parent
033da09800
commit
d1c3e5f58f
9 changed files with 97 additions and 185 deletions
|
@ -20,6 +20,7 @@ use std::{os, ptr, thread};
|
|||
|
||||
use background_hang_monitor_api::ScriptHangAnnotation;
|
||||
use js::conversions::jsstr_to_string;
|
||||
use js::gc::StackGCVector;
|
||||
use js::glue::{
|
||||
CollectServoSizes, CreateJobQueue, DeleteJobQueue, DispatchablePointer, DispatchableRun,
|
||||
JS_GetReservedSlot, JobQueueTraps, RUST_js_GetErrorMessage, SetBuildId, SetUpEventLoopDispatch,
|
||||
|
@ -29,19 +30,19 @@ use js::glue::{
|
|||
use js::jsapi::{
|
||||
AsmJSOption, BuildIdCharVector, CompilationType, ContextOptionsRef,
|
||||
Dispatchable_MaybeShuttingDown, GCDescription, GCOptions, GCProgress, GCReason,
|
||||
GetPromiseUserInputEventHandlingState, HandleObject, HandleString,
|
||||
GetPromiseUserInputEventHandlingState, Handle as RawHandle, HandleObject, HandleString,
|
||||
HandleValue as RawHandleValue, Heap, InitConsumeStreamCallback, JS_AddExtraGCRootsTracer,
|
||||
JS_InitDestroyPrincipalsCallback, JS_InitReadPrincipalsCallback, JS_NewObject,
|
||||
JS_NewStringCopyN, JS_SetGCCallback, JS_SetGCParameter, JS_SetGlobalJitCompilerOption,
|
||||
JS_SetOffthreadIonCompilationEnabled, JS_SetReservedSlot, JS_SetSecurityCallbacks,
|
||||
JSCLASS_RESERVED_SLOTS_MASK, JSCLASS_RESERVED_SLOTS_SHIFT, JSClass, JSClassOps,
|
||||
JSContext as RawJSContext, JSGCParamKey, JSGCStatus, JSJitCompilerOption, JSObject,
|
||||
JSSecurityCallbacks, JSTracer, JobQueue, MimeType, MutableHandleObject, MutableHandleString,
|
||||
PromiseRejectionHandlingState, PromiseUserInputEventHandlingState, RuntimeCode,
|
||||
SetDOMCallbacks, SetGCSliceCallback, SetJobQueue, SetPreserveWrapperCallbacks,
|
||||
JSSecurityCallbacks, JSString, JSTracer, JobQueue, MimeType, MutableHandleObject,
|
||||
MutableHandleString, PromiseRejectionHandlingState, PromiseUserInputEventHandlingState,
|
||||
RuntimeCode, SetDOMCallbacks, SetGCSliceCallback, SetJobQueue, SetPreserveWrapperCallbacks,
|
||||
SetProcessBuildIdOp, SetPromiseRejectionTrackerCallback, StreamConsumer as JSStreamConsumer,
|
||||
};
|
||||
use js::jsval::{ObjectValue, UndefinedValue};
|
||||
use js::jsval::{JSVal, ObjectValue, UndefinedValue};
|
||||
use js::panic::wrap_panic;
|
||||
pub(crate) use js::rust::ThreadSafeJSContext;
|
||||
use js::rust::wrappers::{GetPromiseIsHandled, JS_GetPromiseResult};
|
||||
|
@ -62,6 +63,7 @@ use crate::body::BodyMixin;
|
|||
use crate::dom::bindings::codegen::Bindings::PromiseBinding::PromiseJobCallback;
|
||||
use crate::dom::bindings::codegen::Bindings::ResponseBinding::Response_Binding::ResponseMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::ResponseBinding::ResponseType as DOMResponseType;
|
||||
use crate::dom::bindings::codegen::UnionTypes::TrustedScriptOrString;
|
||||
use crate::dom::bindings::conversions::{
|
||||
get_dom_class, private_from_object, root_from_handleobject, root_from_object,
|
||||
};
|
||||
|
@ -504,9 +506,9 @@ unsafe extern "C" fn content_security_policy_allows(
|
|||
runtime_code: RuntimeCode,
|
||||
code_string: HandleString,
|
||||
compilation_type: CompilationType,
|
||||
parameter_strings: u8, // FIXME in bindings generation
|
||||
parameter_strings: RawHandle<StackGCVector<*mut JSString>>,
|
||||
body_string: HandleString,
|
||||
parameter_args: u8, // FIXME in bindings generation
|
||||
parameter_args: RawHandle<StackGCVector<JSVal>>,
|
||||
body_arg: RawHandleValue,
|
||||
can_compile_strings: *mut bool,
|
||||
) -> bool {
|
||||
|
@ -516,21 +518,66 @@ unsafe extern "C" fn content_security_policy_allows(
|
|||
// SpiderMonkey provides null pointer when executing webassembly.
|
||||
let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
|
||||
let global = &GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));
|
||||
let csp_list = global.get_csp_list();
|
||||
|
||||
allowed = match runtime_code {
|
||||
RuntimeCode::JS => TrustedScript::can_compile_string_with_trusted_type(
|
||||
cx,
|
||||
global,
|
||||
safely_convert_null_to_string(cx, code_string),
|
||||
compilation_type,
|
||||
parameter_strings,
|
||||
safely_convert_null_to_string(cx, body_string),
|
||||
parameter_args,
|
||||
HandleValue::from_raw(body_arg),
|
||||
CanGc::note(),
|
||||
),
|
||||
RuntimeCode::WASM => global.get_csp_list().is_wasm_evaluation_allowed(global),
|
||||
};
|
||||
// If we don't have any CSP checks to run, short-circuit all logic here
|
||||
allowed = csp_list.is_none() ||
|
||||
match runtime_code {
|
||||
RuntimeCode::JS => {
|
||||
let parameter_strings = Handle::from_raw(parameter_strings);
|
||||
let parameter_strings_length = parameter_strings.len();
|
||||
let mut parameter_strings_vec =
|
||||
Vec::with_capacity(parameter_strings_length as usize);
|
||||
|
||||
for i in 0..parameter_strings_length {
|
||||
let Some(str_) = parameter_strings.at(i) else {
|
||||
unreachable!();
|
||||
};
|
||||
parameter_strings_vec.push(safely_convert_null_to_string(cx, str_.into()));
|
||||
}
|
||||
|
||||
let parameter_args = Handle::from_raw(parameter_args);
|
||||
let parameter_args_length = parameter_args.len();
|
||||
let mut parameter_args_vec = Vec::with_capacity(parameter_args_length as usize);
|
||||
|
||||
for i in 0..parameter_args_length {
|
||||
let Some(arg) = parameter_args.at(i) else {
|
||||
unreachable!();
|
||||
};
|
||||
let value = arg.into_handle().get();
|
||||
if value.is_object() {
|
||||
if let Ok(trusted_script) =
|
||||
root_from_object::<TrustedScript>(value.to_object(), *cx)
|
||||
{
|
||||
parameter_args_vec
|
||||
.push(TrustedScriptOrString::TrustedScript(trusted_script));
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
} else if value.is_string() {
|
||||
let string_ptr = std::ptr::NonNull::new(value.to_string()).unwrap();
|
||||
let dom_string = unsafe { jsstr_to_string(*cx, string_ptr) };
|
||||
parameter_args_vec
|
||||
.push(TrustedScriptOrString::String(dom_string.into()));
|
||||
} else {
|
||||
unreachable!();
|
||||
}
|
||||
}
|
||||
|
||||
TrustedScript::can_compile_string_with_trusted_type(
|
||||
cx,
|
||||
global,
|
||||
safely_convert_null_to_string(cx, code_string),
|
||||
compilation_type,
|
||||
parameter_strings_vec,
|
||||
safely_convert_null_to_string(cx, body_string),
|
||||
parameter_args_vec,
|
||||
HandleValue::from_raw(body_arg),
|
||||
CanGc::note(),
|
||||
)
|
||||
},
|
||||
RuntimeCode::WASM => global.get_csp_list().is_wasm_evaluation_allowed(global),
|
||||
};
|
||||
});
|
||||
*can_compile_strings = allowed;
|
||||
true
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue