summaryrefslogtreecommitdiffstats
path: root/dom/plugins/ipc/PluginProcessParent.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /dom/plugins/ipc/PluginProcessParent.cpp
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/plugins/ipc/PluginProcessParent.cpp')
-rw-r--r--dom/plugins/ipc/PluginProcessParent.cpp191
1 files changed, 191 insertions, 0 deletions
diff --git a/dom/plugins/ipc/PluginProcessParent.cpp b/dom/plugins/ipc/PluginProcessParent.cpp
new file mode 100644
index 0000000000..2f65311263
--- /dev/null
+++ b/dom/plugins/ipc/PluginProcessParent.cpp
@@ -0,0 +1,191 @@
+/* -*- 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 "mozilla/plugins/PluginProcessParent.h"
+
+#include "base/string_util.h"
+#include "base/process_util.h"
+
+#include "nsAppDirectoryServiceDefs.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsIFile.h"
+#include "nsIProperties.h"
+#include "nsServiceManagerUtils.h"
+
+#include "mozilla/ipc/BrowserProcessSubThread.h"
+#include "mozilla/plugins/PluginMessageUtils.h"
+#include "mozilla/Telemetry.h"
+#include "nsThreadUtils.h"
+
+using std::string;
+using std::vector;
+
+using mozilla::ipc::BrowserProcessSubThread;
+using mozilla::ipc::GeckoChildProcessHost;
+using mozilla::plugins::LaunchCompleteTask;
+using mozilla::plugins::PluginProcessParent;
+
+#ifdef XP_WIN
+PluginProcessParent::PidSet* PluginProcessParent::sPidSet = nullptr;
+#endif
+
+PluginProcessParent::PluginProcessParent(const std::string& aPluginFilePath)
+ : GeckoChildProcessHost(GeckoProcessType_Plugin),
+ mPluginFilePath(aPluginFilePath),
+ mTaskFactory(this),
+ mMainMsgLoop(MessageLoop::current())
+#ifdef XP_WIN
+ ,
+ mChildPid(0)
+#endif
+{
+}
+
+PluginProcessParent::~PluginProcessParent() {
+#ifdef XP_WIN
+ if (sPidSet && mChildPid) {
+ sPidSet->RemoveEntry(mChildPid);
+ if (sPidSet->IsEmpty()) {
+ delete sPidSet;
+ sPidSet = nullptr;
+ }
+ }
+#endif
+}
+
+bool PluginProcessParent::Launch(
+ mozilla::UniquePtr<LaunchCompleteTask> aLaunchCompleteTask,
+ int32_t aSandboxLevel, bool aIsSandboxLoggingEnabled) {
+#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_SANDBOX)
+ // At present, the Mac Flash plugin sandbox does not support different
+ // levels and is enabled via a boolean pref or environment variable.
+ // On Mac, when |aSandboxLevel| is positive, we enable the sandbox.
+# if defined(XP_WIN)
+ mSandboxLevel = aSandboxLevel;
+
+ // The sandbox process sometimes needs read access to the plugin file.
+ if (aSandboxLevel >= 3) {
+ std::wstring pluginFile(
+ NS_ConvertUTF8toUTF16(mPluginFilePath.c_str()).get());
+ mAllowedFilesRead.push_back(pluginFile);
+ }
+# endif // XP_WIN
+#else
+ if (aSandboxLevel != 0) {
+ MOZ_ASSERT(false,
+ "Can't enable an NPAPI process sandbox for platform/build.");
+ }
+#endif
+
+ mLaunchCompleteTask = std::move(aLaunchCompleteTask);
+
+ vector<string> args;
+ args.push_back(MungePluginDsoPath(mPluginFilePath));
+
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+ if (aSandboxLevel > 0) {
+ args.push_back("-flashSandboxLevel");
+ args.push_back(std::to_string(aSandboxLevel));
+ if (aIsSandboxLoggingEnabled) {
+ args.push_back("-flashSandboxLogging");
+ }
+ }
+#elif defined(XP_WIN) && defined(MOZ_SANDBOX)
+ nsresult rv;
+ nsCOMPtr<nsIProperties> dirSvc =
+ do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) {
+ MOZ_ASSERT(false, "Failed to get directory service.");
+ return false;
+ }
+
+ nsCOMPtr<nsIFile> dir;
+ rv = dirSvc->Get(NS_APP_PLUGIN_PROCESS_TEMP_DIR, NS_GET_IID(nsIFile),
+ getter_AddRefs(dir));
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Failed to get plugin process temp directory.");
+ return false;
+ }
+
+ nsAutoString tempDir;
+ MOZ_ALWAYS_SUCCEEDS(dir->GetPath(tempDir));
+ args.push_back(NS_ConvertUTF16toUTF8(tempDir).get());
+
+ rv =
+ dirSvc->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsIFile), getter_AddRefs(dir));
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Failed to get appdata directory.");
+ return false;
+ }
+
+ nsAutoString appdataDir;
+ MOZ_ALWAYS_SUCCEEDS(dir->GetPath(appdataDir));
+ appdataDir.Append(L"\\Adobe\\");
+ args.push_back(NS_ConvertUTF16toUTF8(appdataDir).get());
+#endif
+
+ bool result = AsyncLaunch(args);
+ if (!result) {
+ mLaunchCompleteTask = nullptr;
+ }
+ return result;
+}
+
+/**
+ * This function exists so that we may provide an additional level of
+ * indirection between the task being posted to main event loop (a
+ * RunnableMethod) and the launch complete task itself. This is needed
+ * for cases when both WaitUntilConnected or OnChannel* race to invoke the
+ * task.
+ */
+void PluginProcessParent::RunLaunchCompleteTask() {
+ if (mLaunchCompleteTask) {
+ mLaunchCompleteTask->Run();
+ mLaunchCompleteTask = nullptr;
+ }
+}
+
+bool PluginProcessParent::WaitUntilConnected(int32_t aTimeoutMs) {
+ bool result = GeckoChildProcessHost::WaitUntilConnected(aTimeoutMs);
+ if (mLaunchCompleteTask) {
+ if (result) {
+ mLaunchCompleteTask->SetLaunchSucceeded();
+ }
+ RunLaunchCompleteTask();
+ }
+ return result;
+}
+
+void PluginProcessParent::OnChannelConnected(int32_t peer_pid) {
+#ifdef XP_WIN
+ mChildPid = static_cast<uint32_t>(peer_pid);
+ if (!sPidSet) {
+ sPidSet = new PluginProcessParent::PidSet();
+ }
+ sPidSet->PutEntry(mChildPid);
+#endif
+
+ GeckoChildProcessHost::OnChannelConnected(peer_pid);
+}
+
+void PluginProcessParent::OnChannelError() {
+ GeckoChildProcessHost::OnChannelError();
+}
+
+bool PluginProcessParent::IsConnected() {
+ mozilla::MonitorAutoLock lock(mMonitor);
+ return mProcessState == PROCESS_CONNECTED;
+}
+
+bool PluginProcessParent::IsPluginProcessId(base::ProcessId procId) {
+#ifdef XP_WIN
+ MOZ_ASSERT(XRE_IsParentProcess());
+ return sPidSet && sPidSet->Contains(static_cast<uint32_t>(procId));
+#else
+ NS_ERROR("IsPluginProcessId not available on this platform.");
+ return false;
+#endif
+}