1 : /* -*- c++ -*- */
2 : /*
3 : * Copyright (c) 2012 The Native Client Authors. All rights reserved.
4 : * Use of this source code is governed by a BSD-style license that can be
5 : * found in the LICENSE file.
6 : */
7 :
8 : #ifndef NATIVE_CLIENT_SRC_TRUSTED_REVERSE_SERVICE_REVERSE_SERVICE_H_
9 : #define NATIVE_CLIENT_SRC_TRUSTED_REVERSE_SERVICE_REVERSE_SERVICE_H_
10 :
11 : #include <set>
12 :
13 : #include "native_client/src/include/nacl_compiler_annotations.h"
14 : #include "native_client/src/include/nacl_macros.h"
15 : #include "native_client/src/include/nacl_scoped_ptr.h"
16 : #include "native_client/src/include/nacl_string.h"
17 :
18 : #include "native_client/src/public/name_service.h"
19 : #include "native_client/src/shared/platform/refcount_base.h"
20 : #include "native_client/src/shared/platform/nacl_sync.h"
21 : #include "native_client/src/trusted/desc/nacl_desc_wrapper.h"
22 : #include "native_client/src/trusted/reverse_service/reverse_service_c.h"
23 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
24 :
25 : struct NaClFileInfo;
26 :
27 : namespace nacl {
28 :
29 : // The CreateProcessFunctorInterface allows delivery of results to an
30 : // RPC handler via the Results arguments. This is so that RPC
31 : // handlers can invoke their done closure to send the output arguments
32 : // -- when the functor returns, the code that invoked the
33 : // CreateProcessFunctorInterface can unlock mutex locks, deallocate
34 : // memory, or finalize storage as needed. (See the 2-phase comment in
35 : // src/trusted/sel_universal/reverse_emulate.cc,
36 : // ReverseEmulate::CreateProcessFunctorResult.)
37 : //
38 : // The out_pid_or_errno contains an identifier for informing the
39 : // embedding interface that it is okay to free the resources
40 : // associated with the child process once it has exited, or a negative
41 : // ABI error value otherwise (see
42 : // service_runtime/include/sys/errno.h).
43 : class CreateProcessFunctorInterface {
44 : public:
45 2 : CreateProcessFunctorInterface() {}
46 2 : virtual ~CreateProcessFunctorInterface() {}
47 :
48 : virtual void Results(nacl::DescWrapper* out_sock_addr,
49 : nacl::DescWrapper* out_app_addr,
50 : int32_t out_pid_or_errno) = 0;
51 : };
52 :
53 :
54 5 : class ReverseInterface : public RefCountBase {
55 : public:
56 0 : virtual ~ReverseInterface() {}
57 :
58 : // Startup handshake
59 : virtual void StartupInitializationComplete() = 0;
60 :
61 : // Name service use.
62 : //
63 : // Some of these functions require that the actual operation be done
64 : // in a different thread, so that the implementation of the
65 : // interface will have to block the requesting thread. However, on
66 : // surf away, the thread switch may get cancelled, and the
67 : // implementation will have to reply with a failure indication.
68 :
69 : // The bool functions returns false if the service thread unblocked
70 : // because of surf-away, shutdown, or other issues. The plugin,
71 : // when it tells sel_ldr to shut down, will also signal all threads
72 : // that are waiting for main thread callbacks to wake up and abandon
73 : // their vigil after the callbacks are all cancelled (by abandoning
74 : // the WeakRefAnchor or by bombing their CompletionCallbackFactory).
75 : // Since shutdown/surfaway is the only admissible error, we use bool
76 : // as the return type.
77 : virtual bool OpenManifestEntry(nacl::string url_key,
78 : struct NaClFileInfo* info) = 0;
79 : virtual void ReportCrash() = 0;
80 :
81 : // The low-order 8 bits of the |exit_status| should be reported to
82 : // any interested parties.
83 : virtual void ReportExitStatus(int exit_status) = 0;
84 :
85 : // Standard output and standard error redirection, via setting
86 : // NACL_EXE_STDOUT to the string "DEBUG_ONLY:dev://postmessage" (see
87 : // native_client/src/trusted/nacl_resource.* and sel_ldr). NB: the
88 : // contents of |message| is arbitrary bytes and not an Unicode
89 : // string, so the implementation should take care to handle this
90 : // appropriately.
91 : virtual void DoPostMessage(nacl::string message) = 0;
92 :
93 : // Create new service runtime process and return secure command
94 : // channel and untrusted application channel socket addresses. Returns
95 : // 0 if successful or negative ABI error value otherwise (see
96 : // service_runtime/include/sys/errno.h).
97 : // TODO(phosek): remove the stub interface once the plugin provides one.
98 0 : virtual int CreateProcess(nacl::DescWrapper** out_sock_addr,
99 0 : nacl::DescWrapper** out_app_addr) {
100 0 : UNREFERENCED_PARAMETER(out_sock_addr);
101 0 : UNREFERENCED_PARAMETER(out_app_addr);
102 0 : return -NACL_ABI_EAGAIN;
103 : }
104 :
105 : // Create new service runtime process and return, via the functor,
106 : // the secure command channel and untrusted application channel
107 : // socket addresses and a non-negative pid or negated errno value.
108 : // See CreateProcessFunctorInterface above.
109 :
110 : // TODO(bsy): remove the stub interface once the plugin provides
111 : // one.
112 : virtual void CreateProcessFunctorResult(
113 0 : CreateProcessFunctorInterface* functor) {
114 0 : UNREFERENCED_PARAMETER(functor);
115 0 : }
116 :
117 0 : virtual void FinalizeProcess(int32_t pid) {
118 0 : UNREFERENCED_PARAMETER(pid);
119 0 : return;
120 : }
121 :
122 : // Quota checking for files that were sent to the untrusted module.
123 : // TODO(sehr): remove the stub interface once the plugin provides one.
124 0 : virtual int64_t RequestQuotaForWrite(nacl::string file_id,
125 0 : int64_t offset,
126 0 : int64_t bytes_to_write) {
127 0 : UNREFERENCED_PARAMETER(file_id);
128 0 : UNREFERENCED_PARAMETER(offset);
129 0 : return bytes_to_write;
130 : }
131 :
132 : // covariant impl of Ref()
133 : ReverseInterface* Ref() { // down_cast
134 : return reinterpret_cast<ReverseInterface*>(RefCountBase::Ref());
135 : }
136 : };
137 :
138 : class ReverseService : public RefCountBase {
139 : public:
140 : ReverseService(DescWrapper* conn_cap, ReverseInterface* rif);
141 :
142 : // covariant impl of Ref()
143 : ReverseService* Ref() { // down_cast
144 : return reinterpret_cast<ReverseService*>(RefCountBase::Ref());
145 : }
146 :
147 : // Start starts the reverse service by initiating a connection on
148 : // the conn_cap and spawning a service thread using the
149 : // ReverseInterface rif, both provided in the ctor.
150 : //
151 : // If |crash_report| is true, then the ReportCrash virtual function
152 : // will be invoked when the reverse channel is closed. Typically
153 : // this is needed only in one (the "primary" or "bootstrap")
154 : // instance of the reverse service, since additional channels
155 : // created are often used for and are under application program
156 : // control, and the untrusted application should be able to close
157 : // those channels without generating a false crash report.
158 : bool Start(bool crash_report);
159 :
160 : bool Start() {
161 5 : return Start(true);
162 : }
163 :
164 : void WaitForServiceThreadsToExit();
165 :
166 : void IncrThreadCount();
167 : void DecrThreadCount();
168 :
169 : ReverseInterface* reverse_interface() const { return reverse_interface_; }
170 :
171 : protected:
172 : ~ReverseService();
173 :
174 : private:
175 : NACL_DISALLOW_COPY_AND_ASSIGN(ReverseService);
176 :
177 : NaClReverseService* service_;
178 : ReverseInterface* reverse_interface_;
179 : };
180 :
181 : } // namespace nacl
182 :
183 : #endif
|