Skip to content

Commit dbe417f

Browse files
committed
Bug 1905239 - Add new parameters to HostEnsureCanCompileStrings hook. r=tschuster
Currently, we do this via isRuntimeCodeGenEnabled whose single argument is equivalent to codeString in "Dynamic Code Brand Checks" spec [1]. We extend this hook to accept new parameters from that spec and adjust PerformEval and CreateDynamicFunction accordingly. We don't change the behavior for PerformShadowRealmEval [2] and WASM, i.e. we keep dummy parameters. [1] https://tc39.es/proposal-dynamic-code-brand-checks [2] tc39/proposal-shadowrealm#414 Differential Revision: https://phabricator.services.mozilla.com/D229588 UltraBlame original commit: 2baefcde5dbc41852c85e4f7198b338e529b7406
1 parent 3b25a69 commit dbe417f

File tree

12 files changed

+363
-33
lines changed

12 files changed

+363
-33
lines changed

caps/nsScriptSecurityManager.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@
7373
#include "nsJSUtils.h"
7474
#include "nsILoadInfo.h"
7575
#include "js/ColumnNumber.h"
76+
#include "js/GCVector.h"
77+
#include "js/Value.h"
7678

7779

7880
#define WEBAPPS_PERM_NAME "webapps-manage"
@@ -462,7 +464,12 @@ NS_IMPL_ISUPPORTS(nsScriptSecurityManager, nsIScriptSecurityManager)
462464

463465

464466
bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
465-
JSContext* cx, JS::RuntimeCode aKind, JS::Handle<JSString*> aCode) {
467+
JSContext* cx, JS::RuntimeCode aKind, JS::Handle<JSString*> aCodeString,
468+
JS::CompilationType aCompilationType,
469+
JS::Handle<JS::StackGCVector<JSString*>> aParameterStrings,
470+
JS::Handle<JSString*> aBodyString,
471+
JS::Handle<JS::StackGCVector<JS::Value>> aParameterArgs,
472+
JS::Handle<JS::Value> aBodyArg, bool* aOutCanCompileStrings) {
466473
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
467474

468475
nsCOMPtr<nsIPrincipal> subjectPrincipal = nsContentUtils::SubjectPrincipal();
@@ -477,13 +484,14 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
477484
if (contextForbidsEval) {
478485
nsAutoJSString scriptSample;
479486
if (aKind == JS::RuntimeCode::JS &&
480-
NS_WARN_IF(!scriptSample.init(cx, aCode))) {
487+
NS_WARN_IF(!scriptSample.init(cx, aCodeString))) {
481488
return false;
482489
}
483490

484491
if (!nsContentSecurityUtils::IsEvalAllowed(
485492
cx, subjectPrincipal->IsSystemPrincipal(), scriptSample)) {
486-
return false;
493+
*aOutCanCompileStrings = false;
494+
return true;
487495
}
488496
}
489497

@@ -503,6 +511,7 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
503511
}
504512

505513
if (!csp) {
514+
*aOutCanCompileStrings = true;
506515
return true;
507516
}
508517
}
@@ -522,7 +531,8 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
522531
nsresult rv = csp->GetAllowsEval(&reportViolation, &evalOK);
523532
if (NS_FAILED(rv)) {
524533
NS_WARNING("CSP: failed to get allowsEval");
525-
return true;
534+
*aOutCanCompileStrings = true;
535+
return true;
526536
}
527537
} else {
528538
if (NS_FAILED(csp->GetAllowsWasmEval(&reportViolation, &evalOK))) {
@@ -545,8 +555,7 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
545555
auto caller = JSCallingLocation::Get(cx);
546556
nsAutoJSString scriptSample;
547557
if (aKind == JS::RuntimeCode::JS &&
548-
NS_WARN_IF(!scriptSample.init(cx, aCode))) {
549-
JS_ClearPendingException(cx);
558+
NS_WARN_IF(!scriptSample.init(cx, aCodeString))) {
550559
return false;
551560
}
552561
uint16_t violationType =
@@ -559,7 +568,8 @@ bool nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(
559568
caller.mLine, caller.mColumn, u""_ns, u""_ns);
560569
}
561570

562-
return evalOK;
571+
*aOutCanCompileStrings = evalOK;
572+
return true;
563573
}
564574

565575

caps/nsScriptSecurityManager.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class SystemPrincipal;
2828

2929
namespace JS {
3030
enum class RuntimeCode;
31+
enum class CompilationType;
3132
}
3233

3334

@@ -91,9 +92,13 @@ class nsScriptSecurityManager final : public nsIScriptSecurityManager {
9192
virtual ~nsScriptSecurityManager();
9293

9394

94-
static bool ContentSecurityPolicyPermitsJSAction(JSContext* cx,
95-
JS::RuntimeCode kind,
96-
JS::Handle<JSString*> aCode);
95+
static bool ContentSecurityPolicyPermitsJSAction(
96+
JSContext* aCx, JS::RuntimeCode aKind, JS::Handle<JSString*> aCodeString,
97+
JS::CompilationType aCompilationType,
98+
JS::Handle<JS::StackGCVector<JSString*>> aParameterStrings,
99+
JS::Handle<JSString*> aBodyString,
100+
JS::Handle<JS::StackGCVector<JS::Value>> aParameterArgs,
101+
JS::Handle<JS::Value> aBodyArg, bool* aOutCanCompileStrings);
97102

98103
static bool JSPrincipalsSubsume(JSPrincipals* first, JSPrincipals* second);
99104

dom/workers/RuntimeService.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
#include "jsfriendapi.h"
2727
#include "js/friend/ErrorMessages.h"
2828
#include "js/ContextOptions.h"
29+
#include "js/GCVector.h"
2930
#include "js/Initialization.h"
3031
#include "js/LocaleSensitive.h"
32+
#include "js/Value.h"
3133
#include "js/WasmFeatures.h"
3234
#include "mozilla/ArrayUtils.h"
3335
#include "mozilla/Atomics.h"
@@ -499,8 +501,13 @@ class LogViolationDetailsRunnable final : public WorkerMainThreadRunnable {
499501
~LogViolationDetailsRunnable() = default;
500502
};
501503

502-
bool ContentSecurityPolicyAllows(JSContext* aCx, JS::RuntimeCode aKind,
503-
JS::Handle<JSString*> aCode) {
504+
bool ContentSecurityPolicyAllows(
505+
JSContext* aCx, JS::RuntimeCode aKind, JS::Handle<JSString*> aCodeString,
506+
JS::CompilationType aCompilationType,
507+
JS::Handle<JS::StackGCVector<JSString*>> aParameterStrings,
508+
JS::Handle<JSString*> aBodyString,
509+
JS::Handle<JS::StackGCVector<JS::Value>> aParameterArgs,
510+
JS::Handle<JS::Value> aBodyArg, bool* aOutCanCompileStrings) {
504511
WorkerPrivate* worker = GetWorkerPrivateFromContext(aCx);
505512
worker->AssertIsOnWorkerThread();
506513

@@ -509,14 +516,14 @@ bool ContentSecurityPolicyAllows(JSContext* aCx, JS::RuntimeCode aKind,
509516
uint16_t violationType;
510517
nsAutoJSString scriptSample;
511518
if (aKind == JS::RuntimeCode::JS) {
512-
if (NS_WARN_IF(!scriptSample.init(aCx, aCode))) {
513-
JS_ClearPendingException(aCx);
519+
if (NS_WARN_IF(!scriptSample.init(aCx, aCodeString))) {
514520
return false;
515521
}
516522

517523
if (!nsContentSecurityUtils::IsEvalAllowed(
518524
aCx, worker->UsesSystemPrincipal(), scriptSample)) {
519-
return false;
525+
*aOutCanCompileStrings = false;
526+
return true;
520527
}
521528

522529
evalOK = worker->IsEvalAllowed();
@@ -542,7 +549,8 @@ bool ContentSecurityPolicyAllows(JSContext* aCx, JS::RuntimeCode aKind,
542549
}
543550
}
544551

545-
return evalOK;
552+
*aOutCanCompileStrings = evalOK;
553+
return true;
546554
}
547555

548556
void CTypesActivityCallback(JSContext* aCx, JS::CTypesActivityType aType) {

js/public/Principals.h

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ typedef bool (*JSSubsumesOp)(JSPrincipals* first, JSPrincipals* second);
7777

7878
namespace JS {
7979
enum class RuntimeCode { JS, WASM };
80+
enum class CompilationType { DirectEval, IndirectEval, Function, Undefined };
8081
}
8182

8283

@@ -89,8 +90,22 @@ enum class RuntimeCode { JS, WASM };
8990

9091

9192

92-
typedef bool (*JSCSPEvalChecker)(JSContext* cx, JS::RuntimeCode kind,
93-
JS::HandleString code);
93+
94+
95+
96+
97+
98+
99+
100+
101+
102+
typedef bool (*JSCSPEvalChecker)(
103+
JSContext* cx, JS::RuntimeCode kind, JS::Handle<JSString*> codeString,
104+
JS::CompilationType compilationType,
105+
JS::Handle<JS::StackGCVector<JSString*>> parameterStrings,
106+
JS::Handle<JSString*> bodyString,
107+
JS::Handle<JS::StackGCVector<JS::Value>> parameterArgs,
108+
JS::Handle<JS::Value> bodyArg, bool* outCanCompileStrings);
94109

95110

96111

js/src/builtin/Eval.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,17 @@ static bool EvalKernel(JSContext* cx, HandleValue v, EvalType evalType,
257257
}
258258

259259

260-
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::JS, str)) {
260+
JS::RootedVector<JSString*> parameterStrings(cx);
261+
JS::RootedVector<Value> parameterArgs(cx);
262+
bool canCompileStrings = false;
263+
if (!cx->isRuntimeCodeGenEnabled(
264+
JS::RuntimeCode::JS, str,
265+
evalType == DIRECT_EVAL ? JS::CompilationType::DirectEval
266+
: JS::CompilationType::IndirectEval,
267+
parameterStrings, str, parameterArgs, v, &canCompileStrings)) {
268+
return false;
269+
}
270+
if (!canCompileStrings) {
261271
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
262272
JSMSG_CSP_BLOCKED_EVAL);
263273
return false;

js/src/builtin/ShadowRealm.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,16 @@ static bool PerformShadowRealmEval(JSContext* cx, Handle<JSString*> sourceText,
196196
MOZ_ASSERT(callerRealm != evalRealm);
197197

198198

199-
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::JS, sourceText)) {
199+
JS::RootedVector<JSString*> parameterStrings(cx);
200+
JS::RootedVector<Value> parameterArgs(cx);
201+
bool canCompileStrings = false;
202+
if (!cx->isRuntimeCodeGenEnabled(JS::RuntimeCode::JS, sourceText,
203+
JS::CompilationType::Undefined,
204+
parameterStrings, nullptr, parameterArgs,
205+
NullHandleValue, &canCompileStrings)) {
206+
return false;
207+
}
208+
if (!canCompileStrings) {
200209
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
201210
JSMSG_CSP_BLOCKED_SHADOWREALM);
202211
return false;

0 commit comments

Comments
 (0)