1 : /*
2 : * Copyright (c) 2012 The Native Client 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 :
7 : #define NACL_LOG_MODULE_NAME "reverse_service"
8 :
9 : #include "native_client/src/trusted/reverse_service/reverse_service.h"
10 :
11 : #include <string.h>
12 :
13 : #include <limits>
14 : #include <string>
15 :
16 : #include "native_client/src/include/nacl_compiler_annotations.h"
17 : #include "native_client/src/include/nacl_scoped_ptr.h"
18 : #include "native_client/src/include/portability_io.h"
19 : #include "native_client/src/shared/platform/nacl_check.h"
20 : #include "native_client/src/shared/platform/nacl_host_desc.h"
21 : #include "native_client/src/shared/platform/nacl_log.h"
22 : #include "native_client/src/shared/platform/nacl_sync.h"
23 : #include "native_client/src/shared/platform/nacl_sync_checked.h"
24 : #include "native_client/src/shared/platform/nacl_threads.h"
25 : #include "native_client/src/shared/srpc/nacl_srpc.h"
26 :
27 : #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
28 : #include "native_client/src/trusted/desc/nacl_desc_io.h"
29 :
30 : #include "native_client/src/trusted/service_runtime/include/sys/fcntl.h"
31 :
32 : namespace {
33 :
34 : // ReverseInterfaceWrapper wraps a C++ interface and provides
35 : // C-callable wrapper functions for use by the underlying C
36 : // implementation.
37 :
38 : struct ReverseInterfaceWrapper {
39 : NaClReverseInterface base NACL_IS_REFCOUNT_SUBCLASS;
40 : nacl::ReverseInterface* iface;
41 : };
42 :
43 1 : void StartupInitializationComplete(NaClReverseInterface* self) {
44 1 : ReverseInterfaceWrapper* wrapper =
45 : reinterpret_cast<ReverseInterfaceWrapper*>(self);
46 1 : if (NULL == wrapper->iface) {
47 0 : NaClLog(1, "StartupInitializationComplete, no reverse_interface.\n");
48 0 : } else {
49 1 : wrapper->iface->StartupInitializationComplete();
50 : }
51 1 : }
52 :
53 2 : int OpenManifestEntry(NaClReverseInterface* self,
54 2 : char const* url_key,
55 2 : struct NaClFileInfo* info) {
56 2 : ReverseInterfaceWrapper* wrapper =
57 : reinterpret_cast<ReverseInterfaceWrapper*>(self);
58 2 : if (NULL == wrapper->iface) {
59 0 : NaClLog(1, "OpenManifestEntry, no reverse_interface.\n");
60 0 : return 0;
61 : }
62 8 : return wrapper->iface->OpenManifestEntry(nacl::string(url_key), info);
63 2 : }
64 :
65 5 : void ReportCrash(NaClReverseInterface* self) {
66 5 : ReverseInterfaceWrapper* wrapper =
67 : reinterpret_cast<ReverseInterfaceWrapper*>(self);
68 5 : if (NULL == wrapper->iface) {
69 0 : NaClLog(1, "ReportCrash, no reverse_interface.\n");
70 0 : } else {
71 5 : wrapper->iface->ReportCrash();
72 : }
73 5 : }
74 :
75 2 : void ReportExitStatus(NaClReverseInterface* self,
76 2 : int exit_status) {
77 2 : ReverseInterfaceWrapper* wrapper =
78 : reinterpret_cast<ReverseInterfaceWrapper*>(self);
79 2 : if (NULL == wrapper->iface) {
80 0 : NaClLog(1, "ReportExitStatus, no reverse_interface.\n");
81 0 : } else {
82 2 : wrapper->iface->ReportExitStatus(exit_status);
83 : }
84 2 : }
85 :
86 0 : void DoPostMessage(NaClReverseInterface* self,
87 0 : char const* message,
88 0 : size_t message_bytes) {
89 0 : ReverseInterfaceWrapper* wrapper =
90 : reinterpret_cast<ReverseInterfaceWrapper*>(self);
91 0 : if (NULL == wrapper->iface) {
92 0 : NaClLog(1, "DoPostMessage, no reverse_interface.\n");
93 0 : } else {
94 0 : wrapper->iface->DoPostMessage(nacl::string(message, message_bytes));
95 : }
96 0 : }
97 :
98 0 : int CreateProcess(NaClReverseInterface* self,
99 0 : NaClDesc** out_sock_addr,
100 0 : NaClDesc** out_app_addr) {
101 0 : ReverseInterfaceWrapper* wrapper =
102 : reinterpret_cast<ReverseInterfaceWrapper*>(self);
103 0 : if (NULL == wrapper->iface) {
104 0 : NaClLog(1, "CreateProcess, no reverse_interface.\n");
105 0 : return -NACL_ABI_EAGAIN;
106 : }
107 :
108 0 : int status;
109 0 : nacl::DescWrapper* sock_addr;
110 0 : nacl::DescWrapper* app_addr;
111 0 : if (0 == (status = wrapper->iface->CreateProcess(&sock_addr, &app_addr))) {
112 0 : *out_sock_addr = sock_addr->desc();
113 0 : *out_app_addr = app_addr->desc();
114 0 : }
115 0 : return status;
116 0 : }
117 :
118 4 : class CreateProcessFunctorBinder : public nacl::CreateProcessFunctorInterface {
119 : public:
120 4 : CreateProcessFunctorBinder(void (*functor)(void* functor_state,
121 : NaClDesc* out_sock_addr,
122 : NaClDesc* out_app_addr,
123 : int32_t out_pid_or_errno),
124 4 : void* functor_state)
125 4 : : functor_(functor), state_(functor_state) {}
126 :
127 2 : virtual void Results(nacl::DescWrapper* out_sock_addr,
128 2 : nacl::DescWrapper* out_app_addr,
129 2 : int32_t out_pid_or_errno) {
130 2 : functor_(state_, out_sock_addr->desc(), out_app_addr->desc(),
131 : out_pid_or_errno);
132 2 : }
133 : private:
134 : void (*functor_)(void*, NaClDesc*, NaClDesc*, int32_t);
135 : void* state_;
136 : };
137 :
138 2 : void CreateProcessFunctorResult(NaClReverseInterface* self,
139 2 : void (*functor)(void* functor_state,
140 : NaClDesc* out_sock_addr,
141 : NaClDesc* out_app_addr,
142 : int32_t out_pid_or_errno),
143 2 : void *functor_state) {
144 2 : ReverseInterfaceWrapper* wrapper =
145 : reinterpret_cast<ReverseInterfaceWrapper*>(self);
146 :
147 2 : CreateProcessFunctorBinder callback(functor, functor_state);
148 2 : wrapper->iface->CreateProcessFunctorResult(&callback);
149 2 : }
150 :
151 0 : void FinalizeProcess(NaClReverseInterface* self,
152 0 : int32_t pid) {
153 0 : ReverseInterfaceWrapper* wrapper =
154 : reinterpret_cast<ReverseInterfaceWrapper*>(self);
155 :
156 0 : wrapper->iface->FinalizeProcess(pid);
157 0 : }
158 :
159 0 : int64_t RequestQuotaForWrite(NaClReverseInterface* self,
160 0 : char const* file_id,
161 0 : int64_t offset,
162 0 : int64_t length) {
163 0 : ReverseInterfaceWrapper* wrapper =
164 : reinterpret_cast<ReverseInterfaceWrapper*>(self);
165 0 : if (NULL == wrapper->iface) {
166 0 : NaClLog(1, "RequestQuotaForWrite, no reverse_interface.\n");
167 0 : return 0;
168 : }
169 0 : return wrapper->iface->RequestQuotaForWrite(
170 : nacl::string(file_id), offset, length);
171 0 : }
172 :
173 0 : void ReverseInterfaceWrapperDtor(NaClRefCount* vself) {
174 0 : ReverseInterfaceWrapper* self =
175 : reinterpret_cast<ReverseInterfaceWrapper*>(vself);
176 :
177 0 : self->iface->Unref();
178 0 : self->iface = NULL;
179 :
180 0 : NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl;
181 0 : (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
182 0 : }
183 :
184 : static NaClReverseInterfaceVtbl const kReverseInterfaceWrapperVtbl = {
185 : {
186 : ReverseInterfaceWrapperDtor,
187 : },
188 : StartupInitializationComplete,
189 : OpenManifestEntry,
190 : ReportCrash,
191 : ReportExitStatus,
192 : DoPostMessage,
193 : CreateProcess,
194 : CreateProcessFunctorResult,
195 : FinalizeProcess,
196 : RequestQuotaForWrite,
197 : };
198 :
199 5 : int ReverseInterfaceWrapperCtor(ReverseInterfaceWrapper* self,
200 5 : nacl::ReverseInterface* itf) {
201 10 : NaClLog(4,
202 : "ReverseInterfaceWrapperCtor: self 0x%" NACL_PRIxPTR "\n",
203 : reinterpret_cast<uintptr_t>(self));
204 5 : if (!NaClReverseInterfaceCtor_protected(
205 : reinterpret_cast<NaClReverseInterface*>(&self->base))) {
206 0 : NaClLog(4, "ReverseInterfaceWrapperCtor:"
207 : " NaClReverseInterfaceCtor_protected failed\n");
208 0 : return 0;
209 : }
210 5 : self->iface = itf;
211 :
212 5 : NACL_VTBL(NaClRefCount, self) =
213 : reinterpret_cast<NaClRefCountVtbl const*>(&kReverseInterfaceWrapperVtbl);
214 :
215 10 : NaClLog(4, "VTBL\n");
216 10 : NaClLog(4, "Leaving ReverseInterfaceWrapperCtor\n");
217 5 : return 1;
218 5 : }
219 :
220 : } // namespace
221 :
222 : namespace nacl {
223 :
224 10 : ReverseService::ReverseService(DescWrapper* conn_cap,
225 10 : ReverseInterface* rif)
226 : : service_(NULL),
227 5 : reverse_interface_(rif) {
228 15 : NaClLog(4, "ReverseService::ReverseService ctor invoked\n");
229 :
230 5 : ReverseInterfaceWrapper* wrapper =
231 10 : reinterpret_cast<ReverseInterfaceWrapper*>(malloc(sizeof *wrapper));
232 5 : if (NULL == wrapper) {
233 0 : NaClLog(LOG_FATAL, "ReverseService::ReverseService: malloc failed\n");
234 0 : }
235 10 : if (!ReverseInterfaceWrapperCtor(wrapper, rif)) {
236 0 : NaClLog(LOG_FATAL, "ReverseService::ReverseService: "
237 : "ReverseInterfaceWrapperCtor failed\n");
238 0 : }
239 :
240 10 : service_ = reinterpret_cast<NaClReverseService*>(malloc(sizeof *service_));
241 5 : if (NULL == service_) {
242 0 : NaClLog(LOG_FATAL, "ReverseService::ReverseService: malloc failed\n");
243 0 : }
244 15 : if (!NaClReverseServiceCtor(service_,
245 : reinterpret_cast<NaClReverseInterface*>(wrapper),
246 5 : conn_cap->desc())) {
247 0 : NaClLog(LOG_FATAL, "ReverseService::ReverseService: "
248 : "NaClReverseServiceCtor failed\n");
249 0 : }
250 10 : }
251 :
252 20 : ReverseService::~ReverseService() {
253 5 : NaClRefCountUnref(reinterpret_cast<struct NaClRefCount*>(service_));
254 5 : service_ = NULL;
255 15 : }
256 :
257 5 : bool ReverseService::Start(bool crash_report) {
258 5 : return NACL_VTBL(NaClReverseService, service_)->Start(
259 : service_, crash_report);
260 : }
261 :
262 : void ReverseService::WaitForServiceThreadsToExit() {
263 5 : NACL_VTBL(NaClReverseService, service_)->WaitForServiceThreadsToExit(
264 : service_);
265 5 : }
266 :
267 : void ReverseService::IncrThreadCount() {
268 0 : NACL_VTBL(NaClReverseService, service_)->ThreadCountIncr(service_);
269 0 : }
270 :
271 : void ReverseService::DecrThreadCount() {
272 0 : NACL_VTBL(NaClReverseService, service_)->ThreadCountDecr(service_);
273 0 : }
274 :
275 : } // namespace nacl
|