• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // -*- c++ -*-
2 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 
6 // The portable representation of an instance and root scriptable object.
7 // The PPAPI version of the plugin instantiates a subclass of this class.
8 
9 #ifndef NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_
10 #define NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_
11 
12 #include <stdio.h>
13 
14 #include <map>
15 #include <queue>
16 #include <set>
17 #include <string>
18 
19 #include "native_client/src/include/nacl_macros.h"
20 #include "native_client/src/include/nacl_scoped_ptr.h"
21 #include "native_client/src/include/nacl_string.h"
22 #include "native_client/src/public/nacl_file_info.h"
23 
24 #include "ppapi/c/private/ppb_nacl_private.h"
25 #include "ppapi/cpp/instance.h"
26 #include "ppapi/cpp/private/uma_private.h"
27 #include "ppapi/cpp/url_loader.h"
28 #include "ppapi/cpp/var.h"
29 #include "ppapi/cpp/view.h"
30 
31 #include "ppapi/native_client/src/trusted/plugin/file_downloader.h"
32 #include "ppapi/native_client/src/trusted/plugin/nacl_subprocess.h"
33 #include "ppapi/native_client/src/trusted/plugin/pnacl_coordinator.h"
34 #include "ppapi/native_client/src/trusted/plugin/service_runtime.h"
35 #include "ppapi/native_client/src/trusted/plugin/utility.h"
36 
37 namespace nacl {
38 class DescWrapper;
39 class DescWrapperFactory;
40 }  // namespace nacl
41 
42 namespace pp {
43 class CompletionCallback;
44 class URLLoader;
45 class URLUtil_Dev;
46 }
47 
48 namespace plugin {
49 
50 class ErrorInfo;
51 class Manifest;
52 
53 int32_t ConvertFileDescriptor(PP_FileHandle handle);
54 
55 class Plugin : public pp::Instance {
56  public:
57   explicit Plugin(PP_Instance instance);
58 
59   // ----- Methods inherited from pp::Instance:
60 
61   // Initializes this plugin with <embed/object ...> tag attribute count |argc|,
62   // names |argn| and values |argn|. Returns false on failure.
63   // Gets called by the browser right after New().
64   virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
65 
66   // Handles document load, when the plugin is a MIME type handler.
67   virtual bool HandleDocumentLoad(const pp::URLLoader& url_loader);
68 
69   // Load support.
70   //
71   // Starts NaCl module but does not wait until low-level
72   // initialization (e.g. ld.so dynamic loading of manifest files) is
73   // done.  The module will become ready later, asynchronously.  Other
74   // event handlers should block until the module is ready before
75   // trying to communicate with it, i.e., until nacl_ready_state is
76   // DONE.
77   //
78   // NB: currently we do not time out, so if the untrusted code
79   // does not signal that it is ready, then we will deadlock the main
80   // thread of the renderer on this subsequent event delivery.  We
81   // should include a time-out at which point we declare the
82   // nacl_ready_state to be done, and let the normal crash detection
83   // mechanism(s) take over.
84   void LoadNaClModule(PP_NaClFileInfo file_info,
85                       bool uses_nonsfi_mode,
86                       bool enable_dyncode_syscalls,
87                       bool enable_exception_handling,
88                       bool enable_crash_throttling,
89                       const pp::CompletionCallback& init_done_cb,
90                       const pp::CompletionCallback& crash_cb);
91 
92   // Finish hooking interfaces up, after low-level initialization is
93   // complete.
94   bool LoadNaClModuleContinuationIntern();
95 
96   // Continuation for starting SRPC/JSProxy services as appropriate.
97   // This is invoked as a callback when the NaCl module makes the
98   // init_done reverse RPC to tell us that low-level initialization
99   // such as ld.so processing is done.  That initialization requires
100   // that the main thread be free in order to do Pepper
101   // main-thread-only operations such as file processing.
102   bool LoadNaClModuleContinuation(int32_t pp_error);
103 
104   // Load support.
105   // A helper SRPC NaCl module can be loaded given a PP_FileHandle.
106   // Blocks until the helper module signals initialization is done.
107   // Does not update nacl_module_origin().
108   // Returns NULL or the NaClSubprocess of the new helper NaCl module.
109   NaClSubprocess* LoadHelperNaClModule(const nacl::string& helper_url,
110                                        PP_FileHandle file_handle,
111                                        ErrorInfo* error_info);
112 
113   // Report an error that was encountered while loading a module.
114   void ReportLoadError(const ErrorInfo& error_info);
115 
wrapper_factory()116   nacl::DescWrapperFactory* wrapper_factory() const { return wrapper_factory_; }
117 
118   // A helper function that indicates if |url| can be requested by the document
119   // under the same-origin policy. Strictly speaking, it may be possible for the
120   // document to request the URL using CORS even if this function returns false.
121   bool DocumentCanRequest(const std::string& url);
122 
123   // set_exit_status may be called off the main thread.
124   void set_exit_status(int exit_status);
125 
nacl_interface()126   const PPB_NaCl_Private* nacl_interface() const { return nacl_interface_; }
uma_interface()127   pp::UMAPrivate& uma_interface() { return uma_interface_; }
128 
129  private:
130   NACL_DISALLOW_COPY_AND_ASSIGN(Plugin);
131   // The browser will invoke the destructor via the pp::Instance
132   // pointer to this object, not from base's Delete().
133   ~Plugin();
134 
135   // Shuts down socket connection, service runtime, and receive thread,
136   // in this order, for the main nacl subprocess.
137   void ShutDownSubprocesses();
138 
139   // Histogram helper functions, internal to Plugin so they can use
140   // uma_interface_ normally.
141   void HistogramTimeSmall(const std::string& name, int64_t ms);
142 
143   // Load a nacl module from the file specified in file_handle.
144   // Only to be used from a background (non-main) thread for the PNaCl
145   // translator. This will fully initialize the |subprocess| if the load was
146   // successful.
147   bool LoadHelperNaClModule(PP_FileHandle file_handle,
148                             NaClSubprocess* subprocess,
149                             const SelLdrStartParams& params);
150 
151   // Start sel_ldr from the main thread, given the start params.
152   // |pp_error| is set by CallOnMainThread (should be PP_OK).
153   void StartSelLdrOnMainThread(int32_t pp_error,
154                                ServiceRuntime* service_runtime,
155                                const SelLdrStartParams& params,
156                                pp::CompletionCallback callback);
157 
158   // Signals that StartSelLdr has finished.
159   // This is invoked on the main thread.
160   void SignalStartSelLdrDone(int32_t pp_error,
161                              bool* started,
162                              ServiceRuntime* service_runtime);
163 
164   // Signals that the nexe is started.
165   // This is invoked on the main thread.
166   void SignalNexeStarted(int32_t pp_error,
167                          bool* started,
168                          ServiceRuntime* service_runtime);
169 
170   // This is invoked on the main thread.
171   void LoadNexeAndStart(int32_t pp_error,
172                         ServiceRuntime* service_runtime,
173                         PP_NaClFileInfo file_info,
174                         const pp::CompletionCallback& callback);
175 
176   // Callback used when getting the URL for the .nexe file.  If the URL loading
177   // is successful, the file descriptor is opened and can be passed to sel_ldr
178   // with the sandbox on.
179   void NexeFileDidOpen(int32_t pp_error);
180   void NexeFileDidOpenContinuation(int32_t pp_error);
181 
182   // Callback used when the reverse channel closes.  This is an
183   // asynchronous event that might turn into a JavaScript error or
184   // crash event -- this is controlled by the two state variables
185   // nacl_ready_state_ and nexe_error_reported_: If an error or crash
186   // had already been reported, no additional crash event is
187   // generated.  If no error has been reported but nacl_ready_state_
188   // is not DONE, then the loadend event has not been reported, and we
189   // enqueue an error event followed by loadend.  If nacl_ready_state_
190   // is DONE, then we are in the post-loadend (we need temporal
191   // predicate symbols), and we enqueue a crash event.
192   void NexeDidCrash(int32_t pp_error);
193 
194   // Callback used when a .nexe is translated from bitcode.  If the translation
195   // is successful, the file descriptor is opened and can be passed to sel_ldr
196   // with the sandbox on.
197   void BitcodeDidTranslate(int32_t pp_error);
198   void BitcodeDidTranslateContinuation(int32_t pp_error);
199 
200   // NaCl ISA selection manifest file support.  The manifest file is specified
201   // using the "nacl" attribute in the <embed> tag.  First, the manifest URL (or
202   // data: URI) is fetched, then the JSON is parsed.  Once a valid .nexe is
203   // chosen for the sandbox ISA, any current service runtime is shut down, the
204   // .nexe is loaded and run.
205 
206   // Callback used when getting the manifest file as a local file descriptor.
207   void NaClManifestFileDidOpen(int32_t pp_error);
208 
209   // Processes the JSON manifest string and starts loading the nexe.
210   void ProcessNaClManifest(const nacl::string& manifest_json);
211 
212   void SetExitStatusOnMainThread(int32_t pp_error, int exit_status);
213 
214   // Keep track of the NaCl module subprocess that was spun up in the plugin.
215   NaClSubprocess main_subprocess_;
216 
217   bool uses_nonsfi_mode_;
218 
219   nacl::DescWrapperFactory* wrapper_factory_;
220 
221   // Original, unresolved URL for the .nexe program to load.
222   std::string program_url_;
223 
224   pp::CompletionCallbackFactory<Plugin> callback_factory_;
225 
226   nacl::scoped_ptr<PnaclCoordinator> pnacl_coordinator_;
227 
228   int exit_status_;
229 
230   PP_NaClFileInfo nexe_file_info_;
231 
232   const PPB_NaCl_Private* nacl_interface_;
233   pp::UMAPrivate uma_interface_;
234 };
235 
236 }  // namespace plugin
237 
238 #endif  // NATIVE_CLIENT_SRC_TRUSTED_PLUGIN_PLUGIN_H_
239