LCOV - code coverage report
Current view: top level - dom/media/gmp - GMPLoader.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 55 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: sw=4 ts=4 et :
       3             :  * This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "GMPLoader.h"
       8             : #include <stdio.h>
       9             : #include "mozilla/Attributes.h"
      10             : #include "gmp-entrypoints.h"
      11             : #include "prlink.h"
      12             : #include "prenv.h"
      13             : #if defined(XP_WIN) && defined(MOZ_SANDBOX)
      14             : #include "mozilla/sandboxTarget.h"
      15             : #include "mozilla/sandboxing/SandboxInitialization.h"
      16             : #include "mozilla/sandboxing/sandboxLogging.h"
      17             : #endif
      18             : #if defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
      19             : #include "mozilla/Sandbox.h"
      20             : #include "mozilla/SandboxInfo.h"
      21             : #endif
      22             : 
      23             : #include <string>
      24             : 
      25             : #ifdef XP_WIN
      26             : #include "windows.h"
      27             : #endif
      28             : 
      29             : namespace mozilla {
      30             : namespace gmp {
      31           0 : class PassThroughGMPAdapter : public GMPAdapter {
      32             : public:
      33           0 :   ~PassThroughGMPAdapter() override {
      34             :     // Ensure we're always shutdown, even if caller forgets to call GMPShutdown().
      35           0 :     GMPShutdown();
      36           0 :   }
      37             : 
      38           0 :   void SetAdaptee(PRLibrary* aLib) override
      39             :   {
      40           0 :     mLib = aLib;
      41           0 :   }
      42             : 
      43           0 :   GMPErr GMPInit(const GMPPlatformAPI* aPlatformAPI) override
      44             :   {
      45           0 :     if (!mLib) {
      46           0 :       return GMPGenericErr;
      47             :     }
      48           0 :     GMPInitFunc initFunc = reinterpret_cast<GMPInitFunc>(PR_FindFunctionSymbol(mLib, "GMPInit"));
      49           0 :     if (!initFunc) {
      50           0 :       return GMPNotImplementedErr;
      51             :     }
      52           0 :     return initFunc(aPlatformAPI);
      53             :   }
      54             : 
      55           0 :   GMPErr GMPGetAPI(const char* aAPIName,
      56             :                    void* aHostAPI,
      57             :                    void** aPluginAPI,
      58             :                    uint32_t aDecryptorId) override
      59             :   {
      60           0 :     if (!mLib) {
      61           0 :       return GMPGenericErr;
      62             :     }
      63           0 :     GMPGetAPIFunc getapiFunc = reinterpret_cast<GMPGetAPIFunc>(PR_FindFunctionSymbol(mLib, "GMPGetAPI"));
      64           0 :     if (!getapiFunc) {
      65           0 :       return GMPNotImplementedErr;
      66             :     }
      67           0 :     return getapiFunc(aAPIName, aHostAPI, aPluginAPI);
      68             :   }
      69             : 
      70           0 :   void GMPShutdown() override
      71             :   {
      72           0 :     if (mLib) {
      73           0 :       GMPShutdownFunc shutdownFunc = reinterpret_cast<GMPShutdownFunc>(PR_FindFunctionSymbol(mLib, "GMPShutdown"));
      74           0 :       if (shutdownFunc) {
      75           0 :         shutdownFunc();
      76             :       }
      77           0 :       PR_UnloadLibrary(mLib);
      78           0 :       mLib = nullptr;
      79             :     }
      80           0 :   }
      81             : 
      82             : private:
      83             :   PRLibrary* mLib = nullptr;
      84             : };
      85             : 
      86             : bool
      87           0 : GMPLoader::Load(const char* aUTF8LibPath,
      88             :                 uint32_t aUTF8LibPathLen,
      89             :                 const GMPPlatformAPI* aPlatformAPI,
      90             :                 GMPAdapter* aAdapter)
      91             : {
      92           0 :   if (mSandboxStarter && !mSandboxStarter->Start(aUTF8LibPath)) {
      93           0 :     return false;
      94             :   }
      95             : 
      96             :   // Load the GMP.
      97             :   PRLibSpec libSpec;
      98             : #ifdef XP_WIN
      99             :   int pathLen = MultiByteToWideChar(CP_UTF8, 0, aUTF8LibPath, -1, nullptr, 0);
     100             :   if (pathLen == 0) {
     101             :     return false;
     102             :   }
     103             : 
     104             :   auto widePath = MakeUnique<wchar_t[]>(pathLen);
     105             :   if (MultiByteToWideChar(CP_UTF8, 0, aUTF8LibPath, -1, widePath.get(), pathLen) == 0) {
     106             :     return false;
     107             :   }
     108             : 
     109             :   libSpec.value.pathname_u = widePath.get();
     110             :   libSpec.type = PR_LibSpec_PathnameU;
     111             : #else
     112           0 :   libSpec.value.pathname = aUTF8LibPath;
     113           0 :   libSpec.type = PR_LibSpec_Pathname;
     114             : #endif
     115           0 :   PRLibrary* lib = PR_LoadLibraryWithFlags(libSpec, 0);
     116           0 :   if (!lib) {
     117           0 :     return false;
     118             :   }
     119             : 
     120           0 :   mAdapter.reset((!aAdapter) ? new PassThroughGMPAdapter() : aAdapter);
     121           0 :   mAdapter->SetAdaptee(lib);
     122             : 
     123           0 :   if (mAdapter->GMPInit(aPlatformAPI) != GMPNoErr) {
     124           0 :     return false;
     125             :   }
     126             : 
     127           0 :   return true;
     128             : }
     129             : 
     130             : GMPErr
     131           0 : GMPLoader::GetAPI(const char* aAPIName,
     132             :                   void* aHostAPI,
     133             :                   void** aPluginAPI,
     134             :                   uint32_t aDecryptorId)
     135             : {
     136           0 :   return mAdapter->GMPGetAPI(aAPIName, aHostAPI, aPluginAPI, aDecryptorId);
     137             : }
     138             : 
     139             : void
     140           0 : GMPLoader::Shutdown()
     141             : {
     142           0 :   if (mAdapter) {
     143           0 :     mAdapter->GMPShutdown();
     144             :   }
     145           0 : }
     146             : 
     147             : #if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
     148             : void
     149             : GMPLoader::SetSandboxInfo(MacSandboxInfo* aSandboxInfo)
     150             : {
     151             :   if (mSandboxStarter) {
     152             :     mSandboxStarter->SetSandboxInfo(aSandboxInfo);
     153             :   }
     154             : }
     155             : #endif
     156             : 
     157             : #if defined(XP_WIN) && defined(MOZ_SANDBOX)
     158             : class WinSandboxStarter : public mozilla::gmp::SandboxStarter
     159             : {
     160             : public:
     161             :   bool Start(const char *aLibPath) override
     162             :   {
     163             :     // Cause advapi32 to load before the sandbox is turned on, as
     164             :     // Widevine version 970 and later require it and the sandbox
     165             :     // blocks it on Win7.
     166             :     unsigned int dummy_rand;
     167             :     rand_s(&dummy_rand);
     168             : 
     169             :     mozilla::SandboxTarget::Instance()->StartSandbox();
     170             :     return true;
     171             :   }
     172             : };
     173             : #endif
     174             : 
     175             : #if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
     176             : class MacSandboxStarter : public mozilla::gmp::SandboxStarter
     177             : {
     178             : public:
     179             :   bool Start(const char *aLibPath) override
     180             :   {
     181             :     std::string err;
     182             :     bool rv = mozilla::StartMacSandbox(mInfo, err);
     183             :     if (!rv) {
     184             :       fprintf(stderr, "sandbox_init() failed! Error \"%s\"\n", err.c_str());
     185             :     }
     186             :     return rv;
     187             :   }
     188             :   void SetSandboxInfo(MacSandboxInfo* aSandboxInfo) override
     189             :   {
     190             :     mInfo = *aSandboxInfo;
     191             :   }
     192             : private:
     193             :   MacSandboxInfo mInfo;
     194             : };
     195             : #endif
     196             : 
     197             : #if defined (XP_LINUX) && defined(MOZ_GMP_SANDBOX)
     198             : namespace {
     199             : class LinuxSandboxStarter : public mozilla::gmp::SandboxStarter
     200             : {
     201             : private:
     202             :   LinuxSandboxStarter() { }
     203             :   friend mozilla::detail::UniqueSelector<LinuxSandboxStarter>::SingleObject mozilla::MakeUnique<LinuxSandboxStarter>();
     204             : 
     205             : public:
     206             :   static UniquePtr<SandboxStarter> Make()
     207             :   {
     208             :     if (mozilla::SandboxInfo::Get().CanSandboxMedia()) {
     209             :       return MakeUnique<LinuxSandboxStarter>();
     210             :     }
     211             :     // Sandboxing isn't possible, but the parent has already
     212             :     // checked that this plugin doesn't require it.  (Bug 1074561)
     213             :     return nullptr;
     214             :   }
     215             :   bool Start(const char *aLibPath) override
     216             :   {
     217             :     mozilla::SetMediaPluginSandbox(aLibPath);
     218             :     return true;
     219             :   }
     220             : };
     221             : } // anonymous namespace
     222             : #endif // XP_LINUX && MOZ_GMP_SANDBOX
     223             : 
     224             : static UniquePtr<SandboxStarter>
     225           0 : MakeSandboxStarter()
     226             : {
     227             : #if defined(XP_WIN) && defined(MOZ_SANDBOX)
     228             :   return mozilla::MakeUnique<WinSandboxStarter>();
     229             : #elif defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
     230             :   return mozilla::MakeUnique<MacSandboxStarter>();
     231             : #elif defined(XP_LINUX) && defined(MOZ_GMP_SANDBOX)
     232             :   return LinuxSandboxStarter::Make();
     233             : #else
     234           0 :   return nullptr;
     235             : #endif
     236             : }
     237             : 
     238           0 : GMPLoader::GMPLoader()
     239           0 :   : mSandboxStarter(MakeSandboxStarter())
     240             : {
     241           0 : }
     242             : 
     243             : bool
     244           0 : GMPLoader::CanSandbox() const
     245             : {
     246           0 :   return !!mSandboxStarter;
     247             : }
     248             : 
     249             : } // namespace gmp
     250             : } // namespace mozilla

Generated by: LCOV version 1.13