Attachment #625950: Part 2 - Pull object principals directly off the compartment, and assert that behavior doesn't change. v2 for bug #754202

View | Details | Raw Unified | Return to bug 754202
Collapse All | Expand All

(-)a/caps/include/nsScriptSecurityManager.h (-4 / +3 lines)
Line     Link Here 
 Lines 434-455   private: Link Here 
434
    ObjectPrincipalFinder(JSObject *obj);
434
    ObjectPrincipalFinder(JSObject *obj);
435
    
435
    
436
    // Decides, based on CSP, whether or not eval() and stuff can be executed.
436
    // Decides, based on CSP, whether or not eval() and stuff can be executed.
437
    static JSBool
437
    static JSBool
438
    ContentSecurityPolicyPermitsJSAction(JSContext *cx);
438
    ContentSecurityPolicyPermitsJSAction(JSContext *cx);
439
439
440
    // Returns null if a principal cannot be found; generally callers
440
    // Returns null if a principal cannot be found; generally callers
441
    // should error out at that point.
441
    // should error out at that point.
442
    static nsIPrincipal*
442
    static nsIPrincipal* doGetObjectPrincipal(JSObject *obj);
443
    doGetObjectPrincipal(JSObject *obj
444
#ifdef DEBUG
443
#ifdef DEBUG
445
                         , bool aAllowShortCircuit = true
444
    static nsIPrincipal*
445
    old_doGetObjectPrincipal(JSObject *obj, bool aAllowShortCircuit = true);
446
#endif
446
#endif
447
                         );
448
447
449
    // Returns null if a principal cannot be found.  Note that rv can be NS_OK
448
    // Returns null if a principal cannot be found.  Note that rv can be NS_OK
450
    // when this happens -- this means that there was no JS running.
449
    // when this happens -- this means that there was no JS running.
451
    nsIPrincipal*
450
    nsIPrincipal*
452
    doGetSubjectPrincipal(nsresult* rv);
451
    doGetSubjectPrincipal(nsresult* rv);
453
    
452
    
454
    nsresult
453
    nsresult
455
    CheckPropertyAccessImpl(PRUint32 aAction,
454
    CheckPropertyAccessImpl(PRUint32 aAction,
(-)a/caps/src/nsScriptSecurityManager.cpp (-17 / +23 lines)
Line     Link Here 
 Lines 2415-2443   nsScriptSecurityManager::GetObjectPrincipal(JSContext *aCx, JSObject *aObj, Link Here 
2415
    if (!*result)
2415
    if (!*result)
2416
        return NS_ERROR_FAILURE;
2416
        return NS_ERROR_FAILURE;
2417
    NS_ADDREF(*result);
2417
    NS_ADDREF(*result);
2418
    return NS_OK;
2418
    return NS_OK;
2419
}
2419
}
2420
2420
2421
// static
2421
// static
2422
nsIPrincipal*
2422
nsIPrincipal*
2423
nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
2423
nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj)
2424
{
2425
    JSCompartment *compartment = js::GetObjectCompartment(aObj);
2426
    JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
2427
    nsIPrincipal *principal = nsJSPrincipals::get(principals);
2428
2429
    // We leave the old code in for a little while to make sure that pulling
2430
    // object principals directly off the compartment always gives an equivalent
2431
    // result (from a security perspective).
2424
#ifdef DEBUG
2432
#ifdef DEBUG
2425
                                              , bool aAllowShortCircuit
2433
    nsIPrincipal *old = old_doGetObjectPrincipal(aObj);
2434
    MOZ_ASSERT(NS_SUCCEEDED(CheckSameOriginPrincipal(principal, old)));
2426
#endif
2435
#endif
2427
                                              )
2436
2437
    return principal;
2438
}
2439
2440
#ifdef DEBUG
2441
// static
2442
nsIPrincipal*
2443
nsScriptSecurityManager::old_doGetObjectPrincipal(JSObject *aObj,
2444
                                                  bool aAllowShortCircuit)
2428
{
2445
{
2429
    NS_ASSERTION(aObj, "Bad call to doGetObjectPrincipal()!");
2446
    NS_ASSERTION(aObj, "Bad call to doGetObjectPrincipal()!");
2430
    nsIPrincipal* result = nsnull;
2447
    nsIPrincipal* result = nsnull;
2431
2448
2432
#ifdef DEBUG
2433
    JSObject* origObj = aObj;
2449
    JSObject* origObj = aObj;
2434
#endif
2435
    
2436
    js::Class *jsClass = js::GetObjectClass(aObj);
2450
    js::Class *jsClass = js::GetObjectClass(aObj);
2437
2451
2438
    // A common case seen in this code is that we enter this function
2452
    // A common case seen in this code is that we enter this function
2439
    // with aObj being a Function object, whose parent is a Call
2453
    // with aObj being a Function object, whose parent is a Call
2440
    // object. Neither of those have object principals, so we can skip
2454
    // object. Neither of those have object principals, so we can skip
2441
    // those objects here before we enter the below loop. That way we
2455
    // those objects here before we enter the below loop. That way we
2442
    // avoid wasting time checking properties of their classes etc in
2456
    // avoid wasting time checking properties of their classes etc in
2443
    // the loop.
2457
    // the loop.
 Lines 2461-2508   nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj Link Here 
2461
    }
2475
    }
2462
2476
2463
    do {
2477
    do {
2464
        // Note: jsClass is set before this loop, and also at the
2478
        // Note: jsClass is set before this loop, and also at the
2465
        // *end* of this loop.
2479
        // *end* of this loop.
2466
        
2480
        
2467
        if (IS_WRAPPER_CLASS(jsClass)) {
2481
        if (IS_WRAPPER_CLASS(jsClass)) {
2468
            result = sXPConnect->GetPrincipal(aObj,
2482
            result = sXPConnect->GetPrincipal(aObj,
2469
#ifdef DEBUG
2483
                                              aAllowShortCircuit);
2470
                                              aAllowShortCircuit
2471
#else
2472
                                              true
2473
#endif
2474
                                              );
2475
            if (result) {
2484
            if (result) {
2476
                break;
2485
                break;
2477
            }
2486
            }
2478
        } else {
2487
        } else {
2479
            nsISupports *priv;
2488
            nsISupports *priv;
2480
            if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
2489
            if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
2481
                                     JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
2490
                                     JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
2482
                priv = (nsISupports *) js::GetObjectPrivate(aObj);
2491
                priv = (nsISupports *) js::GetObjectPrivate(aObj);
2483
            } else if ((jsClass->flags & JSCLASS_IS_DOMJSCLASS) &&
2492
            } else if ((jsClass->flags & JSCLASS_IS_DOMJSCLASS) &&
2484
                       DOMJSClass::FromJSClass(jsClass)->mDOMObjectIsISupports) {
2493
                       DOMJSClass::FromJSClass(jsClass)->mDOMObjectIsISupports) {
2485
                priv = UnwrapDOMObject<nsISupports>(aObj, jsClass);
2494
                priv = UnwrapDOMObject<nsISupports>(aObj, jsClass);
2486
            } else {
2495
            } else {
2487
                priv = nsnull;
2496
                priv = nsnull;
2488
            }
2497
            }
2489
2498
2490
#ifdef DEBUG
2491
            if (aAllowShortCircuit) {
2499
            if (aAllowShortCircuit) {
2492
                nsCOMPtr<nsIXPConnectWrappedNative> xpcWrapper =
2500
                nsCOMPtr<nsIXPConnectWrappedNative> xpcWrapper =
2493
                    do_QueryInterface(priv);
2501
                    do_QueryInterface(priv);
2494
2502
2495
                NS_ASSERTION(!xpcWrapper ||
2503
                NS_ASSERTION(!xpcWrapper ||
2496
                             !strcmp(jsClass->name, "XPCNativeWrapper"),
2504
                             !strcmp(jsClass->name, "XPCNativeWrapper"),
2497
                             "Uh, an nsIXPConnectWrappedNative with the "
2505
                             "Uh, an nsIXPConnectWrappedNative with the "
2498
                             "wrong JSClass or getObjectOps hooks!");
2506
                             "wrong JSClass or getObjectOps hooks!");
2499
            }
2507
            }
2500
#endif
2501
2508
2502
            nsCOMPtr<nsIScriptObjectPrincipal> objPrin =
2509
            nsCOMPtr<nsIScriptObjectPrincipal> objPrin =
2503
                do_QueryInterface(priv);
2510
                do_QueryInterface(priv);
2504
2511
2505
            if (objPrin) {
2512
            if (objPrin) {
2506
                result = objPrin->GetPrincipal();
2513
                result = objPrin->GetPrincipal();
2507
2514
2508
                if (result) {
2515
                if (result) {
 Lines 2514-2543   nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj Link Here 
2514
        aObj = js::GetObjectParentMaybeScope(aObj);
2521
        aObj = js::GetObjectParentMaybeScope(aObj);
2515
2522
2516
        if (!aObj)
2523
        if (!aObj)
2517
            break;
2524
            break;
2518
2525
2519
        jsClass = js::GetObjectClass(aObj);
2526
        jsClass = js::GetObjectClass(aObj);
2520
    } while (1);
2527
    } while (1);
2521
2528
2522
#ifdef DEBUG
2523
    if (aAllowShortCircuit) {
2529
    if (aAllowShortCircuit) {
2524
        nsIPrincipal *principal = doGetObjectPrincipal(origObj, false);
2530
        nsIPrincipal *principal = old_doGetObjectPrincipal(origObj, false);
2525
2531
2526
        // Because of inner window reuse, we can have objects with one principal
2532
        // Because of inner window reuse, we can have objects with one principal
2527
        // living in a scope with a different (but same-origin) principal. So
2533
        // living in a scope with a different (but same-origin) principal. So
2528
        // just check same-origin here.
2534
        // just check same-origin here.
2529
        NS_ASSERTION(NS_SUCCEEDED(CheckSameOriginPrincipal(result, principal)),
2535
        NS_ASSERTION(NS_SUCCEEDED(CheckSameOriginPrincipal(result, principal)),
2530
                     "Principal mismatch.  Not good");
2536
                     "Principal mismatch.  Not good");
2531
    }
2537
    }
2532
#endif
2533
2538
2534
    return result;
2539
    return result;
2535
}
2540
}
2541
#endif /* DEBUG */
2536
2542
2537
///////////////// Capabilities API /////////////////////
2543
///////////////// Capabilities API /////////////////////
2538
NS_IMETHODIMP
2544
NS_IMETHODIMP
2539
nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
2545
nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
2540
                                             bool *result)
2546
                                             bool *result)
2541
{
2547
{
2542
    nsresult rv;
2548
    nsresult rv;
2543
    JSStackFrame *fp = nsnull;
2549
    JSStackFrame *fp = nsnull;

Return to bug 754202