mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 451729 - " Allow runtime's security callbacks to be overridden by a context". r=brendan.
This commit is contained in:
parent
6a65adf854
commit
1e5c70827f
@ -4136,16 +4136,6 @@ JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
return OBJ_CHECK_ACCESS(cx, obj, id, mode, vp, attrsp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSCheckAccessOp)
|
||||
JS_SetCheckObjectAccessCallback(JSRuntime *rt, JSCheckAccessOp acb)
|
||||
{
|
||||
JSCheckAccessOp oldacb;
|
||||
|
||||
oldacb = rt->checkObjectAccess;
|
||||
rt->checkObjectAccess = acb;
|
||||
return oldacb;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
ReservedSlotIndexOK(JSContext *cx, JSObject *obj, JSClass *clasp,
|
||||
uint32 index, uint32 limit)
|
||||
@ -4209,24 +4199,38 @@ JS_DropPrincipals(JSContext *cx, JSPrincipals *principals)
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_PUBLIC_API(JSPrincipalsTranscoder)
|
||||
JS_SetPrincipalsTranscoder(JSRuntime *rt, JSPrincipalsTranscoder px)
|
||||
JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_SetRuntimeSecurityCallbacks(JSRuntime *rt, JSSecurityCallbacks *callbacks)
|
||||
{
|
||||
JSPrincipalsTranscoder oldpx;
|
||||
JSSecurityCallbacks *oldcallbacks;
|
||||
|
||||
oldpx = rt->principalsTranscoder;
|
||||
rt->principalsTranscoder = px;
|
||||
return oldpx;
|
||||
oldcallbacks = rt->securityCallbacks;
|
||||
rt->securityCallbacks = callbacks;
|
||||
return oldcallbacks;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSObjectPrincipalsFinder)
|
||||
JS_SetObjectPrincipalsFinder(JSRuntime *rt, JSObjectPrincipalsFinder fop)
|
||||
JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_GetRuntimeSecurityCallbacks(JSRuntime *rt)
|
||||
{
|
||||
JSObjectPrincipalsFinder oldfop;
|
||||
return rt->securityCallbacks;
|
||||
}
|
||||
|
||||
oldfop = rt->findObjectPrincipals;
|
||||
rt->findObjectPrincipals = fop;
|
||||
return oldfop;
|
||||
JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_SetContextSecurityCallbacks(JSContext *cx, JSSecurityCallbacks *callbacks)
|
||||
{
|
||||
JSSecurityCallbacks *oldcallbacks;
|
||||
|
||||
oldcallbacks = cx->securityCallbacks;
|
||||
cx->securityCallbacks = callbacks;
|
||||
return oldcallbacks;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_GetSecurityCallbacks(JSContext *cx)
|
||||
{
|
||||
return cx->securityCallbacks
|
||||
? cx->securityCallbacks
|
||||
: cx->runtime->securityCallbacks;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSFunction *)
|
||||
|
@ -1794,9 +1794,6 @@ extern JS_PUBLIC_API(JSBool)
|
||||
JS_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
jsval *vp, uintN *attrsp);
|
||||
|
||||
extern JS_PUBLIC_API(JSCheckAccessOp)
|
||||
JS_SetCheckObjectAccessCallback(JSRuntime *rt, JSCheckAccessOp acb);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_GetReservedSlot(JSContext *cx, JSObject *obj, uint32 index, jsval *vp);
|
||||
|
||||
@ -1840,11 +1837,24 @@ JS_DropPrincipals(JSContext *cx, JSPrincipals *principals);
|
||||
: (principals)->refcount)
|
||||
#endif
|
||||
|
||||
extern JS_PUBLIC_API(JSPrincipalsTranscoder)
|
||||
JS_SetPrincipalsTranscoder(JSRuntime *rt, JSPrincipalsTranscoder px);
|
||||
|
||||
extern JS_PUBLIC_API(JSObjectPrincipalsFinder)
|
||||
JS_SetObjectPrincipalsFinder(JSRuntime *rt, JSObjectPrincipalsFinder fop);
|
||||
struct JSSecurityCallbacks {
|
||||
JSCheckAccessOp checkObjectAccess;
|
||||
JSPrincipalsTranscoder principalsTranscoder;
|
||||
JSObjectPrincipalsFinder findObjectPrincipals;
|
||||
};
|
||||
|
||||
extern JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_SetRuntimeSecurityCallbacks(JSRuntime *rt, JSSecurityCallbacks *callbacks);
|
||||
|
||||
extern JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_GetRuntimeSecurityCallbacks(JSRuntime *rt);
|
||||
|
||||
extern JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_SetContextSecurityCallbacks(JSContext *cx, JSSecurityCallbacks *callbacks);
|
||||
|
||||
extern JS_PUBLIC_API(JSSecurityCallbacks *)
|
||||
JS_GetSecurityCallbacks(JSContext *cx);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
|
@ -391,16 +391,10 @@ struct JSRuntime {
|
||||
uint32 debuggerMutations;
|
||||
|
||||
/*
|
||||
* Check property accessibility for objects of arbitrary class. Used at
|
||||
* present to check f.caller accessibility for any function object f.
|
||||
* Security callbacks set on the runtime are used by each context unless
|
||||
* an override is set on the context.
|
||||
*/
|
||||
JSCheckAccessOp checkObjectAccess;
|
||||
|
||||
/* Security principals serialization support. */
|
||||
JSPrincipalsTranscoder principalsTranscoder;
|
||||
|
||||
/* Optional hook to find principals for an object in this runtime. */
|
||||
JSObjectPrincipalsFinder findObjectPrincipals;
|
||||
JSSecurityCallbacks *securityCallbacks;
|
||||
|
||||
/*
|
||||
* Shared scope property tree, and arena-pool for allocating its nodes.
|
||||
@ -887,6 +881,9 @@ struct JSContext {
|
||||
|
||||
/* Debug hooks associated with the current context. */
|
||||
JSDebugHooks *debugHooks;
|
||||
|
||||
/* Security callbacks that override any defined on the runtime. */
|
||||
JSSecurityCallbacks *securityCallbacks;
|
||||
};
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
|
@ -1007,12 +1007,13 @@ JS_GetScriptedCaller(JSContext *cx, JSStackFrame *fp)
|
||||
JS_PUBLIC_API(JSPrincipals *)
|
||||
JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
if (fp->fun) {
|
||||
JSRuntime *rt = cx->runtime;
|
||||
JSSecurityCallbacks *callbacks;
|
||||
|
||||
if (rt->findObjectPrincipals) {
|
||||
if (fp->fun) {
|
||||
callbacks = JS_GetSecurityCallbacks(cx);
|
||||
if (callbacks && callbacks->findObjectPrincipals) {
|
||||
if (FUN_OBJECT(fp->fun) != fp->callee)
|
||||
return rt->findObjectPrincipals(cx, fp->callee);
|
||||
return callbacks->findObjectPrincipals(cx, fp->callee);
|
||||
/* FALL THROUGH */
|
||||
}
|
||||
}
|
||||
@ -1024,12 +1025,12 @@ JS_StackFramePrincipals(JSContext *cx, JSStackFrame *fp)
|
||||
JS_PUBLIC_API(JSPrincipals *)
|
||||
JS_EvalFramePrincipals(JSContext *cx, JSStackFrame *fp, JSStackFrame *caller)
|
||||
{
|
||||
JSRuntime *rt;
|
||||
JSPrincipals *principals, *callerPrincipals;
|
||||
JSSecurityCallbacks *callbacks;
|
||||
|
||||
rt = cx->runtime;
|
||||
if (rt->findObjectPrincipals) {
|
||||
principals = rt->findObjectPrincipals(cx, fp->callee);
|
||||
callbacks = JS_GetSecurityCallbacks(cx);
|
||||
if (callbacks && callbacks->findObjectPrincipals) {
|
||||
principals = callbacks->findObjectPrincipals(cx, fp->callee);
|
||||
} else {
|
||||
principals = NULL;
|
||||
}
|
||||
|
@ -248,6 +248,7 @@ static JSBool
|
||||
InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
|
||||
JSString *filename, uintN lineno, JSErrorReport *report)
|
||||
{
|
||||
JSSecurityCallbacks *callbacks;
|
||||
JSCheckAccessOp checkAccess;
|
||||
JSErrorReporter older;
|
||||
JSExceptionState *state;
|
||||
@ -268,7 +269,10 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
|
||||
* so we can suppress any checkAccess failures. Such failures should stop
|
||||
* the backtrace procedure, not result in a failure of this constructor.
|
||||
*/
|
||||
checkAccess = cx->runtime->checkObjectAccess;
|
||||
callbacks = JS_GetSecurityCallbacks(cx);
|
||||
checkAccess = callbacks
|
||||
? callbacks->checkObjectAccess
|
||||
: NULL;
|
||||
older = JS_SetErrorReporter(cx, NULL);
|
||||
state = JS_SaveExceptionState(cx);
|
||||
|
||||
|
@ -966,6 +966,7 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
jsint slot;
|
||||
JSFunction *fun;
|
||||
JSStackFrame *fp;
|
||||
JSSecurityCallbacks *callbacks;
|
||||
|
||||
if (!JSVAL_IS_INT(id))
|
||||
return JS_TRUE;
|
||||
@ -1040,10 +1041,13 @@ fun_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
*vp = OBJECT_TO_JSVAL(fp->down->callee);
|
||||
else
|
||||
*vp = JSVAL_NULL;
|
||||
if (!JSVAL_IS_PRIMITIVE(*vp) && cx->runtime->checkObjectAccess) {
|
||||
id = ATOM_KEY(cx->runtime->atomState.callerAtom);
|
||||
if (!cx->runtime->checkObjectAccess(cx, obj, id, JSACC_READ, vp))
|
||||
return JS_FALSE;
|
||||
if (!JSVAL_IS_PRIMITIVE(*vp)) {
|
||||
callbacks = JS_GetSecurityCallbacks(cx);
|
||||
if (callbacks && callbacks->checkObjectAccess) {
|
||||
id = ATOM_KEY(cx->runtime->atomState.callerAtom);
|
||||
if (!callbacks->checkObjectAccess(cx, obj, id, JSACC_READ, vp))
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1408,6 +1408,8 @@ JSBool
|
||||
js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval,
|
||||
JSAccessMode mode, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
JSSecurityCallbacks *callbacks;
|
||||
|
||||
/*
|
||||
* js_InternalInvoke could result in another try to get or set the same id
|
||||
* again, see bug 355497.
|
||||
@ -1430,11 +1432,12 @@ js_InternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, jsval fval,
|
||||
* many embeddings have no security policy at all.
|
||||
*/
|
||||
JS_ASSERT(mode == JSACC_READ || mode == JSACC_WRITE);
|
||||
if (cx->runtime->checkObjectAccess &&
|
||||
callbacks = JS_GetSecurityCallbacks(cx);
|
||||
if (callbacks &&
|
||||
callbacks->checkObjectAccess &&
|
||||
VALUE_IS_FUNCTION(cx, fval) &&
|
||||
FUN_INTERPRETED(GET_FUNCTION_PRIVATE(cx, JSVAL_TO_OBJECT(fval))) &&
|
||||
!cx->runtime->checkObjectAccess(cx, obj, ID_TO_VALUE(id), mode,
|
||||
&fval)) {
|
||||
!callbacks->checkObjectAccess(cx, obj, ID_TO_VALUE(id), mode, &fval)) {
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
|
@ -1083,13 +1083,13 @@ JSBool
|
||||
js_CheckPrincipalsAccess(JSContext *cx, JSObject *scopeobj,
|
||||
JSPrincipals *principals, JSAtom *caller)
|
||||
{
|
||||
JSRuntime *rt;
|
||||
JSSecurityCallbacks *callbacks;
|
||||
JSPrincipals *scopePrincipals;
|
||||
const char *callerstr;
|
||||
|
||||
rt = cx->runtime;
|
||||
if (rt->findObjectPrincipals) {
|
||||
scopePrincipals = rt->findObjectPrincipals(cx, scopeobj);
|
||||
callbacks = JS_GetSecurityCallbacks(cx);
|
||||
if (callbacks && callbacks->findObjectPrincipals) {
|
||||
scopePrincipals = callbacks->findObjectPrincipals(cx, scopeobj);
|
||||
if (!principals || !scopePrincipals ||
|
||||
!principals->subsume(principals, scopePrincipals)) {
|
||||
callerstr = js_AtomToPrintableString(cx, caller);
|
||||
@ -1146,8 +1146,11 @@ js_ComputeFilename(JSContext *cx, JSStackFrame *caller,
|
||||
JSPrincipals *principals, uintN *linenop)
|
||||
{
|
||||
uint32 flags;
|
||||
#ifdef DEBUG
|
||||
JSSecurityCallbacks *callbacks = JS_GetSecurityCallbacks(cx);
|
||||
#endif
|
||||
|
||||
JS_ASSERT(principals || !cx->runtime->findObjectPrincipals);
|
||||
JS_ASSERT(principals || !(callbacks && callbacks->findObjectPrincipals));
|
||||
flags = JS_GetScriptFilenameFlags(caller->script);
|
||||
if ((flags & JSFILENAME_PROTECTED) &&
|
||||
principals &&
|
||||
@ -1370,7 +1373,7 @@ obj_watch_handler(JSContext *cx, JSObject *obj, jsval id, jsval old, jsval *nvp,
|
||||
void *closure)
|
||||
{
|
||||
JSObject *callable;
|
||||
JSRuntime *rt;
|
||||
JSSecurityCallbacks *callbacks;
|
||||
JSStackFrame *caller;
|
||||
JSPrincipals *subject, *watcher;
|
||||
JSResolvingKey key;
|
||||
@ -1381,8 +1384,8 @@ obj_watch_handler(JSContext *cx, JSObject *obj, jsval id, jsval old, jsval *nvp,
|
||||
|
||||
callable = (JSObject *) closure;
|
||||
|
||||
rt = cx->runtime;
|
||||
if (rt->findObjectPrincipals) {
|
||||
callbacks = JS_GetSecurityCallbacks(cx);
|
||||
if (callbacks && callbacks->findObjectPrincipals) {
|
||||
/* Skip over any obj_watch_* frames between us and the real subject. */
|
||||
caller = JS_GetScriptedCaller(cx, cx->fp);
|
||||
if (caller) {
|
||||
@ -1390,7 +1393,7 @@ obj_watch_handler(JSContext *cx, JSObject *obj, jsval id, jsval old, jsval *nvp,
|
||||
* Only call the watch handler if the watcher is allowed to watch
|
||||
* the currently executing script.
|
||||
*/
|
||||
watcher = rt->findObjectPrincipals(cx, callable);
|
||||
watcher = callbacks->findObjectPrincipals(cx, callable);
|
||||
subject = JS_StackFramePrincipals(cx, caller);
|
||||
|
||||
if (watcher && subject && !watcher->subsume(watcher, subject)) {
|
||||
@ -4465,6 +4468,7 @@ js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
JSProperty *prop;
|
||||
JSClass *clasp;
|
||||
JSScopeProperty *sprop;
|
||||
JSSecurityCallbacks *callbacks;
|
||||
JSCheckAccessOp check;
|
||||
|
||||
writing = (mode & JSACC_WRITE) != 0;
|
||||
@ -4532,8 +4536,10 @@ js_CheckAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode,
|
||||
*/
|
||||
clasp = OBJ_GET_CLASS(cx, pobj);
|
||||
check = clasp->checkAccess;
|
||||
if (!check)
|
||||
check = cx->runtime->checkObjectAccess;
|
||||
if (!check) {
|
||||
callbacks = JS_GetSecurityCallbacks(cx);
|
||||
check = callbacks ? callbacks->checkObjectAccess : NULL;
|
||||
}
|
||||
return !check || check(cx, pobj, ID_TO_VALUE(id), mode, vp);
|
||||
}
|
||||
|
||||
|
@ -153,6 +153,7 @@ typedef struct JSString JSString;
|
||||
typedef struct JSXDRState JSXDRState;
|
||||
typedef struct JSExceptionState JSExceptionState;
|
||||
typedef struct JSLocaleCallbacks JSLocaleCallbacks;
|
||||
typedef struct JSSecurityCallbacks JSSecurityCallbacks;
|
||||
|
||||
/* JSClass (and JSObjectOps where appropriate) function pointer typedefs. */
|
||||
|
||||
|
@ -428,6 +428,7 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic)
|
||||
uint32 encodeable;
|
||||
JSBool filenameWasSaved;
|
||||
jssrcnote *notes, *sn;
|
||||
JSSecurityCallbacks *callbacks;
|
||||
|
||||
cx = xdr->cx;
|
||||
script = *scriptp;
|
||||
@ -547,25 +548,26 @@ js_XDRScript(JSXDRState *xdr, JSScript **scriptp, JSBool *hasMagic)
|
||||
goto error;
|
||||
}
|
||||
|
||||
callbacks = JS_GetSecurityCallbacks(cx);
|
||||
if (xdr->mode == JSXDR_ENCODE) {
|
||||
principals = script->principals;
|
||||
encodeable = (cx->runtime->principalsTranscoder != NULL);
|
||||
encodeable = callbacks && callbacks->principalsTranscoder;
|
||||
if (!JS_XDRUint32(xdr, &encodeable))
|
||||
goto error;
|
||||
if (encodeable &&
|
||||
!cx->runtime->principalsTranscoder(xdr, &principals)) {
|
||||
!callbacks->principalsTranscoder(xdr, &principals)) {
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
if (!JS_XDRUint32(xdr, &encodeable))
|
||||
goto error;
|
||||
if (encodeable) {
|
||||
if (!cx->runtime->principalsTranscoder) {
|
||||
if (!(callbacks && callbacks->principalsTranscoder)) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_CANT_DECODE_PRINCIPALS);
|
||||
goto error;
|
||||
}
|
||||
if (!cx->runtime->principalsTranscoder(xdr, &principals))
|
||||
if (!callbacks->principalsTranscoder(xdr, &principals))
|
||||
goto error;
|
||||
script->principals = principals;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user