Bug 1049272 - Expose sandbox vouchers to GMPs. r=jesup

This commit is contained in:
Chris Pearce 2014-12-05 00:43:41 -08:00
parent 66efa6e637
commit a904300204
6 changed files with 66 additions and 11 deletions

View File

@ -25,7 +25,7 @@
using mozilla::dom::CrashReporterChild;
static const int MAX_PLUGIN_VOUCHER_LENGTH = 500000;
static const int MAX_VOUCHER_LENGTH = 500000;
#ifdef XP_WIN
#include <stdlib.h> // for _exit()
@ -255,6 +255,7 @@ GMPChild::CheckThread()
bool
GMPChild::Init(const std::string& aPluginPath,
const std::string& aVoucherPath,
base::ProcessHandle aParentProcessHandle,
MessageLoop* aIOLoop,
IPC::Channel* aChannel)
@ -268,6 +269,7 @@ GMPChild::Init(const std::string& aPluginPath,
#endif
mPluginPath = aPluginPath;
mVoucherPath = aVoucherPath;
return true;
}
@ -398,6 +400,7 @@ GMPChild::RecvStartPlugin()
PreLoadLibraries(mPluginPath);
#endif
PreLoadPluginVoucher(mPluginPath);
PreLoadSandboxVoucher();
nsCString libPath;
if (!GetLibPath(libPath)) {
@ -523,7 +526,7 @@ GMPChild::DeallocPGMPVideoDecoderChild(PGMPVideoDecoderChild* aActor)
PGMPDecryptorChild*
GMPChild::AllocPGMPDecryptorChild()
{
GMPDecryptorChild* actor = new GMPDecryptorChild(this, mPluginVoucher);
GMPDecryptorChild* actor = new GMPDecryptorChild(this, mPluginVoucher, mSandboxVoucher);
actor->AddRef();
return actor;
}
@ -730,7 +733,7 @@ GMPChild::PreLoadPluginVoucher(const std::string& aPluginPath)
std::streampos end = stream.tellg();
stream.seekg (0, std::ios::beg);
auto length = end - start;
if (length > MAX_PLUGIN_VOUCHER_LENGTH) {
if (length > MAX_VOUCHER_LENGTH) {
NS_WARNING("Plugin voucher file too big!");
return false;
}
@ -745,5 +748,33 @@ GMPChild::PreLoadPluginVoucher(const std::string& aPluginPath)
return true;
}
void
GMPChild::PreLoadSandboxVoucher()
{
std::ifstream stream;
stream.open(mVoucherPath.c_str(), std::ios::binary);
if (!stream.good()) {
NS_WARNING("PreLoadSandboxVoucher can't find sandbox voucher file!");
return;
}
std::streampos start = stream.tellg();
stream.seekg (0, std::ios::end);
std::streampos end = stream.tellg();
stream.seekg (0, std::ios::beg);
auto length = end - start;
if (length > MAX_VOUCHER_LENGTH) {
NS_WARNING("PreLoadSandboxVoucher sandbox voucher file too big!");
return;
}
mSandboxVoucher.SetLength(length);
stream.read((char*)mSandboxVoucher.Elements(), length);
if (!stream) {
NS_WARNING("PreLoadSandboxVoucher failed to read plugin voucher file!");
return;
}
}
} // namespace gmp
} // namespace mozilla

View File

@ -27,6 +27,7 @@ public:
virtual ~GMPChild();
bool Init(const std::string& aPluginPath,
const std::string& aVoucherPath,
base::ProcessHandle aParentProcessHandle,
MessageLoop* aIOLoop,
IPC::Channel* aChannel);
@ -52,6 +53,7 @@ public:
private:
bool PreLoadPluginVoucher(const std::string& aPluginPath);
void PreLoadSandboxVoucher();
bool GetLibPath(nsACString& aOutLibPath);
@ -97,12 +99,14 @@ private:
MessageLoop* mGMPMessageLoop;
std::string mPluginPath;
std::string mVoucherPath;
#if defined(XP_MACOSX) && defined(MOZ_GMP_SANDBOX)
nsCString mPluginBinaryPath;
#endif
std::string mNodeId;
GMPLoader* mGMPLoader;
nsTArray<uint8_t> mPluginVoucher;
nsTArray<uint8_t> mSandboxVoucher;
};
} // namespace gmp

View File

@ -27,10 +27,12 @@ namespace mozilla {
namespace gmp {
GMPDecryptorChild::GMPDecryptorChild(GMPChild* aPlugin,
const nsTArray<uint8_t>& aPluginVoucher)
const nsTArray<uint8_t>& aPluginVoucher,
const nsTArray<uint8_t>& aSandboxVoucher)
: mSession(nullptr)
, mPlugin(aPlugin)
, mPluginVoucher(aPluginVoucher)
, mSandboxVoucher(aSandboxVoucher)
{
MOZ_ASSERT(mPlugin);
}
@ -181,9 +183,8 @@ GMPDecryptorChild::GetSandboxVoucher(const uint8_t** aVoucher,
if (!aVoucher || !aVoucherLength) {
return;
}
const char* voucher = "placeholder_sandbox_voucher.";
*aVoucher = (uint8_t*)voucher;
*aVoucherLength = strlen(voucher);
*aVoucher = mSandboxVoucher.Elements();
*aVoucherLength = mSandboxVoucher.Length();
}
void

View File

@ -25,7 +25,8 @@ public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(GMPDecryptorChild);
explicit GMPDecryptorChild(GMPChild* aPlugin,
const nsTArray<uint8_t>& aPluginVoucher);
const nsTArray<uint8_t>& aPluginVoucher,
const nsTArray<uint8_t>& aSandboxVoucher);
void Init(GMPDecryptor* aSession);
@ -122,8 +123,9 @@ private:
GMPDecryptor* mSession;
GMPChild* mPlugin;
// Reference to the voucher owned by the GMPChild.
// Reference to the vouchers owned by the GMPChild.
const nsTArray<uint8_t>& mPluginVoucher;
const nsTArray<uint8_t>& mSandboxVoucher;
};
} // namespace gmp

View File

@ -29,18 +29,21 @@ bool
GMPProcessChild::Init()
{
std::string pluginFilename;
std::string voucherFilename;
#if defined(OS_POSIX)
// NB: need to be very careful in ensuring that the first arg
// (after the binary name) here is indeed the plugin module path.
// Keep in sync with dom/plugins/PluginModuleParent.
std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
NS_ABORT_IF_FALSE(values.size() >= 2, "not enough args");
NS_ABORT_IF_FALSE(values.size() >= 3, "not enough args");
pluginFilename = values[1];
voucherFilename = values[2];
#elif defined(OS_WIN)
std::vector<std::wstring> values = CommandLine::ForCurrentProcess()->GetLooseValues();
NS_ABORT_IF_FALSE(values.size() >= 1, "not enough loose args");
NS_ABORT_IF_FALSE(values.size() >= 2, "not enough loose args");
pluginFilename = WideToUTF8(values[0]);
voucherFilename = WideToUTF8(values[1]);
#else
#error Not implemented
#endif
@ -48,6 +51,7 @@ GMPProcessChild::Init()
BackgroundHangMonitor::Startup();
return mPlugin.Init(pluginFilename,
voucherFilename,
ParentHandle(),
IOThreadChild::message_loop(),
IOThreadChild::channel());

View File

@ -5,6 +5,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GMPProcessParent.h"
#include "nsDirectoryServiceDefs.h"
#include "nsIFile.h"
#include "base/string_util.h"
#include "base/process_util.h"
@ -43,8 +45,19 @@ GMPProcessParent::~GMPProcessParent()
bool
GMPProcessParent::Launch(int32_t aTimeoutMs)
{
nsCOMPtr<nsIFile> greDir;
NS_GetSpecialDirectory(NS_GRE_DIR, getter_AddRefs(greDir));
if (!greDir) {
NS_WARNING("GMPProcessParent can't get NS_GRE_DIR");
return false;
}
greDir->AppendNative(NS_LITERAL_CSTRING("voucher.bin"));
nsAutoCString voucherPath;
greDir->GetNativePath(voucherPath);
vector<string> args;
args.push_back(mGMPPath);
args.push_back(string(voucherPath.BeginReading(), voucherPath.EndReading()));
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
std::wstring wGMPPath = UTF8ToWide(mGMPPath.c_str());