1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=4 et :
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "FunctionBrokerParent.h"
#include "FunctionBroker.h"
#include "FunctionBrokerThread.h"
#include "mozilla/ipc/Endpoint.h"
namespace mozilla::plugins {
#if defined(XP_WIN)
UlongPairToIdMap sPairToIdMap;
IdToUlongPairMap sIdToPairMap;
PtrToIdMap sPtrToIdMap;
IdToPtrMap sIdToPtrMap;
#endif // defined(XP_WIN)
/* static */
FunctionBrokerParent* FunctionBrokerParent::Create(
Endpoint<PFunctionBrokerParent>&& aParentEnd) {
FunctionBrokerThread* thread = FunctionBrokerThread::Create();
if (!thread) {
return nullptr;
}
// We get the FunctionHooks so that they are created here, not on the
// message thread.
FunctionHook::GetHooks();
return new FunctionBrokerParent(thread, std::move(aParentEnd));
}
FunctionBrokerParent::FunctionBrokerParent(
FunctionBrokerThread* aThread, Endpoint<PFunctionBrokerParent>&& aParentEnd)
: mThread(aThread),
mMonitor("FunctionBrokerParent Lock"),
mShutdownDone(false) {
MOZ_ASSERT(mThread);
mThread->Dispatch(
NewNonOwningRunnableMethod<Endpoint<PFunctionBrokerParent>&&>(
"FunctionBrokerParent::Bind", this, &FunctionBrokerParent::Bind,
std::move(aParentEnd)));
}
FunctionBrokerParent::~FunctionBrokerParent() {
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
// Clean up any file permissions that we granted to the child process.
MOZ_RELEASE_ASSERT(NS_IsMainThread());
RemovePermissionsForProcess(OtherPid());
#endif
}
void FunctionBrokerParent::Bind(Endpoint<PFunctionBrokerParent>&& aEnd) {
MOZ_RELEASE_ASSERT(mThread->IsOnThread());
DebugOnly<bool> ok = aEnd.Bind(this);
MOZ_ASSERT(ok);
}
void FunctionBrokerParent::ShutdownOnBrokerThread() {
MOZ_ASSERT(mThread->IsOnThread());
Close();
// Notify waiting thread that we are done.
MonitorAutoLock lock(mMonitor);
mShutdownDone = true;
mMonitor.Notify();
}
void FunctionBrokerParent::Destroy(FunctionBrokerParent* aInst) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aInst);
{
// Hold the lock while we destroy the actor on the broker thread.
MonitorAutoLock lock(aInst->mMonitor);
aInst->mThread->Dispatch(NewNonOwningRunnableMethod(
"FunctionBrokerParent::ShutdownOnBrokerThread", aInst,
&FunctionBrokerParent::ShutdownOnBrokerThread));
// Wait for broker thread to complete destruction.
while (!aInst->mShutdownDone) {
aInst->mMonitor.Wait();
}
}
delete aInst;
}
void FunctionBrokerParent::ActorDestroy(ActorDestroyReason aWhy) {
MOZ_RELEASE_ASSERT(mThread->IsOnThread());
}
mozilla::ipc::IPCResult FunctionBrokerParent::RecvBrokerFunction(
const FunctionHookId& aFunctionId, const IpdlTuple& aInTuple,
IpdlTuple* aOutTuple) {
#if defined(XP_WIN)
MOZ_ASSERT(mThread->IsOnThread());
if (RunBrokeredFunction(OtherPid(), aFunctionId, aInTuple, aOutTuple)) {
return IPC_OK();
}
return IPC_FAIL_NO_REASON(this);
#else
MOZ_ASSERT_UNREACHABLE(
"BrokerFunction is currently only implemented on Windows.");
return IPC_FAIL_NO_REASON(this);
#endif
}
// static
bool FunctionBrokerParent::RunBrokeredFunction(
base::ProcessId aClientId, const FunctionHookId& aFunctionId,
const IPC::IpdlTuple& aInTuple, IPC::IpdlTuple* aOutTuple) {
if ((size_t)aFunctionId >= FunctionHook::GetHooks()->Length()) {
MOZ_ASSERT_UNREACHABLE("Invalid function ID");
return false;
}
FunctionHook* hook = FunctionHook::GetHooks()->ElementAt(aFunctionId);
MOZ_ASSERT(hook->FunctionId() == aFunctionId);
return hook->RunOriginalFunction(aClientId, aInTuple, aOutTuple);
}
#if defined(XP_WIN) && defined(MOZ_SANDBOX)
mozilla::SandboxPermissions FunctionBrokerParent::sSandboxPermissions;
// static
void FunctionBrokerParent::RemovePermissionsForProcess(
base::ProcessId aClientId) {
sSandboxPermissions.RemovePermissionsForProcess(aClientId);
}
#endif // defined(XP_WIN) && defined(MOZ_SANDBOX)
} // namespace mozilla::plugins
|