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 "mozilla/ipc/IOThreadChild.h"
8 : #include "mozilla/plugins/PluginProcessChild.h"
9 :
10 : #include "prlink.h"
11 :
12 : #include "base/command_line.h"
13 : #include "base/string_util.h"
14 : #include "nsDebugImpl.h"
15 :
16 : #if defined(XP_MACOSX)
17 : #include "nsCocoaFeatures.h"
18 : // An undocumented CoreGraphics framework method, present in the same form
19 : // since at least OS X 10.5.
20 : extern "C" CGError CGSSetDebugOptions(int options);
21 : #endif
22 :
23 : #ifdef XP_WIN
24 : bool ShouldProtectPluginCurrentDirectory(char16ptr_t pluginFilePath);
25 : #if defined(MOZ_SANDBOX)
26 : #define TARGET_SANDBOX_EXPORTS
27 : #include "mozilla/sandboxTarget.h"
28 : #endif
29 : #endif
30 :
31 : using mozilla::ipc::IOThreadChild;
32 :
33 : #ifdef OS_WIN
34 : #include "nsSetDllDirectory.h"
35 : #include <algorithm>
36 : #endif
37 :
38 : namespace mozilla {
39 : namespace plugins {
40 :
41 :
42 : bool
43 0 : PluginProcessChild::Init(int aArgc, char* aArgv[])
44 : {
45 0 : nsDebugImpl::SetMultiprocessMode("NPAPI");
46 :
47 : #if defined(XP_MACOSX)
48 : // Remove the trigger for "dyld interposing" that we added in
49 : // GeckoChildProcessHost::PerformAsyncLaunchInternal(), in the host
50 : // process just before we were launched. Dyld interposing will still
51 : // happen in our process (the plugin child process). But we don't want
52 : // it to happen in any processes that the plugin might launch from our
53 : // process.
54 : nsCString interpose(PR_GetEnv("DYLD_INSERT_LIBRARIES"));
55 : if (!interpose.IsEmpty()) {
56 : // If we added the path to libplugin_child_interpose.dylib to an
57 : // existing DYLD_INSERT_LIBRARIES, we appended it to the end, after a
58 : // ":" path seperator.
59 : int32_t lastSeparatorPos = interpose.RFind(":");
60 : int32_t lastTriggerPos = interpose.RFind("libplugin_child_interpose.dylib");
61 : bool needsReset = false;
62 : if (lastTriggerPos != -1) {
63 : if (lastSeparatorPos == -1) {
64 : interpose.Truncate();
65 : needsReset = true;
66 : } else if (lastTriggerPos > lastSeparatorPos) {
67 : interpose.SetLength(lastSeparatorPos);
68 : needsReset = true;
69 : }
70 : }
71 : if (needsReset) {
72 : nsCString setInterpose("DYLD_INSERT_LIBRARIES=");
73 : if (!interpose.IsEmpty()) {
74 : setInterpose.Append(interpose);
75 : }
76 : // Values passed to PR_SetEnv() must be seperately allocated.
77 : char* setInterposePtr = strdup(setInterpose.get());
78 : PR_SetEnv(setInterposePtr);
79 : }
80 : }
81 : #endif
82 :
83 : // Certain plugins, such as flash, steal the unhandled exception filter
84 : // thus we never get crash reports when they fault. This call fixes it.
85 0 : message_loop()->set_exception_restoration(true);
86 :
87 0 : std::string pluginFilename;
88 :
89 : #if defined(OS_POSIX)
90 : // NB: need to be very careful in ensuring that the first arg
91 : // (after the binary name) here is indeed the plugin module path.
92 : // Keep in sync with dom/plugins/PluginModuleParent.
93 0 : std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
94 0 : MOZ_ASSERT(values.size() >= 2, "not enough args");
95 :
96 0 : pluginFilename = UnmungePluginDsoPath(values[1]);
97 :
98 : #elif defined(OS_WIN)
99 : std::vector<std::wstring> values =
100 : CommandLine::ForCurrentProcess()->GetLooseValues();
101 : MOZ_ASSERT(values.size() >= 1, "not enough loose args");
102 :
103 : if (ShouldProtectPluginCurrentDirectory(values[0].c_str())) {
104 : SanitizeEnvironmentVariables();
105 : SetDllDirectory(L"");
106 : }
107 :
108 : pluginFilename = WideToUTF8(values[0]);
109 :
110 : #if defined(MOZ_SANDBOX)
111 : // This is probably the earliest we would want to start the sandbox.
112 : // As we attempt to tighten the sandbox, we may need to consider moving this
113 : // to later in the plugin initialization.
114 : mozilla::SandboxTarget::Instance()->StartSandbox();
115 : #endif
116 : #else
117 : # error Sorry
118 : #endif
119 :
120 0 : if (NS_FAILED(nsRegion::InitStatic())) {
121 0 : NS_ERROR("Could not initialize nsRegion");
122 0 : return false;
123 : }
124 :
125 0 : bool retval = mPlugin.InitForChrome(pluginFilename, ParentPid(),
126 : IOThreadChild::message_loop(),
127 0 : IOThreadChild::channel());
128 : #if defined(XP_MACOSX)
129 : if (nsCocoaFeatures::OnYosemiteOrLater()) {
130 : // Explicitly turn off CGEvent logging. This works around bug 1092855.
131 : // If there are already CGEvents in the log, turning off logging also
132 : // causes those events to be written to disk. But at this point no
133 : // CGEvents have yet been processed. CGEvents are events (usually
134 : // input events) pulled from the WindowServer. An option of 0x80000008
135 : // turns on CGEvent logging.
136 : CGSSetDebugOptions(0x80000007);
137 : }
138 : #endif
139 0 : return retval;
140 : }
141 :
142 : void
143 0 : PluginProcessChild::CleanUp()
144 : {
145 0 : nsRegion::ShutdownStatic();
146 0 : }
147 :
148 : } // namespace plugins
149 : } // namespace mozilla
|