Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/plugins/ipc/PluginProcessChild.cpp
Line
Count
Source (jump to first uncovered line)
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
#include "nsThreadManager.h"
16
#include "ClearOnShutdown.h"
17
18
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
19
#include "mozilla/SandboxSettings.h"
20
#endif
21
22
#if defined(XP_MACOSX)
23
#include "nsCocoaFeatures.h"
24
// An undocumented CoreGraphics framework method, present in the same form
25
// since at least OS X 10.5.
26
extern "C" CGError CGSSetDebugOptions(int options);
27
#endif
28
29
#ifdef XP_WIN
30
#if defined(MOZ_SANDBOX)
31
#include "mozilla/sandboxTarget.h"
32
#endif
33
#endif
34
35
using mozilla::ipc::IOThreadChild;
36
37
#ifdef OS_WIN
38
#include <algorithm>
39
#endif
40
41
namespace mozilla {
42
namespace plugins {
43
44
bool
45
PluginProcessChild::Init(int aArgc, char* aArgv[])
46
0
{
47
0
    nsDebugImpl::SetMultiprocessMode("NPAPI");
48
0
49
#if defined(XP_MACOSX)
50
    // Remove the trigger for "dyld interposing" that we added in
51
    // GeckoChildProcessHost::PerformAsyncLaunch(), in the host
52
    // process just before we were launched.  Dyld interposing will still
53
    // happen in our process (the plugin child process).  But we don't want
54
    // it to happen in any processes that the plugin might launch from our
55
    // process.
56
    nsCString interpose(PR_GetEnv("DYLD_INSERT_LIBRARIES"));
57
    if (!interpose.IsEmpty()) {
58
        // If we added the path to libplugin_child_interpose.dylib to an
59
        // existing DYLD_INSERT_LIBRARIES, we appended it to the end, after a
60
        // ":" path seperator.
61
        int32_t lastSeparatorPos = interpose.RFind(":");
62
        int32_t lastTriggerPos = interpose.RFind("libplugin_child_interpose.dylib");
63
        bool needsReset = false;
64
        if (lastTriggerPos != -1) {
65
            if (lastSeparatorPos == -1) {
66
                interpose.Truncate();
67
                needsReset = true;
68
            } else if (lastTriggerPos > lastSeparatorPos) {
69
                interpose.SetLength(lastSeparatorPos);
70
                needsReset = true;
71
            }
72
        }
73
        if (needsReset) {
74
            nsCString setInterpose("DYLD_INSERT_LIBRARIES=");
75
            if (!interpose.IsEmpty()) {
76
                setInterpose.Append(interpose);
77
            }
78
            // Values passed to PR_SetEnv() must be seperately allocated.
79
            char* setInterposePtr = strdup(setInterpose.get());
80
            PR_SetEnv(setInterposePtr);
81
        }
82
    }
83
#endif
84
85
0
    // Certain plugins, such as flash, steal the unhandled exception filter
86
0
    // thus we never get crash reports when they fault. This call fixes it.
87
0
    message_loop()->set_exception_restoration(true);
88
0
89
0
    std::string pluginFilename;
90
0
91
0
#if defined(OS_POSIX)
92
0
    // NB: need to be very careful in ensuring that the first arg
93
0
    // (after the binary name) here is indeed the plugin module path.
94
0
    // Keep in sync with dom/plugins/PluginModuleParent.
95
0
    std::vector<std::string> values = CommandLine::ForCurrentProcess()->argv();
96
0
    MOZ_ASSERT(values.size() >= 2, "not enough args");
97
0
98
0
    pluginFilename = UnmungePluginDsoPath(values[1]);
99
0
100
#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
101
    int level;
102
    if (values.size() >= 4 && values[2] == "-flashSandboxLevel" &&
103
        (level = std::stoi(values[3], nullptr)) > 0) {
104
105
      level = ClampFlashSandboxLevel(level);
106
      MOZ_ASSERT(level > 0);
107
108
      bool enableLogging = false;
109
      if (values.size() >= 5 && values[4] == "-flashSandboxLogging") {
110
        enableLogging = true;
111
      }
112
113
      mPlugin.EnableFlashSandbox(level, enableLogging);
114
    }
115
#endif
116
117
#elif defined(OS_WIN)
118
    std::vector<std::wstring> values =
119
        CommandLine::ForCurrentProcess()->GetLooseValues();
120
    MOZ_ASSERT(values.size() >= 1, "not enough loose args");
121
122
    pluginFilename = WideToUTF8(values[0]);
123
124
    // We don't initialize XPCOM but we need the thread manager and the
125
    // logging framework for the FunctionBroker.
126
    NS_SetMainThread();
127
    mozilla::TimeStamp::Startup();
128
    NS_LogInit();
129
    mozilla::LogModule::Init(aArgc, aArgv);
130
    nsThreadManager::get().Init();
131
132
#if defined(MOZ_SANDBOX)
133
    // This is probably the earliest we would want to start the sandbox.
134
    // As we attempt to tighten the sandbox, we may need to consider moving this
135
    // to later in the plugin initialization.
136
    mozilla::SandboxTarget::Instance()->StartSandbox();
137
#endif
138
#else
139
#  error Sorry
140
#endif
141
142
0
    bool retval = mPlugin.InitForChrome(pluginFilename, ParentPid(),
143
0
                                        IOThreadChild::message_loop(),
144
0
                                        IOThreadChild::channel());
145
#if defined(XP_MACOSX)
146
    if (nsCocoaFeatures::OnYosemiteOrLater()) {
147
      // Explicitly turn off CGEvent logging.  This works around bug 1092855.
148
      // If there are already CGEvents in the log, turning off logging also
149
      // causes those events to be written to disk.  But at this point no
150
      // CGEvents have yet been processed.  CGEvents are events (usually
151
      // input events) pulled from the WindowServer.  An option of 0x80000008
152
      // turns on CGEvent logging.
153
      CGSSetDebugOptions(0x80000007);
154
    }
155
#endif
156
    return retval;
157
0
}
158
159
void
160
PluginProcessChild::CleanUp()
161
0
{
162
#if defined(OS_WIN)
163
    MOZ_ASSERT(NS_IsMainThread());
164
165
    // Shutdown components we started in Init.  Note that KillClearOnShutdown
166
    // is an event that is regularly part of XPCOM shutdown.  We do not
167
    // call XPCOM's shutdown but we need this event to be sent to avoid
168
    // leaking objects labeled as ClearOnShutdown.
169
    nsThreadManager::get().Shutdown();
170
    NS_LogTerm();
171
#endif
172
173
0
    mozilla::KillClearOnShutdown(ShutdownPhase::ShutdownFinal);
174
0
}
175
176
} // namespace plugins
177
} // namespace mozilla