static JSBool XPC_SJOW_CheckAccess(JSContext *cx, JSObject *obj, jsval id, JSAccessMode mode, jsval *vp) { // Prevent setting __proto__ on an XPCSafeJSObjectWrapper if ((mode & JSACC_WATCH) == JSACC_PROTO && (mode & JSACC_WRITE)) { return ThrowException(NS_ERROR_XPC_SECURITY_MANAGER_VETO, cx); } // Forward to the checkObjectAccess hook in the runtime, if any. JSSecurityCallbacks *callbacks = JS_GetSecurityCallbacks(cx); if (callbacks && callbacks->checkObjectAccess && !callbacks->checkObjectAccess(cx, obj, id, mode, vp)) { return JS_FALSE; } JSObject *unsafeObj = GetUnsafeObject(obj); if (!unsafeObj) { return JS_TRUE; } // Forward the unsafe object to the checkObjectAccess hook in the // runtime too, if any. if (callbacks && callbacks->checkObjectAccess && !callbacks->checkObjectAccess(cx, unsafeObj, id, mode, vp)) { return JS_FALSE; } JSClass *clazz = STOBJ_GET_CLASS(unsafeObj); return !clazz->checkAccess || clazz->checkAccess(cx, unsafeObj, id, mode, vp); }
static JSBool checkAccess(JSContext *cx, JSObject *obj, jsid id, JSAccessMode mode, jsval *vp) { // Forward to the checkObjectAccess hook in the runtime, if any. JSSecurityCallbacks *callbacks = JS_GetSecurityCallbacks(cx); if (callbacks && callbacks->checkObjectAccess) return callbacks->checkObjectAccess(cx, obj, id, mode, vp); JS_ReportError(cx, "Security callbacks not defined"); return JS_FALSE; }
bool GlobalObject::isEvalAllowed(JSContext *cx) { Value &v = getSlotRef(EVAL_ALLOWED); if (v.isUndefined()) { JSSecurityCallbacks *callbacks = JS_GetSecurityCallbacks(cx); /* * If there are callbacks, make sure that the CSP callback is installed * and that it permits eval(), then cache the result. */ v.setBoolean((!callbacks || !callbacks->contentSecurityPolicyAllows) || callbacks->contentSecurityPolicyAllows(cx)); } return !v.isFalse(); }
bool GlobalObject::isRuntimeCodeGenEnabled(JSContext *cx) { Value &v = getSlotRef(RUNTIME_CODEGEN_ENABLED); if (v.isUndefined()) { JSSecurityCallbacks *callbacks = JS_GetSecurityCallbacks(cx); /* * If there are callbacks, make sure that the CSP callback is installed * and that it permits runtime code generation, then cache the result. */ v.setBoolean((!callbacks || !callbacks->contentSecurityPolicyAllows) || callbacks->contentSecurityPolicyAllows(cx)); } return !v.isFalse(); }
static JSBool InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message, JSString *filename, uintN lineno, JSErrorReport *report) { JSSecurityCallbacks *callbacks; JSCheckAccessOp checkAccess; JSErrorReporter older; JSExceptionState *state; jsval callerid, v; JSStackFrame *fp, *fpstop; size_t stackDepth, valueCount, size; JSBool overflow; JSExnPrivate *priv; JSStackTraceElem *elem; jsval *values; JS_ASSERT(OBJ_GET_CLASS(cx, exnObject) == &js_ErrorClass); /* * Prepare stack trace data. * * Set aside any error reporter for cx and save its exception state * so we can suppress any checkAccess failures. Such failures should stop * the backtrace procedure, not result in a failure of this constructor. */ callbacks = JS_GetSecurityCallbacks(cx); checkAccess = callbacks ? callbacks->checkObjectAccess : NULL; older = JS_SetErrorReporter(cx, NULL); state = JS_SaveExceptionState(cx); callerid = ATOM_KEY(cx->runtime->atomState.callerAtom); stackDepth = 0; valueCount = 0; for (fp = js_GetTopStackFrame(cx); fp; fp = fp->down) { if (fp->fun && fp->argv) { v = JSVAL_NULL; if (checkAccess && !checkAccess(cx, fp->callee(), callerid, JSACC_READ, &v)) { break; } valueCount += fp->argc; } ++stackDepth; } JS_RestoreExceptionState(cx, state); JS_SetErrorReporter(cx, older); fpstop = fp; size = offsetof(JSExnPrivate, stackElems); overflow = (stackDepth > ((size_t)-1 - size) / sizeof(JSStackTraceElem)); size += stackDepth * sizeof(JSStackTraceElem); overflow |= (valueCount > ((size_t)-1 - size) / sizeof(jsval)); size += valueCount * sizeof(jsval); if (overflow) { js_ReportAllocationOverflow(cx); return JS_FALSE; } priv = (JSExnPrivate *)cx->malloc(size); if (!priv) return JS_FALSE; /* * We initialize errorReport with a copy of report after setting the * private slot, to prevent GC accessing a junk value we clear the field * here. */ priv->errorReport = NULL; priv->message = message; priv->filename = filename; priv->lineno = lineno; priv->stackDepth = stackDepth; values = GetStackTraceValueBuffer(priv); elem = priv->stackElems; for (fp = js_GetTopStackFrame(cx); fp != fpstop; fp = fp->down) { if (!fp->fun) { elem->funName = NULL; elem->argc = 0; } else { elem->funName = fp->fun->atom ? ATOM_TO_STRING(fp->fun->atom) : cx->runtime->emptyString; elem->argc = fp->argc; memcpy(values, fp->argv, fp->argc * sizeof(jsval)); values += fp->argc; } elem->ulineno = 0; elem->filename = NULL; if (fp->script) { elem->filename = fp->script->filename; if (fp->regs) elem->ulineno = js_FramePCToLineNumber(cx, fp); } ++elem; } JS_ASSERT(priv->stackElems + stackDepth == elem); JS_ASSERT(GetStackTraceValueBuffer(priv) + valueCount == values); exnObject->setPrivate(priv); if (report) { /* * Construct a new copy of the error report struct. We can't use the * error report struct that was passed in, because it's allocated on * the stack, and also because it may point to transient data in the * JSTokenStream. */ priv->errorReport = CopyErrorReport(cx, report); if (!priv->errorReport) { /* The finalizer realeases priv since it is in the private slot. */ return JS_FALSE; } } return JS_TRUE; }