示例#1
0
void
GMPLoaderImpl::SetSandboxInfo(MacSandboxInfo* aSandboxInfo)
{
  if (mSandboxStarter) {
    mSandboxStarter->SetSandboxInfo(aSandboxInfo);
  }
}
示例#2
0
bool
GMPLoaderImpl::Load(const char* aLibPath,
                    uint32_t aLibPathLen,
                    char* aOriginSalt,
                    uint32_t aOriginSaltLen,
                    const GMPPlatformAPI* aPlatformAPI)
{
    std::string nodeId;
#ifdef HASH_NODE_ID_WITH_DEVICE_ID
    if (aOriginSaltLen > 0) {
        string16 deviceId;
        int volumeId;
        if (!rlz_lib::GetRawMachineId(&deviceId, &volumeId)) {
            return false;
        }

        SHA256Context ctx;
        SHA256_Begin(&ctx);
        SHA256_Update(&ctx, (const uint8_t*)aOriginSalt, aOriginSaltLen);
        SHA256_Update(&ctx, (const uint8_t*)deviceId.c_str(), deviceId.size() * sizeof(string16::value_type));
        SHA256_Update(&ctx, (const uint8_t*)&volumeId, sizeof(int));
        uint8_t digest[SHA256_LENGTH] = {0};
        unsigned int digestLen = 0;
        SHA256_End(&ctx, digest, &digestLen, SHA256_LENGTH);

        // Overwrite all data involved in calculation as it could potentially
        // identify the user, so there's no chance a GMP can read it and use
        // it for identity tracking.
        memset(&ctx, 0, sizeof(ctx));
        memset(aOriginSalt, 0, aOriginSaltLen);
        volumeId = 0;
        memset(&deviceId[0], '*', sizeof(string16::value_type) * deviceId.size());
        deviceId = L"";

        if (!rlz_lib::BytesToString(digest, SHA256_LENGTH, &nodeId)) {
            return false;
        }
        // We've successfully bound the origin salt to node id.
        // rlz_lib::GetRawMachineId and/or the system functions it
        // called could have left user identifiable data on the stack,
        // so carefully zero the stack down to the guard page.
        uint8_t* top;
        uint8_t* bottom;
        if (!GetStackAfterCurrentFrame(&top, &bottom)) {
            return false;
        }
        assert(top >= bottom);
        // Inline instructions equivalent to RtlSecureZeroMemory().
        // We can't just use RtlSecureZeroMemory here directly, as in debug
        // builds, RtlSecureZeroMemory() can't be inlined, and the stack
        // memory it uses would get wiped by itself running, causing crashes.
        for (volatile uint8_t* p = (volatile uint8_t*)bottom; p < top; p++) {
            *p = 0;
        }
    } else
#endif
    {
        nodeId = std::string(aOriginSalt, aOriginSalt + aOriginSaltLen);
    }

#if defined(XP_WIN) && defined(MOZ_SANDBOX)
    // If the GMP DLL is a side-by-side assembly with static imports then the DLL
    // loader will attempt to create an activation context which will fail because
    // of the sandbox. If we create an activation context before we start the
    // sandbox then this one will get picked up by the DLL loader.
    int pathLen = MultiByteToWideChar(CP_ACP, 0, aLibPath, -1, nullptr, 0);
    if (pathLen == 0) {
        return false;
    }

    wchar_t* widePath = new wchar_t[pathLen];
    if (MultiByteToWideChar(CP_ACP, 0, aLibPath, -1, widePath, pathLen) == 0) {
        delete[] widePath;
        return false;
    }

    ACTCTX actCtx = { sizeof(actCtx) };
    actCtx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
    actCtx.lpSource = widePath;
    actCtx.lpResourceName = ISOLATIONAWARE_MANIFEST_RESOURCE_ID;
    ScopedActCtxHandle actCtxHandle(CreateActCtx(&actCtx));
    delete[] widePath;
#endif

    // Start the sandbox now that we've generated the device bound node id.
    // This must happen after the node id is bound to the device id, as
    // generating the device id requires privileges.
    if (mSandboxStarter) {
        mSandboxStarter->Start(aLibPath);
    }

    // Load the GMP.
    PRLibSpec libSpec;
    libSpec.value.pathname = aLibPath;
    libSpec.type = PR_LibSpec_Pathname;
    mLib = PR_LoadLibraryWithFlags(libSpec, 0);
    if (!mLib) {
        return false;
    }

    GMPInitFunc initFunc = reinterpret_cast<GMPInitFunc>(PR_FindFunctionSymbol(mLib, "GMPInit"));
    if (!initFunc) {
        return false;
    }

    if (initFunc(aPlatformAPI) != GMPNoErr) {
        return false;
    }

    GMPSetNodeIdFunc setNodeIdFunc = reinterpret_cast<GMPSetNodeIdFunc>(PR_FindFunctionSymbol(mLib, "GMPSetNodeId"));
    if (setNodeIdFunc) {
        setNodeIdFunc(nodeId.c_str(), nodeId.size());
    }

    mGetAPIFunc = reinterpret_cast<GMPGetAPIFunc>(PR_FindFunctionSymbol(mLib, "GMPGetAPI"));
    if (!mGetAPIFunc) {
        return false;
    }

    return true;
}
示例#3
0
bool
GMPLoaderImpl::Load(const char* aUTF8LibPath,
                    uint32_t aUTF8LibPathLen,
                    char* aOriginSalt,
                    uint32_t aOriginSaltLen,
                    const GMPPlatformAPI* aPlatformAPI,
                    GMPAdapter* aAdapter)
{
  std::string nodeId;
  if (!CalculateGMPDeviceId(aOriginSalt, aOriginSaltLen, nodeId)) {
    return false;
  }

  // Start the sandbox now that we've generated the device bound node id.
  // This must happen after the node id is bound to the device id, as
  // generating the device id requires privileges.
  if (mSandboxStarter && !mSandboxStarter->Start(aUTF8LibPath)) {
    return false;
  }

  // Load the GMP.
  PRLibSpec libSpec;
#ifdef XP_WIN
  int pathLen = MultiByteToWideChar(CP_UTF8, 0, aUTF8LibPath, -1, nullptr, 0);
  if (pathLen == 0) {
    return false;
  }

  auto widePath = MakeUnique<wchar_t[]>(pathLen);
  if (MultiByteToWideChar(CP_UTF8, 0, aUTF8LibPath, -1, widePath.get(), pathLen) == 0) {
    return false;
  }

  libSpec.value.pathname_u = widePath.get();
  libSpec.type = PR_LibSpec_PathnameU;
#else
  libSpec.value.pathname = aUTF8LibPath;
  libSpec.type = PR_LibSpec_Pathname;
#endif
  PRLibrary* lib = PR_LoadLibraryWithFlags(libSpec, 0);
  if (!lib) {
    return false;
  }

  GMPInitFunc initFunc = reinterpret_cast<GMPInitFunc>(PR_FindFunctionSymbol(lib, "GMPInit"));
  if ((initFunc && aAdapter) ||
      (!initFunc && !aAdapter)) {
    // Ensure that if we're dealing with a GMP we do *not* use an adapter
    // provided from the outside world. This is important as it means we
    // don't call code not covered by Adobe's plugin-container voucher
    // before we pass the node Id to Adobe's GMP.
    return false;
  }

  // Note: PassThroughGMPAdapter's code must remain in this file so that it's
  // covered by Adobe's plugin-container voucher.
  mAdapter.reset((!aAdapter) ? new PassThroughGMPAdapter() : aAdapter);
  mAdapter->SetAdaptee(lib);

  if (mAdapter->GMPInit(aPlatformAPI) != GMPNoErr) {
    return false;
  }

  mAdapter->GMPSetNodeId(nodeId.c_str(), nodeId.size());

  return true;
}
示例#4
0
bool
GMPLoaderImpl::Load(const char* aUTF8LibPath,
                    uint32_t aUTF8LibPathLen,
                    char* aOriginSalt,
                    uint32_t aOriginSaltLen,
                    const GMPPlatformAPI* aPlatformAPI)
{
  std::string nodeId;
#ifdef HASH_NODE_ID_WITH_DEVICE_ID
  if (aOriginSaltLen > 0) {
    std::vector<uint8_t> deviceId;
    int volumeId;
    if (!rlz_lib::GetRawMachineId(&deviceId, &volumeId)) {
      return false;
    }

    SHA256Context ctx;
    SHA256_Begin(&ctx);
    SHA256_Update(&ctx, (const uint8_t*)aOriginSalt, aOriginSaltLen);
    SHA256_Update(&ctx, deviceId.data(), deviceId.size());
    SHA256_Update(&ctx, (const uint8_t*)&volumeId, sizeof(int));
    uint8_t digest[SHA256_LENGTH] = {0};
    unsigned int digestLen = 0;
    SHA256_End(&ctx, digest, &digestLen, SHA256_LENGTH);

    // Overwrite all data involved in calculation as it could potentially
    // identify the user, so there's no chance a GMP can read it and use
    // it for identity tracking.
    SecureMemset(&ctx, 0, sizeof(ctx));
    SecureMemset(aOriginSalt, 0, aOriginSaltLen);
    SecureMemset(&volumeId, 0, sizeof(volumeId));
    SecureMemset(deviceId.data(), '*', deviceId.size());
    deviceId.clear();

    if (!rlz_lib::BytesToString(digest, SHA256_LENGTH, &nodeId)) {
      return false;
    }

    if (!PR_GetEnv("MOZ_GMP_DISABLE_NODE_ID_CLEANUP")) {
      // We've successfully bound the origin salt to node id.
      // rlz_lib::GetRawMachineId and/or the system functions it
      // called could have left user identifiable data on the stack,
      // so carefully zero the stack down to the guard page.
      uint8_t* top;
      uint8_t* bottom;
      if (!GetStackAfterCurrentFrame(&top, &bottom)) {
        return false;
      }
      assert(top >= bottom);
      // Inline instructions equivalent to RtlSecureZeroMemory().
      // We can't just use RtlSecureZeroMemory here directly, as in debug
      // builds, RtlSecureZeroMemory() can't be inlined, and the stack
      // memory it uses would get wiped by itself running, causing crashes.
      for (volatile uint8_t* p = (volatile uint8_t*)bottom; p < top; p++) {
        *p = 0;
      }
    }
  } else
#endif
  {
    nodeId = std::string(aOriginSalt, aOriginSalt + aOriginSaltLen);
  }

  // Start the sandbox now that we've generated the device bound node id.
  // This must happen after the node id is bound to the device id, as
  // generating the device id requires privileges.
  if (mSandboxStarter && !mSandboxStarter->Start(aUTF8LibPath)) {
    return false;
  }

  // Load the GMP.
  PRLibSpec libSpec;
#ifdef XP_WIN
  int pathLen = MultiByteToWideChar(CP_UTF8, 0, aUTF8LibPath, -1, nullptr, 0);
  if (pathLen == 0) {
    return false;
  }

  nsAutoArrayPtr<wchar_t> widePath(new wchar_t[pathLen]);
  if (MultiByteToWideChar(CP_UTF8, 0, aUTF8LibPath, -1, widePath, pathLen) == 0) {
    return false;
  }

  libSpec.value.pathname_u = widePath;
  libSpec.type = PR_LibSpec_PathnameU;
#else
  libSpec.value.pathname = aUTF8LibPath;
  libSpec.type = PR_LibSpec_Pathname;
#endif
  mLib = PR_LoadLibraryWithFlags(libSpec, 0);
  if (!mLib) {
    return false;
  }

  GMPInitFunc initFunc = reinterpret_cast<GMPInitFunc>(PR_FindFunctionSymbol(mLib, "GMPInit"));
  if (!initFunc) {
    return false;
  }

  if (initFunc(aPlatformAPI) != GMPNoErr) {
    return false;
  }

  GMPSetNodeIdFunc setNodeIdFunc = reinterpret_cast<GMPSetNodeIdFunc>(PR_FindFunctionSymbol(mLib, "GMPSetNodeId"));
  if (setNodeIdFunc) {
    setNodeIdFunc(nodeId.c_str(), nodeId.size());
  }

  mGetAPIFunc = reinterpret_cast<GMPGetAPIFunc>(PR_FindFunctionSymbol(mLib, "GMPGetAPI"));
  if (!mGetAPIFunc) {
    return false;
  }

  return true;
}