dom/plugins/ipc/PluginProcessChild.cpp

branch
TOR_BUG_9701
changeset 15
b8a032363ba2
equal deleted inserted replaced
-1:000000000000 0:f50566f4c0b3
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 "chrome/common/chrome_switches.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 #include <objbase.h>
25 bool ShouldProtectPluginCurrentDirectory(char16ptr_t pluginFilePath);
26 #endif
27
28 using mozilla::ipc::IOThreadChild;
29
30 #ifdef OS_WIN
31 #include "nsSetDllDirectory.h"
32 #include <algorithm>
33
34 namespace {
35
36 std::size_t caseInsensitiveFind(std::string aHaystack, std::string aNeedle) {
37 std::transform(aHaystack.begin(), aHaystack.end(), aHaystack.begin(), ::tolower);
38 std::transform(aNeedle.begin(), aNeedle.end(), aNeedle.begin(), ::tolower);
39 return aHaystack.find(aNeedle);
40 }
41
42 }
43 #endif
44
45 namespace mozilla {
46 namespace plugins {
47
48
49 bool
50 PluginProcessChild::Init()
51 {
52 #if defined(XP_MACOSX)
53 // Remove the trigger for "dyld interposing" that we added in
54 // GeckoChildProcessHost::PerformAsyncLaunchInternal(), in the host
55 // process just before we were launched. Dyld interposing will still
56 // happen in our process (the plugin child process). But we don't want
57 // it to happen in any processes that the plugin might launch from our
58 // process.
59 nsCString interpose(PR_GetEnv("DYLD_INSERT_LIBRARIES"));
60 if (!interpose.IsEmpty()) {
61 // If we added the path to libplugin_child_interpose.dylib to an
62 // existing DYLD_INSERT_LIBRARIES, we appended it to the end, after a
63 // ":" path seperator.
64 int32_t lastSeparatorPos = interpose.RFind(":");
65 int32_t lastTriggerPos = interpose.RFind("libplugin_child_interpose.dylib");
66 bool needsReset = false;
67 if (lastTriggerPos != -1) {
68 if (lastSeparatorPos == -1) {
69 interpose.Truncate();
70 needsReset = true;
71 } else if (lastTriggerPos > lastSeparatorPos) {
72 interpose.SetLength(lastSeparatorPos);
73 needsReset = true;
74 }
75 }
76 if (needsReset) {
77 nsCString setInterpose("DYLD_INSERT_LIBRARIES=");
78 if (!interpose.IsEmpty()) {
79 setInterpose.Append(interpose);
80 }
81 // Values passed to PR_SetEnv() must be seperately allocated.
82 char* setInterposePtr = strdup(setInterpose.get());
83 PR_SetEnv(setInterposePtr);
84 }
85 }
86 #endif
87
88 #ifdef XP_WIN
89 // Drag-and-drop needs OleInitialize to be called, and Silverlight depends
90 // on the host calling CoInitialize (which is called by OleInitialize).
91 ::OleInitialize(nullptr);
92 #endif
93
94 // Certain plugins, such as flash, steal the unhandled exception filter
95 // thus we never get crash reports when they fault. This call fixes it.
96 message_loop()->set_exception_restoration(true);
97
98 std::string pluginFilename;
99
100 #if defined(OS_POSIX)
101 // NB: need to be very careful in ensuring that the first arg
102 // (after the binary name) here is indeed the plugin module path.
103 // Keep in sync with dom/plugins/PluginModuleParent.
104 std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
105 NS_ABORT_IF_FALSE(values.size() >= 2, "not enough args");
106
107 pluginFilename = UnmungePluginDsoPath(values[1]);
108
109 #elif defined(OS_WIN)
110 std::vector<std::wstring> values =
111 CommandLine::ForCurrentProcess()->GetLooseValues();
112 NS_ABORT_IF_FALSE(values.size() >= 1, "not enough loose args");
113
114 if (ShouldProtectPluginCurrentDirectory(values[0].c_str())) {
115 SanitizeEnvironmentVariables();
116 SetDllDirectory(L"");
117 }
118
119 pluginFilename = WideToUTF8(values[0]);
120 #else
121 # error Sorry
122 #endif
123
124 if (NS_FAILED(nsRegion::InitStatic())) {
125 NS_ERROR("Could not initialize nsRegion");
126 return false;
127 }
128
129 bool retval = mPlugin.Init(pluginFilename, ParentHandle(),
130 IOThreadChild::message_loop(),
131 IOThreadChild::channel());
132 #if defined(XP_MACOSX)
133 if (nsCocoaFeatures::OnYosemiteOrLater()) {
134 // Explicitly turn off CGEvent logging. This works around bug 1092855.
135 // If there are already CGEvents in the log, turning off logging also
136 // causes those events to be written to disk. But at this point no
137 // CGEvents have yet been processed. CGEvents are events (usually
138 // input events) pulled from the WindowServer. An option of 0x80000008
139 // turns on CGEvent logging.
140 CGSSetDebugOptions(0x80000007);
141 }
142 #endif
143 return retval;
144 }
145
146 void
147 PluginProcessChild::CleanUp()
148 {
149 #ifdef XP_WIN
150 ::OleUninitialize();
151 #endif
152 nsRegion::ShutdownStatic();
153 }
154
155 } // namespace plugins
156 } // namespace mozilla

mercurial