Exemple #1
0
// The global is used to extract the principal.
already_AddRefed<InternalRequest> InternalRequest::GetRequestConstructorCopy(
    nsIGlobalObject* aGlobal, ErrorResult& aRv) const {
  MOZ_RELEASE_ASSERT(!mURLList.IsEmpty(),
                     "Internal Request's urlList should not be empty when "
                     "copied from constructor.");
  RefPtr<InternalRequest> copy =
      new InternalRequest(mURLList.LastElement(), mFragment);
  copy->SetMethod(mMethod);
  copy->mHeaders = new InternalHeaders(*mHeaders);
  copy->SetUnsafeRequest();
  copy->mBodyStream = mBodyStream;
  copy->mBodyLength = mBodyLength;
  // The "client" is not stored in our implementation. Fetch API users should
  // use the appropriate window/document/principal and other Gecko security
  // mechanisms as appropriate.
  copy->mSameOriginDataURL = true;
  copy->mPreserveContentCodings = true;
  copy->mReferrer = mReferrer;
  copy->mReferrerPolicy = mReferrerPolicy;
  copy->mEnvironmentReferrerPolicy = mEnvironmentReferrerPolicy;
  copy->mIntegrity = mIntegrity;
  copy->mMozErrors = mMozErrors;

  copy->mContentPolicyType = mContentPolicyTypeOverridden
                                 ? mContentPolicyType
                                 : nsIContentPolicy::TYPE_FETCH;
  copy->mMode = mMode;
  copy->mCredentialsMode = mCredentialsMode;
  copy->mCacheMode = mCacheMode;
  copy->mRedirectMode = mRedirectMode;
  copy->mCreatedByFetchEvent = mCreatedByFetchEvent;
  copy->mContentPolicyTypeOverridden = mContentPolicyTypeOverridden;

  copy->mPreferredAlternativeDataType = mPreferredAlternativeDataType;
  return copy.forget();
}
static void
TestScanUnsignedMax()
{
  Input<uintmax_t> u;

  PoisonInput(u);
  sscanf("14220563454333534", "%" SCNoMAX, &u.i);
  MOZ_RELEASE_ASSERT(u.i == UINTMAX_C(432157943248732));
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));

  PoisonInput(u);
  sscanf("432157943248732", "%" SCNuMAX, &u.i);
  MOZ_RELEASE_ASSERT(u.i == UINTMAX_C(432157943248732));
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));

  PoisonInput(u);
  sscanf("4c337ca791", "%" SCNxMAX, &u.i);
  MOZ_RELEASE_ASSERT(u.i == UINTMAX_C(327281321873));
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
}
static void
TestScanUnsigned64()
{
  Input<uint64_t> u;

  PoisonInput(u);
  sscanf("17421742173", "%" SCNo64, &u.i);
  MOZ_RELEASE_ASSERT(u.i == UINT64_C(017421742173));
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));

  PoisonInput(u);
  sscanf("421786713579", "%" SCNu64, &u.i);
  MOZ_RELEASE_ASSERT(u.i == UINT64_C(421786713579));
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));

  PoisonInput(u);
  sscanf("DEADBEEF7457E", "%" SCNx64, &u.i);
  MOZ_RELEASE_ASSERT(u.i == UINT64_C(0xDEADBEEF7457E));
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
}
static void
TestScanUnsigned32()
{
  Input<uint32_t> u;

  PoisonInput(u);
  sscanf("17421742", "%" SCNo32, &u.i);
  MOZ_RELEASE_ASSERT(u.i == 017421742);
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));

  PoisonInput(u);
  sscanf("4217867", "%" SCNu32, &u.i);
  MOZ_RELEASE_ASSERT(u.i == 4217867);
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));

  PoisonInput(u);
  sscanf("2ABCBEEF", "%" SCNx32, &u.i);
  MOZ_RELEASE_ASSERT(u.i == 0x2ABCBEEF);
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
}
static void
TestScanUnsigned16()
{
  Input<uint16_t> u;

  PoisonInput(u);
  sscanf("1742", "%" SCNo16, &u.i);
  MOZ_RELEASE_ASSERT(u.i == 01742);
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));

  PoisonInput(u);
  sscanf("4217", "%" SCNu16, &u.i);
  MOZ_RELEASE_ASSERT(u.i == 4217);
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));

  PoisonInput(u);
  sscanf("2ABC", "%" SCNx16, &u.i);
  MOZ_RELEASE_ASSERT(u.i == 0x2ABC);
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
}
static void
TestScanUnsignedPtr()
{
  Input<uintptr_t> u;

  PoisonInput(u);
  sscanf("57060516", "%" SCNoPTR, &u.i);
  MOZ_RELEASE_ASSERT(u.i == uintptr_t(reinterpret_cast<void*>(12345678)));
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));

  PoisonInput(u);
  sscanf("87654321", "%" SCNuPTR, &u.i);
  MOZ_RELEASE_ASSERT(u.i == uintptr_t(reinterpret_cast<void*>(87654321)));
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));

  PoisonInput(u);
  sscanf("4c3a791", "%" SCNxPTR, &u.i);
  MOZ_RELEASE_ASSERT(u.i == uintptr_t(reinterpret_cast<void*>(0x4c3a791)));
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
}
static void
TestScanUnsigned8()
{
#if SHOULD_TEST_8BIT_FORMAT_MACROS
  Input<uint8_t> u;

  PoisonInput(u);
  sscanf("17", "%" SCNo8, &u.i);
  MOZ_RELEASE_ASSERT(u.i == 017);
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));

  PoisonInput(u);
  sscanf("42", "%" SCNu8, &u.i);
  MOZ_RELEASE_ASSERT(u.i == 42);
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));

  PoisonInput(u);
  sscanf("2A", "%" SCNx8, &u.i);
  MOZ_RELEASE_ASSERT(u.i == 0x2A);
  MOZ_RELEASE_ASSERT(ExtraBitsUntouched(u));
#endif
}
bool
GLLibraryEGL::EnsureInitialized(bool forceAccel, nsACString* const out_failureId)
{
    if (mInitialized) {
        return true;
    }

    mozilla::ScopedGfxFeatureReporter reporter("EGL");

#ifdef MOZ_B2G
    if (!sCurrentContext.init())
      MOZ_CRASH("GFX: Tls init failed");
#endif

#ifdef XP_WIN
    if (!mEGLLibrary) {
        // On Windows, the GLESv2, EGL and DXSDK libraries are shipped with libxul and
        // we should look for them there. We have to load the libs in this
        // order, because libEGL.dll depends on libGLESv2.dll which depends on the DXSDK
        // libraries. This matters especially for WebRT apps which are in a different directory.
        // See bug 760323 and bug 749459

        // Also note that we intentionally leak the libs we load.

        do {
            // Windows 8.1 has d3dcompiler_47.dll in the system directory.
            // Try it first. Note that _46 will never be in the system
            // directory and we ship with at least _43. So there is no point
            // trying _46 and _43 in the system directory.

            if (LoadLibrarySystem32(L"d3dcompiler_47.dll"))
                break;

#ifdef MOZ_D3DCOMPILER_VISTA_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_VISTA_DLL))))
                break;
#endif

#ifdef MOZ_D3DCOMPILER_XP_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_XP_DLL))))
                break;
#endif

            MOZ_ASSERT(false, "d3dcompiler DLL loading failed.");
        } while (false);

        LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libGLESv2.dll"));

        mEGLLibrary = LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libEGL.dll"));

        if (!mEGLLibrary)
            return false;
    }

#else // !Windows

    // On non-Windows (Android) we use system copies of libEGL. We look for
    // the APITrace lib, libEGL.so, and libEGL.so.1 in that order.

#if defined(ANDROID)
    if (!mEGLLibrary)
        mEGLLibrary = LoadApitraceLibrary();
#endif

    if (!mEGLLibrary) {
        printf_stderr("Attempting load of libEGL.so\n");
        mEGLLibrary = PR_LoadLibrary("libEGL.so");
    }
#if defined(XP_UNIX)
    if (!mEGLLibrary) {
        mEGLLibrary = PR_LoadLibrary("libEGL.so.1");
    }
#endif

    if (!mEGLLibrary) {
        NS_WARNING("Couldn't load EGL LIB.");
        return false;
    }

#endif // !Windows

#define SYMBOL(name) \
{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, nullptr } }

    GLLibraryLoader::SymLoadStruct earlySymbols[] = {
        SYMBOL(GetDisplay),
        SYMBOL(Terminate),
        SYMBOL(GetCurrentSurface),
        SYMBOL(GetCurrentContext),
        SYMBOL(MakeCurrent),
        SYMBOL(DestroyContext),
        SYMBOL(CreateContext),
        SYMBOL(DestroySurface),
        SYMBOL(CreateWindowSurface),
        SYMBOL(CreatePbufferSurface),
        SYMBOL(CreatePixmapSurface),
        SYMBOL(BindAPI),
        SYMBOL(Initialize),
        SYMBOL(ChooseConfig),
        SYMBOL(GetError),
        SYMBOL(GetConfigs),
        SYMBOL(GetConfigAttrib),
        SYMBOL(WaitNative),
        SYMBOL(GetProcAddress),
        SYMBOL(SwapBuffers),
        SYMBOL(CopyBuffers),
        SYMBOL(QueryString),
        SYMBOL(QueryContext),
        SYMBOL(BindTexImage),
        SYMBOL(ReleaseTexImage),
        SYMBOL(QuerySurface),
        { nullptr, { nullptr } }
    };

    if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
        NS_WARNING("Couldn't find required entry points in EGL library (early init)");
        return false;
    }

    GLLibraryLoader::SymLoadStruct optionalSymbols[] = {
        // On Android 4.3 and up, certain features like ANDROID_native_fence_sync
        // can only be queried by using a special eglQueryString.
        { (PRFuncPtr*) &mSymbols.fQueryStringImplementationANDROID,
          { "_Z35eglQueryStringImplementationANDROIDPvi", nullptr } },
        { nullptr, { nullptr } }
    };

    // Do not warn about the failure to load this - see bug 1092191
    Unused << GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0],
                                           nullptr, nullptr, false);

#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
    MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID,
                       "GFX: Couldn't find eglQueryStringImplementationANDROID");
#endif

    InitClientExtensions();

    const auto lookupFunction =
        (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;

    // Client exts are ready. (But not display exts!)
    if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*)&mSymbols.fGetPlatformDisplayEXT, { "eglGetPlatformDisplayEXT", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_platform_angle_d3d without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_platform_angle_d3d);

            mSymbols.fGetPlatformDisplayEXT = nullptr;
        }
    }

    // Check the ANGLE support the system has
    nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
    mIsANGLE = IsExtensionSupported(ANGLE_platform_angle);

    EGLDisplay chosenDisplay = nullptr;

    if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
        bool accelAngleSupport = IsAccelAngleSupported(gfxInfo, out_failureId);
        bool shouldTryAccel = forceAccel || accelAngleSupport;
        bool shouldTryWARP = !forceAccel; // Only if ANGLE not supported or fails

        // If WARP preferred, will override ANGLE support
        if (gfxPrefs::WebGLANGLEForceWARP()) {
            shouldTryWARP = true;
            shouldTryAccel = false;
        }

        // Hardware accelerated ANGLE path (supported or force accel)
        if (shouldTryAccel) {
            chosenDisplay = GetAndInitDisplayForAccelANGLE(*this);
        }

        // Fallback to a WARP display if ANGLE fails, or if WARP is forced
        if (!chosenDisplay && shouldTryWARP) {
            chosenDisplay = GetAndInitWARPDisplay(*this, EGL_DEFAULT_DISPLAY);
            if (!chosenDisplay) {
                if (out_failureId->IsEmpty()) {
                    *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WARP_FALLBACK");
                }
                NS_ERROR("Fallback WARP context failed to initialize.");
                return false;
            }
            mIsWARP = true;
        }
    } else {
        chosenDisplay = GetAndInitDisplay(*this, EGL_DEFAULT_DISPLAY);
    }

    if (!chosenDisplay) {
        if (out_failureId->IsEmpty()) {
            *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_DISPLAY");
        }
        NS_WARNING("Failed to initialize a display.");
        return false;
    }
    mEGLDisplay = chosenDisplay;

    InitDisplayExtensions();

    ////////////////////////////////////
    // Alright, load display exts.

    if (IsExtensionSupported(KHR_lock_surface)) {
        GLLibraryLoader::SymLoadStruct lockSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fLockSurface,   { "eglLockSurfaceKHR",   nullptr } },
            { (PRFuncPtr*) &mSymbols.fUnlockSurface, { "eglUnlockSurfaceKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &lockSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_lock_surface without exposing its functions!");

            MarkExtensionUnsupported(KHR_lock_surface);

            mSymbols.fLockSurface = nullptr;
            mSymbols.fUnlockSurface = nullptr;
        }
    }

    if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle);

            mSymbols.fQuerySurfacePointerANGLE = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_fence_sync)) {
        GLLibraryLoader::SymLoadStruct syncSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateSync,     { "eglCreateSyncKHR",     nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroySync,    { "eglDestroySyncKHR",    nullptr } },
            { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "eglClientWaitSyncKHR", nullptr } },
            { (PRFuncPtr*) &mSymbols.fGetSyncAttrib,  { "eglGetSyncAttribKHR",  nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &syncSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(KHR_fence_sync);

            mSymbols.fCreateSync = nullptr;
            mSymbols.fDestroySync = nullptr;
            mSymbols.fClientWaitSync = nullptr;
            mSymbols.fGetSyncAttrib = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base)) {
        GLLibraryLoader::SymLoadStruct imageSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateImage,  { "eglCreateImageKHR",  nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroyImage, { "eglDestroyImageKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &imageSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_image(_base) without exposing its functions!");

            MarkExtensionUnsupported(KHR_image);
            MarkExtensionUnsupported(KHR_image_base);
            MarkExtensionUnsupported(KHR_image_pixmap);

            mSymbols.fCreateImage = nullptr;
            mSymbols.fDestroyImage = nullptr;
        }
    } else {
        MarkExtensionUnsupported(KHR_image_pixmap);
    }

    if (IsExtensionSupported(ANDROID_native_fence_sync)) {
        GLLibraryLoader::SymLoadStruct nativeFenceSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fDupNativeFenceFDANDROID, { "eglDupNativeFenceFDANDROID", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &nativeFenceSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANDROID_native_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(ANDROID_native_fence_sync);

            mSymbols.fDupNativeFenceFDANDROID = nullptr;
        }
    }

    mInitialized = true;
    reporter.SetSuccessful();
    return true;
}
int
main()
{
    MOZ_RELEASE_ASSERT(sum({1, 2, 3, 4, 5, 6}) == 7 * 3);
    return 0;
}
RefPtr<OmxPromiseLayer::OmxCommandPromise>
OmxPromiseLayer::SendCommand(OMX_COMMANDTYPE aCmd, OMX_U32 aParam1, OMX_PTR aCmdData)
{
  if (aCmd == OMX_CommandFlush) {
    // It doesn't support another flush commands before previous one is completed.
    MOZ_RELEASE_ASSERT(!mFlushCommands.Length());

    // Some coomponents don't send event with OMX_ALL, they send flush complete
    // event with input port and another event for output port.
    // In prupose of better compatibility, we interpret the OMX_ALL to OMX_DirInput
    // and OMX_DirOutput flush separately.
    OMX_DIRTYPE types[] = {OMX_DIRTYPE::OMX_DirInput, OMX_DIRTYPE::OMX_DirOutput};
    for(const auto type : types) {
      if ((aParam1 == type) || (aParam1 == OMX_ALL)) {
        mFlushCommands.AppendElement(FlushCommand({type, aCmdData}));
      }

      if (type == OMX_DirInput) {
        // Clear all buffered raw data.
        mRawDatas.Clear();
      }
    }

    // Don't overlay more than one flush command, some components can't overlay flush commands.
    // So here we send another flush after receiving the previous flush completed event.
    if (mFlushCommands.Length()) {
      OMX_ERRORTYPE err =
        mPlatformLayer->SendCommand(OMX_CommandFlush,
                                    mFlushCommands.ElementAt(0).type,
                                    mFlushCommands.ElementAt(0).cmd);
      if (err != OMX_ErrorNone) {
        OmxCommandFailureHolder failure(OMX_ErrorNotReady, OMX_CommandFlush);
        return OmxCommandPromise::CreateAndReject(failure, __func__);
      }
    } else {
      LOG("OMX_CommandFlush parameter error");
      OmxCommandFailureHolder failure(OMX_ErrorNotReady, OMX_CommandFlush);
      return OmxCommandPromise::CreateAndReject(failure, __func__);
    }
  } else {
    OMX_ERRORTYPE err = mPlatformLayer->SendCommand(aCmd, aParam1, aCmdData);
    if (err != OMX_ErrorNone) {
      OmxCommandFailureHolder failure(OMX_ErrorNotReady, aCmd);
      return OmxCommandPromise::CreateAndReject(failure, __func__);
    }
  }

  RefPtr<OmxCommandPromise> p;
  if (aCmd == OMX_CommandStateSet) {
    p = mCommandStatePromise.Ensure(__func__);
  } else if (aCmd == OMX_CommandFlush) {
    p = mFlushPromise.Ensure(__func__);
  } else if (aCmd == OMX_CommandPortEnable) {
    p = mPortEnablePromise.Ensure(__func__);
  } else if (aCmd == OMX_CommandPortDisable) {
    p = mPortDisablePromise.Ensure(__func__);
  } else {
    LOG("error unsupport command");
    MOZ_ASSERT(0);
  }

  return p;
}
Exemple #11
0
void
js::ThisThread::GetName(char* nameBuffer, size_t len)
{
  MOZ_RELEASE_ASSERT(len > 0);
  *nameBuffer = '\0';
}
void
OriginAttributes::CreateSuffix(nsACString& aStr) const
{
  UniquePtr<URLParams> params(new URLParams());
  nsAutoString value;

  //
  // Important: While serializing any string-valued attributes, perform a
  // release-mode assertion to make sure that they don't contain characters that
  // will break the quota manager when it uses the serialization for file
  // naming (see addonId below).
  //

  if (mAppId != nsIScriptSecurityManager::NO_APP_ID) {
    value.AppendInt(mAppId);
    params->Set(NS_LITERAL_STRING("appId"), value);
  }

  if (mInIsolatedMozBrowser) {
    params->Set(NS_LITERAL_STRING("inBrowser"), NS_LITERAL_STRING("1"));
  }

  if (!mAddonId.IsEmpty()) {
    if (mAddonId.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) != kNotFound) {
#ifdef MOZ_CRASHREPORTER
      CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("Crash_AddonId"),
                                         NS_ConvertUTF16toUTF8(mAddonId));
#endif
      MOZ_CRASH();
    }
    params->Set(NS_LITERAL_STRING("addonId"), mAddonId);
  }

  if (mUserContextId != nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID) {
    value.Truncate();
    value.AppendInt(mUserContextId);
    params->Set(NS_LITERAL_STRING("userContextId"), value);
  }


  if (mPrivateBrowsingId) {
    value.Truncate();
    value.AppendInt(mPrivateBrowsingId);
    params->Set(NS_LITERAL_STRING("privateBrowsingId"), value);
  }

  if (!mFirstPartyDomain.IsEmpty()) {
    MOZ_RELEASE_ASSERT(mFirstPartyDomain.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
    params->Set(NS_LITERAL_STRING("firstPartyDomain"), mFirstPartyDomain);
  }

  aStr.Truncate();

  params->Serialize(value);
  if (!value.IsEmpty()) {
    aStr.AppendLiteral("^");
    aStr.Append(NS_ConvertUTF16toUTF8(value));
  }

// In debug builds, check the whole string for illegal characters too (just in case).
#ifdef DEBUG
  nsAutoCString str;
  str.Assign(aStr);
  MOZ_ASSERT(str.FindCharInSet(dom::quota::QuotaManager::kReplaceChars) == kNotFound);
#endif
}
void
unmapPages(void* p, size_t size)
{
    if (munmap(p, size))
        MOZ_RELEASE_ASSERT(errno == ENOMEM);
}
void
ThreadStackHelper::CollectNativeLeafAddr(void* aAddr)
{
  MOZ_RELEASE_ASSERT(mStackToFill);
  TryAppendFrame(HangEntryProgCounter(reinterpret_cast<uintptr_t>(aAddr)));
}
Exemple #15
0
void
SharedSurface_SurfaceTexture::WaitForBufferOwnership()
{
    MOZ_RELEASE_ASSERT(!mSurface->GetAvailable());
    mSurface->SetAvailable(true);
}
/* static */
const CanonicalBrowsingContext* CanonicalBrowsingContext::Cast(
    const BrowsingContext* aContext) {
  MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
  return static_cast<const CanonicalBrowsingContext*>(aContext);
}
Exemple #17
0
bool
GLLibraryEGL::EnsureInitialized()
{
    if (mInitialized) {
        return true;
    }

    mozilla::ScopedGfxFeatureReporter reporter("EGL");

#ifdef MOZ_B2G
    if (!sCurrentContext.init())
      MOZ_CRASH("Tls init failed");
#endif

#ifdef XP_WIN
    if (!mEGLLibrary) {
        // On Windows, the GLESv2, EGL and DXSDK libraries are shipped with libxul and
        // we should look for them there. We have to load the libs in this
        // order, because libEGL.dll depends on libGLESv2.dll which depends on the DXSDK
        // libraries. This matters especially for WebRT apps which are in a different directory.
        // See bug 760323 and bug 749459

        // Also note that we intentionally leak the libs we load.

        do {
            // Windows 8.1 has d3dcompiler_47.dll in the system directory.
            // Try it first. Note that _46 will never be in the system
            // directory and we ship with at least _43. So there is no point
            // trying _46 and _43 in the system directory.

            if (LoadLibrarySystem32(L"d3dcompiler_47.dll"))
                break;

#ifdef MOZ_D3DCOMPILER_VISTA_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_VISTA_DLL))))
                break;
#endif

#ifdef MOZ_D3DCOMPILER_XP_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_XP_DLL))))
                break;
#endif

            MOZ_ASSERT(false, "d3dcompiler DLL loading failed.");
        } while (false);

        LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libGLESv2.dll"));

        mEGLLibrary = LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libEGL.dll"));

        if (!mEGLLibrary)
            return false;
    }

#else // !Windows

    // On non-Windows (Android) we use system copies of libEGL. We look for
    // the APITrace lib, libEGL.so, and libEGL.so.1 in that order.

#if defined(ANDROID)
    if (!mEGLLibrary)
        mEGLLibrary = LoadApitraceLibrary();
#endif

    if (!mEGLLibrary) {
        printf_stderr("Attempting load of libEGL.so\n");
        mEGLLibrary = PR_LoadLibrary("libEGL.so");
    }
#if defined(XP_UNIX)
    if (!mEGLLibrary) {
        mEGLLibrary = PR_LoadLibrary("libEGL.so.1");
    }
#endif

    if (!mEGLLibrary) {
        NS_WARNING("Couldn't load EGL LIB.");
        return false;
    }

#endif // !Windows

#define SYMBOL(name) \
{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, nullptr } }

    GLLibraryLoader::SymLoadStruct earlySymbols[] = {
        SYMBOL(GetDisplay),
        SYMBOL(Terminate),
        SYMBOL(GetCurrentSurface),
        SYMBOL(GetCurrentContext),
        SYMBOL(MakeCurrent),
        SYMBOL(DestroyContext),
        SYMBOL(CreateContext),
        SYMBOL(DestroySurface),
        SYMBOL(CreateWindowSurface),
        SYMBOL(CreatePbufferSurface),
        SYMBOL(CreatePixmapSurface),
        SYMBOL(BindAPI),
        SYMBOL(Initialize),
        SYMBOL(ChooseConfig),
        SYMBOL(GetError),
        SYMBOL(GetConfigs),
        SYMBOL(GetConfigAttrib),
        SYMBOL(WaitNative),
        SYMBOL(GetProcAddress),
        SYMBOL(SwapBuffers),
        SYMBOL(CopyBuffers),
        SYMBOL(QueryString),
        SYMBOL(QueryContext),
        SYMBOL(BindTexImage),
        SYMBOL(ReleaseTexImage),
        SYMBOL(QuerySurface),
        { nullptr, { nullptr } }
    };

    if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
        NS_WARNING("Couldn't find required entry points in EGL library (early init)");
        return false;
    }

    GLLibraryLoader::SymLoadStruct optionalSymbols[] = {
        // On Android 4.3 and up, certain features like ANDROID_native_fence_sync
        // can only be queried by using a special eglQueryString.
        { (PRFuncPtr*) &mSymbols.fQueryStringImplementationANDROID,
          { "_Z35eglQueryStringImplementationANDROIDPvi", nullptr } },
        { nullptr, { nullptr } }
    };

    // Do not warn about the failure to load this - see bug 1092191
    GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0], nullptr, nullptr,
                                 false);

#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
    MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID,
                       "Couldn't find eglQueryStringImplementationANDROID");
#endif

    //Initialize client extensions
    InitExtensionsFromDisplay(EGL_NO_DISPLAY);

    GLLibraryLoader::PlatformLookupFunction lookupFunction =
        (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;

#ifdef XP_WIN
    if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*)&mSymbols.fGetPlatformDisplayEXT, { "eglGetPlatformDisplayEXT", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_platform_angle_d3d without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_platform_angle_d3d);

            mSymbols.fGetPlatformDisplayEXT = nullptr;
        }
    }
#endif

    mEGLDisplay = GetAndInitDisplay(*this, EGL_DEFAULT_DISPLAY);

    const char* vendor = (char*)fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
    if (vendor && (strstr(vendor, "TransGaming") != 0 ||
                   strstr(vendor, "Google Inc.") != 0))
    {
        mIsANGLE = true;
    }

    if (mIsANGLE) {
        EGLDisplay newDisplay = EGL_NO_DISPLAY;

        // D3D11 ANGLE only works with OMTC; there's a bug in the non-OMTC layer
        // manager, and it's pointless to try to fix it.  We also don't try
        // D3D11 ANGLE if the layer manager is prefering D3D9 (hrm, do we care?)
        if (gfxPrefs::LayersOffMainThreadCompositionEnabled() &&
            !gfxPrefs::LayersPreferD3D9())
        {
            if (gfxPrefs::WebGLANGLEForceD3D11()) {
                newDisplay = GetAndInitDisplay(*this,
                                               LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE);
            } else if (gfxPrefs::WebGLANGLETryD3D11() && gfxPlatform::CanUseDirect3D11ANGLE()) {
                newDisplay = GetAndInitDisplay(*this,
                                               LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE);
            }
        }

        if (newDisplay != EGL_NO_DISPLAY) {
            DebugOnly<EGLBoolean> success = fTerminate(mEGLDisplay);
            MOZ_ASSERT(success == LOCAL_EGL_TRUE);

            mEGLDisplay = newDisplay;

            vendor = (char*)fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
        }
    }

    InitExtensionsFromDisplay(mEGLDisplay);

    if (IsExtensionSupported(KHR_lock_surface)) {
        GLLibraryLoader::SymLoadStruct lockSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fLockSurface,   { "eglLockSurfaceKHR",   nullptr } },
            { (PRFuncPtr*) &mSymbols.fUnlockSurface, { "eglUnlockSurfaceKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &lockSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_lock_surface without exposing its functions!");

            MarkExtensionUnsupported(KHR_lock_surface);

            mSymbols.fLockSurface = nullptr;
            mSymbols.fUnlockSurface = nullptr;
        }
    }

    if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle);

            mSymbols.fQuerySurfacePointerANGLE = nullptr;
        }
    }

    //XXX: use correct extension name
    if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*)&mSymbols.fSurfaceReleaseSyncANGLE, { "eglSurfaceReleaseSyncANGLE", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle);

            mSymbols.fSurfaceReleaseSyncANGLE = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_fence_sync)) {
        GLLibraryLoader::SymLoadStruct syncSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateSync,     { "eglCreateSyncKHR",     nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroySync,    { "eglDestroySyncKHR",    nullptr } },
            { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "eglClientWaitSyncKHR", nullptr } },
            { (PRFuncPtr*) &mSymbols.fGetSyncAttrib,  { "eglGetSyncAttribKHR",  nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &syncSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(KHR_fence_sync);

            mSymbols.fCreateSync = nullptr;
            mSymbols.fDestroySync = nullptr;
            mSymbols.fClientWaitSync = nullptr;
            mSymbols.fGetSyncAttrib = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base)) {
        GLLibraryLoader::SymLoadStruct imageSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateImage,  { "eglCreateImageKHR",  nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroyImage, { "eglDestroyImageKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &imageSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_image(_base) without exposing its functions!");

            MarkExtensionUnsupported(KHR_image);
            MarkExtensionUnsupported(KHR_image_base);
            MarkExtensionUnsupported(KHR_image_pixmap);

            mSymbols.fCreateImage = nullptr;
            mSymbols.fDestroyImage = nullptr;
        }
    } else {
        MarkExtensionUnsupported(KHR_image_pixmap);
    }

    if (IsExtensionSupported(ANDROID_native_fence_sync)) {
        GLLibraryLoader::SymLoadStruct nativeFenceSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fDupNativeFenceFDANDROID, { "eglDupNativeFenceFDANDROID", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &nativeFenceSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANDROID_native_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(ANDROID_native_fence_sync);

            mSymbols.fDupNativeFenceFDANDROID = nullptr;
        }
    }

    mInitialized = true;
    reporter.SetSuccessful();
    return true;
}
void
ThreadStackHelper::CollectJitReturnAddr(void* aAddr)
{
  MOZ_RELEASE_ASSERT(mStackToFill);
  TryAppendFrame(HangEntryJit());
}
Exemple #19
0
void
VsyncBridgeChild::ProcessingError(Result aCode, const char* aReason)
{
  MOZ_RELEASE_ASSERT(aCode == MsgDropped, "Processing error in VsyncBridgeChild");
}
void
ThreadStackHelper::CollectPseudoEntry(const js::ProfileEntry& aEntry)
{
  // For non-js frames we just include the raw label.
  if (!aEntry.isJs()) {
    const char* entryLabel = aEntry.label();

    // entryLabel is a statically allocated string, so we want to store a
    // reference to it without performing any allocations. This is important, as
    // we aren't allowed to allocate within this function.
    //
    // The variant for this kind of label in our HangStack object is a
    // `nsCString`, which normally contains heap allocated string data. However,
    // `nsCString` has an optimization for literal strings which causes the
    // backing data to not be copied when being copied between nsCString
    // objects.
    //
    // We take advantage of that optimization by creating a nsCString object
    // which has the LITERAL flag set. Without this optimization, this code
    // would be incorrect.
    nsCString label;
    label.AssignLiteral(entryLabel, strlen(entryLabel));

    // Let's make sure we don't deadlock here, by asserting that `label`'s
    // backing data matches.
    MOZ_RELEASE_ASSERT(label.BeginReading() == entryLabel,
        "String copy performed during ThreadStackHelper::CollectPseudoEntry");
    TryAppendFrame(label);
    return;
  }

  if (!aEntry.script()) {
    TryAppendFrame(HangEntrySuppressed());
    return;
  }

  if (!IsChromeJSScript(aEntry.script())) {
    TryAppendFrame(HangEntryContent());
    return;
  }

  // Rather than using the profiler's dynamic string, we compute our own string.
  // This is because we want to do some size-saving strategies, and throw out
  // information which won't help us as much.
  // XXX: We currently don't collect the function name which hung.
  const char* filename = JS_GetScriptFilename(aEntry.script());
  unsigned lineno = JS_PCToLineNumber(aEntry.script(), aEntry.pc());

  // Some script names are in the form "foo -> bar -> baz".
  // Here we find the origin of these redirected scripts.
  const char* basename = GetPathAfterComponent(filename, " -> ");
  if (basename) {
    filename = basename;
  }

  // Strip chrome:// or resource:// off of the filename if present.
  basename = GetFullPathForScheme(filename, "chrome://");
  if (!basename) {
    basename = GetFullPathForScheme(filename, "resource://");
  }
  if (!basename) {
    // If we're in an add-on script, under the {profile}/extensions
    // directory, extract the path after the /extensions/ part.
    basename = GetPathAfterComponent(filename, "/extensions/");
  }
  if (!basename) {
    // Only keep the file base name for paths outside the above formats.
    basename = strrchr(filename, '/');
    basename = basename ? basename + 1 : filename;
    // Look for Windows path separator as well.
    filename = strrchr(basename, '\\');
    if (filename) {
      basename = filename + 1;
    }
  }

  char buffer[128]; // Enough to fit longest js file name from the tree
  size_t len = SprintfLiteral(buffer, "%s:%u", basename, lineno);
  if (len < sizeof(buffer)) {
    mDesiredBufferSize += len + 1;

    if (mStackToFill->stack().Capacity() > mStackToFill->stack().Length() &&
        (mStackToFill->strbuffer().Capacity() -
         mStackToFill->strbuffer().Length()) > len + 1) {
      // NOTE: We only increment this if we're going to successfully append.
      mDesiredStackSize += 1;
      uint32_t start = mStackToFill->strbuffer().Length();
      mStackToFill->strbuffer().AppendElements(buffer, len);
      mStackToFill->strbuffer().AppendElement('\0');
      mStackToFill->stack().AppendElement(HangEntryBufOffset(start));
      return;
    }
  }

  TryAppendFrame(HangEntryChromeScript());
}
bool
BasePrincipal::Subsumes(nsIPrincipal* aOther, DocumentDomainConsideration aConsideration)
{
  MOZ_RELEASE_ASSERT(aOther, "The caller is performing a nonsensical security check!");
  return SubsumesInternal(aOther, aConsideration);
}
void
PackagedAppVerifier::OnManifestVerified(bool aSuccess)
{
  MOZ_RELEASE_ASSERT(NS_IsMainThread(), "OnManifestVerified must be on main thread.");

  LOG(("PackagedAppVerifier::OnManifestVerified: %d", aSuccess));

  // The listener could have been removed before we verify the resource.
  if (!mListener) {
    return;
  }


  if (!aSuccess && mBypassVerification) {
    aSuccess = true;
    LOG(("Developer mode! Treat junk signature valid."));
  }

  if (aSuccess && !mSignature.IsEmpty()) {
    // Get the package location from the manifest
    nsAutoCString packageOrigin;
    mPackagedAppUtils->GetPackageOrigin(packageOrigin);
    if (packageOrigin != mPackageOrigin) {
      aSuccess = false;
      LOG(("moz-package-location doesn't match:\nFrom: %s\nManifest: %s\n", mPackageOrigin.get(), packageOrigin.get()));
    }
  }

  // Only when the manifest verified and package has signature would we
  // regard this package is signed.
  mIsPackageSigned = aSuccess && !mSignature.IsEmpty();

  mState = aSuccess ? STATE_MANIFEST_VERIFIED_OK
                    : STATE_MANIFEST_VERIFIED_FAILED;

  // Obtain the package identifier from manifest if the package is signed.
  if (mIsPackageSigned) {
    mPackagedAppUtils->GetPackageIdentifier(mPackageIdentifer);
    LOG(("PackageIdentifer is: %s", mPackageIdentifer.get()));
  }

  // If the package is signed, add related info to the package cache.
  if (mIsPackageSigned && mPackageCacheEntry) {
    LOG(("This package is signed. Add this info to the cache channel."));
    if (mPackageCacheEntry) {
      mPackageCacheEntry->SetMetaDataElement(kSignedPakIdMetadataKey,
                                             mPackageIdentifer.get());
      mPackageCacheEntry = nullptr; // the cache entry is no longer needed.
    }
  }

  RefPtr<ResourceCacheInfo> info(mPendingResourceCacheInfoList.popFirst());
  MOZ_ASSERT(info);

  mListener->OnVerified(true, // aIsManifest.
                        info->mURI,
                        info->mCacheEntry,
                        info->mStatusCode,
                        info->mIsLastPart,
                        aSuccess);

  LOG(("Ready to verify resources that were cached during verification"));
  // Verify the resources which were cached during verification accordingly.
  for (auto i = mPendingResourceCacheInfoList.getFirst(); i; i = i->getNext()) {
    VerifyResource(i);
  }
}
Exemple #23
0
js::Thread::~Thread()
{
  LockGuard<Mutex> lock(idMutex_);
  MOZ_RELEASE_ASSERT(!joinable(lock));
}
Exemple #24
0
static void
BroadcastSetThreadSandbox(const sock_fprog* aFilter)
{
  pid_t pid, tid, myTid;
  DIR *taskdp;
  struct dirent *de;

  // This function does not own *aFilter, so this global needs to
  // always be zeroed before returning.
  gSetSandboxFilter = aFilter;

  static_assert(sizeof(mozilla::Atomic<int>) == sizeof(int),
                "mozilla::Atomic<int> isn't represented by an int");
  pid = getpid();
  myTid = syscall(__NR_gettid);
  taskdp = opendir("/proc/self/task");
  if (taskdp == nullptr) {
    SANDBOX_LOG_ERROR("opendir /proc/self/task: %s\n", strerror(errno));
    MOZ_CRASH();
  }

  EnterChroot();

  // In case this races with a not-yet-deprivileged thread cloning
  // itself, repeat iterating over all threads until we find none
  // that are still privileged.
  bool sandboxProgress;
  do {
    sandboxProgress = false;
    // For each thread...
    while ((de = readdir(taskdp))) {
      char *endptr;
      tid = strtol(de->d_name, &endptr, 10);
      if (*endptr != '\0' || tid <= 0) {
        // Not a task ID.
        continue;
      }
      if (tid == myTid) {
        // Drop this thread's privileges last, below, so we can
        // continue to signal other threads.
        continue;
      }

      MOZ_RELEASE_ASSERT(gSeccompTsyncBroadcastSignum != 0);

      // Reset the futex cell and signal.
      gSetSandboxDone = 0;
      if (syscall(__NR_tgkill, pid, tid, gSeccompTsyncBroadcastSignum) != 0) {
        if (errno == ESRCH) {
          SANDBOX_LOG_ERROR("Thread %d unexpectedly exited.", tid);
          // Rescan threads, in case it forked before exiting.
          sandboxProgress = true;
          continue;
        }
        SANDBOX_LOG_ERROR("tgkill(%d,%d): %s\n", pid, tid, strerror(errno));
        MOZ_CRASH();
      }
      // It's unlikely, but if the thread somehow manages to exit
      // after receiving the signal but before entering the signal
      // handler, we need to avoid blocking forever.
      //
      // Using futex directly lets the signal handler send the wakeup
      // from an async signal handler (pthread mutex/condvar calls
      // aren't allowed), and to use a relative timeout that isn't
      // affected by changes to the system clock (not possible with
      // POSIX semaphores).
      //
      // If a thread doesn't respond within a reasonable amount of
      // time, but still exists, we crash -- the alternative is either
      // blocking forever or silently losing security, and it
      // shouldn't actually happen.
      static const int crashDelay = 10; // seconds
      struct timespec timeLimit;
      clock_gettime(CLOCK_MONOTONIC, &timeLimit);
      timeLimit.tv_sec += crashDelay;
      while (true) {
        static const struct timespec futexTimeout = { 0, 10*1000*1000 }; // 10ms
        // Atomically: if gSetSandboxDone == 0, then sleep.
        if (syscall(__NR_futex, reinterpret_cast<int*>(&gSetSandboxDone),
                  FUTEX_WAIT, 0, &futexTimeout) != 0) {
          if (errno != EWOULDBLOCK && errno != ETIMEDOUT && errno != EINTR) {
            SANDBOX_LOG_ERROR("FUTEX_WAIT: %s\n", strerror(errno));
            MOZ_CRASH();
          }
        }
        // Did the handler finish?
        if (gSetSandboxDone > 0) {
          if (gSetSandboxDone == 2) {
            sandboxProgress = true;
          }
          break;
        }
        // Has the thread ceased to exist?
        if (syscall(__NR_tgkill, pid, tid, 0) != 0) {
          if (errno == ESRCH) {
            SANDBOX_LOG_ERROR("Thread %d unexpectedly exited.", tid);
          }
          // Rescan threads, in case it forked before exiting.
          // Also, if it somehow failed in a way that wasn't ESRCH,
          // and still exists, that will be handled on the next pass.
          sandboxProgress = true;
          break;
        }
        struct timespec now;
        clock_gettime(CLOCK_MONOTONIC, &now);
        if (now.tv_sec > timeLimit.tv_sec ||
            (now.tv_sec == timeLimit.tv_sec &&
             now.tv_nsec > timeLimit.tv_nsec)) {
          SANDBOX_LOG_ERROR("Thread %d unresponsive for %d seconds."
                            "  Killing process.",
                            tid, crashDelay);
          MOZ_CRASH();
        }
      }
    }
    rewinddir(taskdp);
  } while (sandboxProgress);

  void (*oldHandler)(int);
  oldHandler = signal(gSeccompTsyncBroadcastSignum, SIG_DFL);
  gSeccompTsyncBroadcastSignum = 0;
  if (oldHandler != SetThreadSandboxHandler) {
    // See the comment on FindFreeSignalNumber about race conditions.
    SANDBOX_LOG_ERROR("handler for signal %d was changed to %p!",
                      gSeccompTsyncBroadcastSignum, oldHandler);
    MOZ_CRASH();
  }
  Unused << closedir(taskdp);
  // And now, deprivilege the main thread:
  SetThreadSandbox();
  gSetSandboxFilter = nullptr;
}
void
SandboxBroker::SetSecurityLevelForContentProcess(int32_t aSandboxLevel)
{
  MOZ_RELEASE_ASSERT(mPolicy, "mPolicy must be set before this call.");

  sandbox::JobLevel jobLevel;
  sandbox::TokenLevel accessTokenLevel;
  sandbox::IntegrityLevel initialIntegrityLevel;
  sandbox::IntegrityLevel delayedIntegrityLevel;

  // The setting of these levels is pretty arbitrary, but they are a useful (if
  // crude) tool while we are tightening the policy. Gaps are left to try and
  // avoid changing their meaning.
  MOZ_RELEASE_ASSERT(aSandboxLevel >= 1, "Should not be called with aSandboxLevel < 1");
  if (aSandboxLevel >= 20) {
    jobLevel = sandbox::JOB_LOCKDOWN;
    accessTokenLevel = sandbox::USER_LOCKDOWN;
    initialIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
    delayedIntegrityLevel = sandbox::INTEGRITY_LEVEL_UNTRUSTED;
  } else if (aSandboxLevel >= 10) {
    jobLevel = sandbox::JOB_RESTRICTED;
    accessTokenLevel = sandbox::USER_LIMITED;
    initialIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
    delayedIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
  } else if (aSandboxLevel >= 2) {
    jobLevel = sandbox::JOB_INTERACTIVE;
    accessTokenLevel = sandbox::USER_INTERACTIVE;
    initialIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
    delayedIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
  } else if (aSandboxLevel == 1) {
    jobLevel = sandbox::JOB_NONE;
    accessTokenLevel = sandbox::USER_NON_ADMIN;
    initialIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
    delayedIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
  }

  sandbox::ResultCode result = mPolicy->SetJobLevel(jobLevel,
                                                    0 /* ui_exceptions */);
  MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
                     "Setting job level failed, have you set memory limit when jobLevel == JOB_NONE?");

  result = mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
                                  accessTokenLevel);
  MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
                     "Lockdown level cannot be USER_UNPROTECTED or USER_LAST if initial level was USER_RESTRICTED_SAME_ACCESS");

  result = mPolicy->SetIntegrityLevel(initialIntegrityLevel);
  MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
                     "SetIntegrityLevel should never fail, what happened?");
  result = mPolicy->SetDelayedIntegrityLevel(delayedIntegrityLevel);
  MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
                     "SetDelayedIntegrityLevel should never fail, what happened?");

  if (aSandboxLevel > 2) {
    result = mPolicy->SetAlternateDesktop(true);
    MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
                       "Failed to create alternate desktop for sandbox.");
  }

  sandbox::MitigationFlags mitigations =
    sandbox::MITIGATION_BOTTOM_UP_ASLR |
    sandbox::MITIGATION_HEAP_TERMINATE |
    sandbox::MITIGATION_SEHOP |
    sandbox::MITIGATION_DEP_NO_ATL_THUNK |
    sandbox::MITIGATION_DEP;

  result = mPolicy->SetProcessMitigations(mitigations);
  MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
                     "Invalid flags for SetProcessMitigations.");

  mitigations =
    sandbox::MITIGATION_STRICT_HANDLE_CHECKS |
    sandbox::MITIGATION_DLL_SEARCH_ORDER;

  result = mPolicy->SetDelayedProcessMitigations(mitigations);
  MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
                     "Invalid flags for SetDelayedProcessMitigations.");

  // Add the policy for the client side of a pipe. It is just a file
  // in the \pipe\ namespace. We restrict it to pipes that start with
  // "chrome." so the sandboxed process cannot connect to system services.
  result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
                            sandbox::TargetPolicy::FILES_ALLOW_ANY,
                            L"\\??\\pipe\\chrome.*");
  MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
                     "With these static arguments AddRule should never fail, what happened?");

  // Add the policy for the client side of the crash server pipe.
  result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
                            sandbox::TargetPolicy::FILES_ALLOW_ANY,
                            L"\\??\\pipe\\gecko-crash-server-pipe.*");
  MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
                     "With these static arguments AddRule should never fail, what happened?");

  // The content process needs to be able to duplicate named pipes back to the
  // broker process, which are File type handles.
  result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
                            sandbox::TargetPolicy::HANDLES_DUP_BROKER,
                            L"File");
  MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
                     "With these static arguments AddRule should never fail, what happened?");

  // The content process needs to be able to duplicate shared memory handles,
  // which are Section handles, to the broker process and other child processes.
  result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
                            sandbox::TargetPolicy::HANDLES_DUP_BROKER,
                            L"Section");
  MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
                     "With these static arguments AddRule should never fail, what happened?");
  result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
                            sandbox::TargetPolicy::HANDLES_DUP_ANY,
                            L"Section");
  MOZ_RELEASE_ASSERT(sandbox::SBOX_ALL_OK == result,
                     "With these static arguments AddRule should never fail, what happened?");
}
Exemple #26
0
void
SandboxEarlyInit(GeckoProcessType aType)
{
  const SandboxInfo info = SandboxInfo::Get();
  if (info.Test(SandboxInfo::kUnexpectedThreads)) {
    return;
  }
  MOZ_RELEASE_ASSERT(IsSingleThreaded());

  // Which kinds of resource isolation (of those that need to be set
  // up at this point) can be used by this process?
  bool canChroot = false;
  bool canUnshareNet = false;
  bool canUnshareIPC = false;

  switch (aType) {
  case GeckoProcessType_Default:
    MOZ_ASSERT(false, "SandboxEarlyInit in parent process");
    return;
#ifdef MOZ_GMP_SANDBOX
  case GeckoProcessType_GMPlugin:
    if (!info.Test(SandboxInfo::kEnabledForMedia)) {
      break;
    }
    canUnshareNet = true;
    canUnshareIPC = true;
    // Need seccomp-bpf to intercept open().
    canChroot = info.Test(SandboxInfo::kHasSeccompBPF);
    break;
#endif
    // In the future, content processes will be able to use some of
    // these.
  default:
    // Other cases intentionally left blank.
    break;
  }

  // If TSYNC is not supported, set up signal handler
  // used to enable seccomp on each thread.
  if (!info.Test(SandboxInfo::kHasSeccompTSync)) {
    gSeccompTsyncBroadcastSignum = FindFreeSignalNumber();
    if (gSeccompTsyncBroadcastSignum == 0) {
      SANDBOX_LOG_ERROR("No available signal numbers!");
      MOZ_CRASH();
    }

    void (*oldHandler)(int);
    oldHandler = signal(gSeccompTsyncBroadcastSignum, SetThreadSandboxHandler);
    if (oldHandler != SIG_DFL) {
      // See the comment on FindFreeSignalNumber about race conditions.
      SANDBOX_LOG_ERROR("signal %d in use by handler %p!\n",
        gSeccompTsyncBroadcastSignum, oldHandler);
      MOZ_CRASH();
    }
  }

  // If there's nothing to do, then we're done.
  if (!canChroot && !canUnshareNet && !canUnshareIPC) {
    return;
  }

  {
    LinuxCapabilities existingCaps;
    if (existingCaps.GetCurrent() && existingCaps.AnyEffective()) {
      SANDBOX_LOG_ERROR("PLEASE DO NOT RUN THIS AS ROOT.  Strange things may"
                        " happen when capabilities are dropped.");
    }
  }

  // If capabilities can't be gained, then nothing can be done.
  if (!info.Test(SandboxInfo::kHasUserNamespaces)) {
    // Drop any existing capabilities; unsharing the user namespace
    // would implicitly drop them, so if we're running in a broken
    // configuration where that would matter (e.g., running as root
    // from a non-root-owned mode-0700 directory) this means it will
    // break the same way on all kernels and be easier to troubleshoot.
    LinuxCapabilities().SetCurrent();
    return;
  }

  // The failure cases for the various unshares, and setting up the
  // chroot helper, don't strictly need to be fatal -- but they also
  // shouldn't fail on any reasonable system, so let's take the small
  // risk of breakage over the small risk of quietly providing less
  // security than we expect.  (Unlike in SandboxInfo, this is in the
  // child process, so crashing here isn't as severe a response to the
  // unexpected.)
  if (!UnshareUserNamespace()) {
    SANDBOX_LOG_ERROR("unshare(CLONE_NEWUSER): %s", strerror(errno));
    // If CanCreateUserNamespace (SandboxInfo.cpp) returns true, then
    // the unshare shouldn't have failed.
    MOZ_CRASH("unshare(CLONE_NEWUSER)");
  }
  // No early returns after this point!  We need to drop the
  // capabilities that were gained by unsharing the user namesapce.

  if (canUnshareIPC && syscall(__NR_unshare, CLONE_NEWIPC) != 0) {
    SANDBOX_LOG_ERROR("unshare(CLONE_NEWIPC): %s", strerror(errno));
    MOZ_CRASH("unshare(CLONE_NEWIPC)");
  }

  if (canUnshareNet && syscall(__NR_unshare, CLONE_NEWNET) != 0) {
    SANDBOX_LOG_ERROR("unshare(CLONE_NEWNET): %s", strerror(errno));
    MOZ_CRASH("unshare(CLONE_NEWNET)");
  }

  if (canChroot) {
    gChrootHelper = MakeUnique<SandboxChroot>();
    if (!gChrootHelper->Prepare()) {
      SANDBOX_LOG_ERROR("failed to set up chroot helper");
      MOZ_CRASH("SandboxChroot::Prepare");
    }
  }

  if (!LinuxCapabilities().SetCurrent()) {
    SANDBOX_LOG_ERROR("dropping capabilities: %s", strerror(errno));
    MOZ_CRASH("can't drop capabilities");
  }
}
Exemple #27
0
AbstractThread*
DocGroup::AbstractMainThreadFor(TaskCategory aCategory)
{
  MOZ_RELEASE_ASSERT(NS_IsMainThread());
  return mTabGroup->AbstractMainThreadFor(aCategory);
}
Exemple #28
0
bool
GLLibraryEGL::EnsureInitialized()
{
    if (mInitialized) {
        return true;
    }

    mozilla::ScopedGfxFeatureReporter reporter("EGL");

#ifdef MOZ_B2G
    if (!sCurrentContext.init())
	    MOZ_CRASH("Tls init failed");
#endif

#ifdef XP_WIN
#ifdef MOZ_WEBGL
    if (!mEGLLibrary) {
        // On Windows, the GLESv2, EGL and DXSDK libraries are shipped with libxul and
        // we should look for them there. We have to load the libs in this
        // order, because libEGL.dll depends on libGLESv2.dll which depends on the DXSDK
        // libraries. This matters especially for WebRT apps which are in a different directory.
        // See bug 760323 and bug 749459

        // Also note that we intentionally leak the libs we load.

        do {
            // Windows 8.1 has d3dcompiler_47.dll in the system directory.
            // Try it first. Note that _46 will never be in the system
            // directory and we ship with at least _43. So there is no point
            // trying _46 and _43 in the system directory.

            if (LoadLibrarySystem32(L"d3dcompiler_47.dll"))
                break;

#ifdef MOZ_D3DCOMPILER_VISTA_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_VISTA_DLL))))
                break;
#endif

#ifdef MOZ_D3DCOMPILER_XP_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_XP_DLL))))
                break;
#endif

            MOZ_ASSERT(false, "d3dcompiler DLL loading failed.");
        } while (false);

        LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libGLESv2.dll"));

        mEGLLibrary = LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libEGL.dll"));

        if (!mEGLLibrary)
            return false;
    }
#endif // MOZ_WEBGL
#else // !Windows

    // On non-Windows (Android) we use system copies of libEGL. We look for
    // the APITrace lib, libEGL.so, and libEGL.so.1 in that order.

#if defined(ANDROID)
    if (!mEGLLibrary)
        mEGLLibrary = LoadApitraceLibrary();
#endif

    if (!mEGLLibrary) {
        printf_stderr("Attempting load of libEGL.so\n");
        mEGLLibrary = PR_LoadLibrary("libEGL.so");
    }
#if defined(XP_UNIX)
    if (!mEGLLibrary) {
        mEGLLibrary = PR_LoadLibrary("libEGL.so.1");
    }
#endif

    if (!mEGLLibrary) {
        NS_WARNING("Couldn't load EGL LIB.");
        return false;
    }

#endif // !Windows

#define SYMBOL(name) \
{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, nullptr } }

    GLLibraryLoader::SymLoadStruct earlySymbols[] = {
        SYMBOL(GetDisplay),
        SYMBOL(GetCurrentSurface),
        SYMBOL(GetCurrentContext),
        SYMBOL(MakeCurrent),
        SYMBOL(DestroyContext),
        SYMBOL(CreateContext),
        SYMBOL(DestroySurface),
        SYMBOL(CreateWindowSurface),
        SYMBOL(CreatePbufferSurface),
        SYMBOL(CreatePixmapSurface),
        SYMBOL(BindAPI),
        SYMBOL(Initialize),
        SYMBOL(ChooseConfig),
        SYMBOL(GetError),
        SYMBOL(GetConfigs),
        SYMBOL(GetConfigAttrib),
        SYMBOL(WaitNative),
        SYMBOL(GetProcAddress),
        SYMBOL(SwapBuffers),
        SYMBOL(CopyBuffers),
        SYMBOL(QueryString),
        SYMBOL(QueryContext),
        SYMBOL(BindTexImage),
        SYMBOL(ReleaseTexImage),
        SYMBOL(QuerySurface),
        { nullptr, { nullptr } }
    };

    if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
        NS_WARNING("Couldn't find required entry points in EGL library (early init)");
        return false;
    }

    GLLibraryLoader::SymLoadStruct optionalSymbols[] = {
        // On Android 4.3 and up, certain features like ANDROID_native_fence_sync
        // can only be queried by using a special eglQueryString.
        { (PRFuncPtr*) &mSymbols.fQueryStringImplementationANDROID,
          { "_Z35eglQueryStringImplementationANDROIDPvi", nullptr } },
        { nullptr, { nullptr } }
    };

    GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0]);

#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
    MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID,
                       "Couldn't find eglQueryStringImplementationANDROID");
#endif

    mEGLDisplay = fGetDisplay(EGL_DEFAULT_DISPLAY);
    if (!fInitialize(mEGLDisplay, nullptr, nullptr))
        return false;

    const char *vendor = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
    if (vendor && (strstr(vendor, "TransGaming") != 0 || strstr(vendor, "Google Inc.") != 0)) {
        mIsANGLE = true;
    }

    InitExtensions();

    GLLibraryLoader::PlatformLookupFunction lookupFunction =
            (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;

    if (IsExtensionSupported(KHR_lock_surface)) {
        GLLibraryLoader::SymLoadStruct lockSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fLockSurface,   { "eglLockSurfaceKHR",   nullptr } },
            { (PRFuncPtr*) &mSymbols.fUnlockSurface, { "eglUnlockSurfaceKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &lockSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_lock_surface without exposing its functions!");

            MarkExtensionUnsupported(KHR_lock_surface);

            mSymbols.fLockSurface = nullptr;
            mSymbols.fUnlockSurface = nullptr;
        }
    }

    if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle);

            mSymbols.fQuerySurfacePointerANGLE = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_fence_sync)) {
        GLLibraryLoader::SymLoadStruct syncSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateSync,     { "eglCreateSyncKHR",     nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroySync,    { "eglDestroySyncKHR",    nullptr } },
            { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "eglClientWaitSyncKHR", nullptr } },
            { (PRFuncPtr*) &mSymbols.fGetSyncAttrib,  { "eglGetSyncAttribKHR",  nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &syncSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(KHR_fence_sync);

            mSymbols.fCreateSync = nullptr;
            mSymbols.fDestroySync = nullptr;
            mSymbols.fClientWaitSync = nullptr;
            mSymbols.fGetSyncAttrib = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base)) {
        GLLibraryLoader::SymLoadStruct imageSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateImage,  { "eglCreateImageKHR",  nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroyImage, { "eglDestroyImageKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &imageSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_image(_base) without exposing its functions!");

            MarkExtensionUnsupported(KHR_image);
            MarkExtensionUnsupported(KHR_image_base);
            MarkExtensionUnsupported(KHR_image_pixmap);

            mSymbols.fCreateImage = nullptr;
            mSymbols.fDestroyImage = nullptr;
        }
    } else {
        MarkExtensionUnsupported(KHR_image_pixmap);
    }

    mInitialized = true;
    reporter.SetSuccessful();
    return true;
}
Exemple #29
0
void
SandboxEarlyInit(GeckoProcessType aType, bool aIsNuwa)
{
    // Bug 1168555: Nuwa isn't reliably single-threaded at this point;
    // it starts an IPC I/O thread and then shuts it down before calling
    // the plugin-container entry point, but that thread may not have
    // finished exiting.  If/when any type of sandboxing is used for the
    // Nuwa process (e.g., unsharing the network namespace there instead
    // of for each content process, to save memory), this will need to be
    // changed by moving the SandboxEarlyInit call to an earlier point.
    if (aIsNuwa) {
        return;
    }

    MOZ_RELEASE_ASSERT(IsSingleThreaded());
    const SandboxInfo info = SandboxInfo::Get();

    // Which kinds of resource isolation (of those that need to be set
    // up at this point) can be used by this process?
    bool canChroot = false;
    bool canUnshareNet = false;
    bool canUnshareIPC = false;

    switch (aType) {
    case GeckoProcessType_Default:
        MOZ_ASSERT(false, "SandboxEarlyInit in parent process");
        return;
#ifdef MOZ_GMP_SANDBOX
    case GeckoProcessType_GMPlugin:
        if (!info.Test(SandboxInfo::kEnabledForMedia)) {
            break;
        }
        canUnshareNet = true;
        canUnshareIPC = true;
        // Need seccomp-bpf to intercept open().
        canChroot = info.Test(SandboxInfo::kHasSeccompBPF);
        break;
#endif
    // In the future, content processes will be able to use some of
    // these.
    default:
        // Other cases intentionally left blank.
        break;
    }

    // If there's nothing to do, then we're done.
    if (!canChroot && !canUnshareNet && !canUnshareIPC) {
        return;
    }

    {
        LinuxCapabilities existingCaps;
        if (existingCaps.GetCurrent() && existingCaps.AnyEffective()) {
            SANDBOX_LOG_ERROR("PLEASE DO NOT RUN THIS AS ROOT.  Strange things may"
                              " happen when capabilities are dropped.");
        }
    }

    // If capabilities can't be gained, then nothing can be done.
    if (!info.Test(SandboxInfo::kHasUserNamespaces)) {
        // Drop any existing capabilities; unsharing the user namespace
        // would implicitly drop them, so if we're running in a broken
        // configuration where that would matter (e.g., running as root
        // from a non-root-owned mode-0700 directory) this means it will
        // break the same way on all kernels and be easier to troubleshoot.
        LinuxCapabilities().SetCurrent();
        return;
    }

    // The failure cases for the various unshares, and setting up the
    // chroot helper, don't strictly need to be fatal -- but they also
    // shouldn't fail on any reasonable system, so let's take the small
    // risk of breakage over the small risk of quietly providing less
    // security than we expect.  (Unlike in SandboxInfo, this is in the
    // child process, so crashing here isn't as severe a response to the
    // unexpected.)
    if (!UnshareUserNamespace()) {
        SANDBOX_LOG_ERROR("unshare(CLONE_NEWUSER): %s", strerror(errno));
        // If CanCreateUserNamespace (SandboxInfo.cpp) returns true, then
        // the unshare shouldn't have failed.
        MOZ_CRASH("unshare(CLONE_NEWUSER)");
    }
    // No early returns after this point!  We need to drop the
    // capabilities that were gained by unsharing the user namesapce.

    if (canUnshareIPC && syscall(__NR_unshare, CLONE_NEWIPC) != 0) {
        SANDBOX_LOG_ERROR("unshare(CLONE_NEWIPC): %s", strerror(errno));
        MOZ_CRASH("unshare(CLONE_NEWIPC)");
    }

    if (canUnshareNet && syscall(__NR_unshare, CLONE_NEWNET) != 0) {
        SANDBOX_LOG_ERROR("unshare(CLONE_NEWNET): %s", strerror(errno));
        MOZ_CRASH("unshare(CLONE_NEWNET)");
    }

    if (canChroot) {
        gChrootHelper = MakeUnique<SandboxChroot>();
        if (!gChrootHelper->Prepare()) {
            SANDBOX_LOG_ERROR("failed to set up chroot helper");
            MOZ_CRASH("SandboxChroot::Prepare");
        }
    }

    if (!LinuxCapabilities().SetCurrent()) {
        SANDBOX_LOG_ERROR("dropping capabilities: %s", strerror(errno));
        MOZ_CRASH("can't drop capabilities");
    }
}
/* static */
already_AddRefed<CanonicalBrowsingContext> CanonicalBrowsingContext::Get(
    uint64_t aId) {
  MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
  return BrowsingContext::Get(aId).downcast<CanonicalBrowsingContext>();
}