mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 05:11:16 +00:00
Bug 924905 - Do a subsumes check inside the stack iterator. r=jandem
--HG-- extra : rebase_source : ff8407c4f79fd3e2264470379470c526a751e45f
This commit is contained in:
parent
43fccf2aec
commit
2e804616e4
@ -117,11 +117,14 @@ private:
|
||||
CheckObjectAccess(JSContext *cx, JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id, JSAccessMode mode,
|
||||
JS::MutableHandle<JS::Value> vp);
|
||||
|
||||
|
||||
// Decides, based on CSP, whether or not eval() and stuff can be executed.
|
||||
static bool
|
||||
ContentSecurityPolicyPermitsJSAction(JSContext *cx);
|
||||
|
||||
static bool
|
||||
JSPrincipalsSubsume(JSPrincipals *first, JSPrincipals *second);
|
||||
|
||||
// Returns null if a principal cannot be found; generally callers
|
||||
// should error out at that point.
|
||||
static nsIPrincipal* doGetObjectPrincipal(JSObject* obj);
|
||||
|
@ -412,7 +412,6 @@ nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
|
||||
return evalOK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
nsScriptSecurityManager::CheckObjectAccess(JSContext *cx, JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id, JSAccessMode mode,
|
||||
@ -450,6 +449,15 @@ nsScriptSecurityManager::CheckObjectAccess(JSContext *cx, JS::Handle<JSObject*>
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
nsScriptSecurityManager::JSPrincipalsSubsume(JSPrincipals *first,
|
||||
JSPrincipals *second)
|
||||
{
|
||||
return nsJSPrincipals::get(first)->Subsumes(nsJSPrincipals::get(second));
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckPropertyAccess(JSContext* cx,
|
||||
JSObject* aJSObject,
|
||||
@ -1791,7 +1799,8 @@ nsresult nsScriptSecurityManager::Init()
|
||||
|
||||
static const JSSecurityCallbacks securityCallbacks = {
|
||||
CheckObjectAccess,
|
||||
ContentSecurityPolicyPermitsJSAction
|
||||
ContentSecurityPolicyPermitsJSAction,
|
||||
JSPrincipalsSubsume,
|
||||
};
|
||||
|
||||
MOZ_ASSERT(!JS_GetSecurityCallbacks(sRuntime));
|
||||
|
@ -272,6 +272,12 @@ typedef bool
|
||||
(* JSCheckAccessOp)(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<jsid> id,
|
||||
JSAccessMode mode, JS::MutableHandle<JS::Value> vp);
|
||||
|
||||
// Return whether the first principal subsumes the second. The exact meaning of
|
||||
// 'subsumes' is left up to the browser. Subsumption is checked inside the JS
|
||||
// engine when determining, e.g., which stack frames to display in a backtrace.
|
||||
typedef bool
|
||||
(* JSSubsumesOp)(JSPrincipals *first, JSPrincipals *second);
|
||||
|
||||
// Check whether v is an instance of obj. Return false on error or exception,
|
||||
// true on success with true in *bp if v is an instance of obj, false in
|
||||
// *bp otherwise.
|
||||
|
@ -3194,6 +3194,7 @@ JS_DropPrincipals(JSRuntime *rt, JSPrincipals *principals);
|
||||
struct JSSecurityCallbacks {
|
||||
JSCheckAccessOp checkObjectAccess;
|
||||
JSCSPEvalChecker contentSecurityPolicyAllows;
|
||||
JSSubsumesOp subsumes;
|
||||
};
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
|
@ -1317,7 +1317,11 @@ JSAbstractFramePtr::evaluateUCInStackFrame(JSContext *cx,
|
||||
|
||||
JSBrokenFrameIterator::JSBrokenFrameIterator(JSContext *cx)
|
||||
{
|
||||
NonBuiltinScriptFrameIter iter(cx);
|
||||
// Show all frames on the stack whose principal is subsumed by the current principal.
|
||||
NonBuiltinScriptFrameIter iter(cx,
|
||||
ScriptFrameIter::ALL_CONTEXTS,
|
||||
ScriptFrameIter::GO_THROUGH_SAVED,
|
||||
cx->compartment()->principals);
|
||||
data_ = iter.copyData();
|
||||
}
|
||||
|
||||
|
@ -521,6 +521,18 @@ ScriptFrameIter::settleOnActivation()
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the caller supplied principals, only show activations which are subsumed (of the same
|
||||
// origin or of an origin accessible) by these principals.
|
||||
if (data_.principals_) {
|
||||
if (JSSubsumesOp subsumes = data_.cx_->runtime()->securityCallbacks->subsumes) {
|
||||
JS::AutoAssertNoGC nogc;
|
||||
if (!subsumes(data_.principals_, activation->compartment()->principals)) {
|
||||
++data_.activations_;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JS_ION
|
||||
if (activation->isJit()) {
|
||||
data_.ionFrames_ = jit::IonFrameIterator(data_.activations_);
|
||||
@ -565,11 +577,12 @@ ScriptFrameIter::settleOnActivation()
|
||||
}
|
||||
|
||||
ScriptFrameIter::Data::Data(JSContext *cx, PerThreadData *perThread, SavedOption savedOption,
|
||||
ContextOption contextOption)
|
||||
ContextOption contextOption, JSPrincipals *principals)
|
||||
: perThread_(perThread),
|
||||
cx_(cx),
|
||||
savedOption_(savedOption),
|
||||
contextOption_(contextOption),
|
||||
principals_(principals),
|
||||
pc_(nullptr),
|
||||
interpFrames_(nullptr),
|
||||
activations_(cx->runtime())
|
||||
@ -584,6 +597,7 @@ ScriptFrameIter::Data::Data(const ScriptFrameIter::Data &other)
|
||||
cx_(other.cx_),
|
||||
savedOption_(other.savedOption_),
|
||||
contextOption_(other.contextOption_),
|
||||
principals_(other.principals_),
|
||||
state_(other.state_),
|
||||
pc_(other.pc_),
|
||||
interpFrames_(other.interpFrames_),
|
||||
@ -595,7 +609,7 @@ ScriptFrameIter::Data::Data(const ScriptFrameIter::Data &other)
|
||||
}
|
||||
|
||||
ScriptFrameIter::ScriptFrameIter(JSContext *cx, SavedOption savedOption)
|
||||
: data_(cx, &cx->runtime()->mainThread, savedOption, CURRENT_CONTEXT)
|
||||
: data_(cx, &cx->runtime()->mainThread, savedOption, CURRENT_CONTEXT, nullptr)
|
||||
#ifdef JS_ION
|
||||
, ionInlineFrames_(cx, (js::jit::IonFrameIterator*) nullptr)
|
||||
#endif
|
||||
@ -603,8 +617,9 @@ ScriptFrameIter::ScriptFrameIter(JSContext *cx, SavedOption savedOption)
|
||||
settleOnActivation();
|
||||
}
|
||||
|
||||
ScriptFrameIter::ScriptFrameIter(JSContext *cx, ContextOption contextOption, SavedOption savedOption)
|
||||
: data_(cx, &cx->runtime()->mainThread, savedOption, contextOption)
|
||||
ScriptFrameIter::ScriptFrameIter(JSContext *cx, ContextOption contextOption,
|
||||
SavedOption savedOption, JSPrincipals *principals)
|
||||
: data_(cx, &cx->runtime()->mainThread, savedOption, contextOption, principals)
|
||||
#ifdef JS_ION
|
||||
, ionInlineFrames_(cx, (js::jit::IonFrameIterator*) nullptr)
|
||||
#endif
|
||||
|
@ -1449,14 +1449,15 @@ class ScriptFrameIter
|
||||
*/
|
||||
struct Data
|
||||
{
|
||||
PerThreadData *perThread_;
|
||||
JSContext *cx_;
|
||||
SavedOption savedOption_;
|
||||
ContextOption contextOption_;
|
||||
PerThreadData * perThread_;
|
||||
JSContext * cx_;
|
||||
SavedOption savedOption_;
|
||||
ContextOption contextOption_;
|
||||
JSPrincipals * principals_;
|
||||
|
||||
State state_;
|
||||
State state_;
|
||||
|
||||
jsbytecode *pc_;
|
||||
jsbytecode * pc_;
|
||||
|
||||
InterpreterFrameIterator interpFrames_;
|
||||
ActivationIterator activations_;
|
||||
@ -1466,7 +1467,7 @@ class ScriptFrameIter
|
||||
#endif
|
||||
|
||||
Data(JSContext *cx, PerThreadData *perThread, SavedOption savedOption,
|
||||
ContextOption contextOption);
|
||||
ContextOption contextOption, JSPrincipals *principals);
|
||||
Data(const Data &other);
|
||||
};
|
||||
|
||||
@ -1487,7 +1488,7 @@ class ScriptFrameIter
|
||||
|
||||
public:
|
||||
ScriptFrameIter(JSContext *cx, SavedOption = STOP_AT_SAVED);
|
||||
ScriptFrameIter(JSContext *cx, ContextOption, SavedOption);
|
||||
ScriptFrameIter(JSContext *cx, ContextOption, SavedOption, JSPrincipals* = nullptr);
|
||||
ScriptFrameIter(const ScriptFrameIter &iter);
|
||||
ScriptFrameIter(const Data &data);
|
||||
ScriptFrameIter(AbstractFramePtr frame);
|
||||
@ -1612,6 +1613,12 @@ class NonBuiltinScriptFrameIter : public ScriptFrameIter
|
||||
NonBuiltinScriptFrameIter(JSContext *cx, ScriptFrameIter::SavedOption opt = ScriptFrameIter::STOP_AT_SAVED)
|
||||
: ScriptFrameIter(cx, opt) { settle(); }
|
||||
|
||||
NonBuiltinScriptFrameIter(JSContext *cx,
|
||||
ScriptFrameIter::ContextOption contextOption,
|
||||
ScriptFrameIter::SavedOption savedOption,
|
||||
JSPrincipals *principals = nullptr)
|
||||
: ScriptFrameIter(cx, contextOption, savedOption, principals) { settle(); }
|
||||
|
||||
NonBuiltinScriptFrameIter(const ScriptFrameIter::Data &data)
|
||||
: ScriptFrameIter(data)
|
||||
{}
|
||||
|
Loading…
Reference in New Issue
Block a user