Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/plugins/ipc/FunctionBrokerParent.cpp
Line
Count
Source (jump to first uncovered line)
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 "FunctionBrokerParent.h"
8
#include "FunctionBroker.h"
9
#include "FunctionBrokerThread.h"
10
11
namespace mozilla {
12
namespace plugins {
13
14
#if defined(XP_WIN)
15
UlongPairToIdMap sPairToIdMap;
16
IdToUlongPairMap sIdToPairMap;
17
PtrToIdMap sPtrToIdMap;
18
IdToPtrMap sIdToPtrMap;
19
#endif // defined(XP_WIN)
20
21
/* static */ FunctionBrokerParent*
22
FunctionBrokerParent::Create(Endpoint<PFunctionBrokerParent>&& aParentEnd)
23
0
{
24
0
  FunctionBrokerThread* thread = FunctionBrokerThread::Create();
25
0
  if (!thread) {
26
0
    return nullptr;
27
0
  }
28
0
29
0
  // We get the FunctionHooks so that they are created here, not on the
30
0
  // message thread.
31
0
  FunctionHook::GetHooks();
32
0
33
0
  return new FunctionBrokerParent(thread, std::move(aParentEnd));
34
0
}
35
36
FunctionBrokerParent::FunctionBrokerParent(FunctionBrokerThread* aThread,
37
                                           Endpoint<PFunctionBrokerParent>&& aParentEnd) :
38
    mThread(aThread)
39
  , mMonitor("FunctionBrokerParent Lock")
40
  , mShutdownDone(false)
41
0
{
42
0
  MOZ_ASSERT(mThread);
43
0
  mThread->Dispatch(NewNonOwningRunnableMethod<Endpoint<PFunctionBrokerParent>&&>(
44
0
          "FunctionBrokerParent::Bind", this, &FunctionBrokerParent::Bind, std::move(aParentEnd)));
45
0
}
46
47
FunctionBrokerParent::~FunctionBrokerParent()
48
0
{
49
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
50
  // Clean up any file permissions that we granted to the child process.
51
  MOZ_RELEASE_ASSERT(NS_IsMainThread());
52
  RemovePermissionsForProcess(OtherPid());
53
#endif
54
}
55
56
void
57
FunctionBrokerParent::Bind(Endpoint<PFunctionBrokerParent>&& aEnd)
58
0
{
59
0
  MOZ_RELEASE_ASSERT(mThread->IsOnThread());
60
0
  DebugOnly<bool> ok = aEnd.Bind(this);
61
0
  MOZ_ASSERT(ok);
62
0
}
63
64
void
65
FunctionBrokerParent::ShutdownOnBrokerThread()
66
0
{
67
0
  MOZ_ASSERT(mThread->IsOnThread());
68
0
  Close();
69
0
70
0
  // Notify waiting thread that we are done.
71
0
  MonitorAutoLock lock(mMonitor);
72
0
  mShutdownDone = true;
73
0
  mMonitor.Notify();
74
0
}
75
76
void
77
FunctionBrokerParent::Destroy(FunctionBrokerParent* aInst)
78
0
{
79
0
  MOZ_ASSERT(NS_IsMainThread());
80
0
  MOZ_ASSERT(aInst);
81
0
82
0
  {
83
0
    // Hold the lock while we destroy the actor on the broker thread.
84
0
    MonitorAutoLock lock(aInst->mMonitor);
85
0
    aInst->mThread->Dispatch(NewNonOwningRunnableMethod(
86
0
      "FunctionBrokerParent::ShutdownOnBrokerThread", aInst,
87
0
      &FunctionBrokerParent::ShutdownOnBrokerThread));
88
0
89
0
    // Wait for broker thread to complete destruction.
90
0
    while (!aInst->mShutdownDone) {
91
0
      aInst->mMonitor.Wait();
92
0
    }
93
0
  }
94
0
95
0
  delete aInst;
96
0
}
97
98
void
99
FunctionBrokerParent::ActorDestroy(ActorDestroyReason aWhy)
100
0
{
101
0
  MOZ_RELEASE_ASSERT(mThread->IsOnThread());
102
0
}
103
104
mozilla::ipc::IPCResult
105
FunctionBrokerParent::RecvBrokerFunction(const FunctionHookId &aFunctionId,
106
                                         const IpdlTuple &aInTuple,
107
                                         IpdlTuple *aOutTuple)
108
0
{
109
#if defined(XP_WIN)
110
  MOZ_ASSERT(mThread->IsOnThread());
111
  if (RunBrokeredFunction(OtherPid(), aFunctionId, aInTuple, aOutTuple)) {
112
    return IPC_OK();
113
  }
114
  return IPC_FAIL_NO_REASON(this);
115
#else
116
0
  MOZ_ASSERT_UNREACHABLE("BrokerFunction is currently only implemented on Windows.");
117
0
  return IPC_FAIL_NO_REASON(this);
118
0
#endif
119
0
}
120
121
// static
122
bool
123
FunctionBrokerParent::RunBrokeredFunction(base::ProcessId aClientId,
124
                                        const FunctionHookId &aFunctionId,
125
                                        const IPC::IpdlTuple &aInTuple,
126
                                        IPC::IpdlTuple *aOutTuple)
127
0
{
128
0
  if ((size_t)aFunctionId >= FunctionHook::GetHooks()->Length()) {
129
0
    MOZ_ASSERT_UNREACHABLE("Invalid function ID");
130
0
    return false;
131
0
  }
132
0
133
0
  FunctionHook* hook = FunctionHook::GetHooks()->ElementAt(aFunctionId);
134
0
  MOZ_ASSERT(hook->FunctionId() == aFunctionId);
135
0
  return hook->RunOriginalFunction(aClientId, aInTuple, aOutTuple);
136
0
}
137
138
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
139
140
mozilla::SandboxPermissions FunctionBrokerParent::sSandboxPermissions;
141
142
// static
143
void
144
FunctionBrokerParent::RemovePermissionsForProcess(base::ProcessId aClientId)
145
{
146
  sSandboxPermissions.RemovePermissionsForProcess(aClientId);
147
}
148
149
#endif // defined(XP_WIN) && defined(MOZ_SANDBOX)
150
151
} // namespace plugins
152
} // namespace mozilla