1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/plugins/ipc/PluginProcessChild.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,156 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 1.5 + * vim: sw=4 ts=4 et : 1.6 + * This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +#include "mozilla/ipc/IOThreadChild.h" 1.11 +#include "mozilla/plugins/PluginProcessChild.h" 1.12 + 1.13 +#include "prlink.h" 1.14 + 1.15 +#include "base/command_line.h" 1.16 +#include "base/string_util.h" 1.17 +#include "chrome/common/chrome_switches.h" 1.18 + 1.19 +#if defined(XP_MACOSX) 1.20 +#include "nsCocoaFeatures.h" 1.21 +// An undocumented CoreGraphics framework method, present in the same form 1.22 +// since at least OS X 10.5. 1.23 +extern "C" CGError CGSSetDebugOptions(int options); 1.24 +#endif 1.25 + 1.26 +#ifdef XP_WIN 1.27 +#include <objbase.h> 1.28 +bool ShouldProtectPluginCurrentDirectory(char16ptr_t pluginFilePath); 1.29 +#endif 1.30 + 1.31 +using mozilla::ipc::IOThreadChild; 1.32 + 1.33 +#ifdef OS_WIN 1.34 +#include "nsSetDllDirectory.h" 1.35 +#include <algorithm> 1.36 + 1.37 +namespace { 1.38 + 1.39 +std::size_t caseInsensitiveFind(std::string aHaystack, std::string aNeedle) { 1.40 + std::transform(aHaystack.begin(), aHaystack.end(), aHaystack.begin(), ::tolower); 1.41 + std::transform(aNeedle.begin(), aNeedle.end(), aNeedle.begin(), ::tolower); 1.42 + return aHaystack.find(aNeedle); 1.43 +} 1.44 + 1.45 +} 1.46 +#endif 1.47 + 1.48 +namespace mozilla { 1.49 +namespace plugins { 1.50 + 1.51 + 1.52 +bool 1.53 +PluginProcessChild::Init() 1.54 +{ 1.55 +#if defined(XP_MACOSX) 1.56 + // Remove the trigger for "dyld interposing" that we added in 1.57 + // GeckoChildProcessHost::PerformAsyncLaunchInternal(), in the host 1.58 + // process just before we were launched. Dyld interposing will still 1.59 + // happen in our process (the plugin child process). But we don't want 1.60 + // it to happen in any processes that the plugin might launch from our 1.61 + // process. 1.62 + nsCString interpose(PR_GetEnv("DYLD_INSERT_LIBRARIES")); 1.63 + if (!interpose.IsEmpty()) { 1.64 + // If we added the path to libplugin_child_interpose.dylib to an 1.65 + // existing DYLD_INSERT_LIBRARIES, we appended it to the end, after a 1.66 + // ":" path seperator. 1.67 + int32_t lastSeparatorPos = interpose.RFind(":"); 1.68 + int32_t lastTriggerPos = interpose.RFind("libplugin_child_interpose.dylib"); 1.69 + bool needsReset = false; 1.70 + if (lastTriggerPos != -1) { 1.71 + if (lastSeparatorPos == -1) { 1.72 + interpose.Truncate(); 1.73 + needsReset = true; 1.74 + } else if (lastTriggerPos > lastSeparatorPos) { 1.75 + interpose.SetLength(lastSeparatorPos); 1.76 + needsReset = true; 1.77 + } 1.78 + } 1.79 + if (needsReset) { 1.80 + nsCString setInterpose("DYLD_INSERT_LIBRARIES="); 1.81 + if (!interpose.IsEmpty()) { 1.82 + setInterpose.Append(interpose); 1.83 + } 1.84 + // Values passed to PR_SetEnv() must be seperately allocated. 1.85 + char* setInterposePtr = strdup(setInterpose.get()); 1.86 + PR_SetEnv(setInterposePtr); 1.87 + } 1.88 + } 1.89 +#endif 1.90 + 1.91 +#ifdef XP_WIN 1.92 + // Drag-and-drop needs OleInitialize to be called, and Silverlight depends 1.93 + // on the host calling CoInitialize (which is called by OleInitialize). 1.94 + ::OleInitialize(nullptr); 1.95 +#endif 1.96 + 1.97 + // Certain plugins, such as flash, steal the unhandled exception filter 1.98 + // thus we never get crash reports when they fault. This call fixes it. 1.99 + message_loop()->set_exception_restoration(true); 1.100 + 1.101 + std::string pluginFilename; 1.102 + 1.103 +#if defined(OS_POSIX) 1.104 + // NB: need to be very careful in ensuring that the first arg 1.105 + // (after the binary name) here is indeed the plugin module path. 1.106 + // Keep in sync with dom/plugins/PluginModuleParent. 1.107 + std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv(); 1.108 + NS_ABORT_IF_FALSE(values.size() >= 2, "not enough args"); 1.109 + 1.110 + pluginFilename = UnmungePluginDsoPath(values[1]); 1.111 + 1.112 +#elif defined(OS_WIN) 1.113 + std::vector<std::wstring> values = 1.114 + CommandLine::ForCurrentProcess()->GetLooseValues(); 1.115 + NS_ABORT_IF_FALSE(values.size() >= 1, "not enough loose args"); 1.116 + 1.117 + if (ShouldProtectPluginCurrentDirectory(values[0].c_str())) { 1.118 + SanitizeEnvironmentVariables(); 1.119 + SetDllDirectory(L""); 1.120 + } 1.121 + 1.122 + pluginFilename = WideToUTF8(values[0]); 1.123 +#else 1.124 +# error Sorry 1.125 +#endif 1.126 + 1.127 + if (NS_FAILED(nsRegion::InitStatic())) { 1.128 + NS_ERROR("Could not initialize nsRegion"); 1.129 + return false; 1.130 + } 1.131 + 1.132 + bool retval = mPlugin.Init(pluginFilename, ParentHandle(), 1.133 + IOThreadChild::message_loop(), 1.134 + IOThreadChild::channel()); 1.135 +#if defined(XP_MACOSX) 1.136 + if (nsCocoaFeatures::OnYosemiteOrLater()) { 1.137 + // Explicitly turn off CGEvent logging. This works around bug 1092855. 1.138 + // If there are already CGEvents in the log, turning off logging also 1.139 + // causes those events to be written to disk. But at this point no 1.140 + // CGEvents have yet been processed. CGEvents are events (usually 1.141 + // input events) pulled from the WindowServer. An option of 0x80000008 1.142 + // turns on CGEvent logging. 1.143 + CGSSetDebugOptions(0x80000007); 1.144 + } 1.145 +#endif 1.146 + return retval; 1.147 +} 1.148 + 1.149 +void 1.150 +PluginProcessChild::CleanUp() 1.151 +{ 1.152 +#ifdef XP_WIN 1.153 + ::OleUninitialize(); 1.154 +#endif 1.155 + nsRegion::ShutdownStatic(); 1.156 +} 1.157 + 1.158 +} // namespace plugins 1.159 +} // namespace mozilla