2 * Copyright (c) 2013 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.
7 #include "native_client/src/trusted/service_runtime/nacl_reverse_host_interface.h"
9 #include "native_client/src/include/nacl_base.h"
11 #include "native_client/src/shared/platform/nacl_log.h"
12 #include "native_client/src/shared/platform/nacl_sync.h"
13 #include "native_client/src/shared/platform/nacl_sync_checked.h"
14 #include "native_client/src/shared/srpc/nacl_srpc.h"
16 #include "native_client/src/trusted/desc/nacl_desc_base.h"
17 #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
18 #include "native_client/src/trusted/nacl_base/nacl_refcount.h"
19 #include "native_client/src/trusted/reverse_service/reverse_control_rpc.h"
20 #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
21 #include "native_client/src/trusted/service_runtime/nacl_runtime_host_interface.h"
22 #include "native_client/src/trusted/service_runtime/nacl_secure_service.h"
25 struct NaClRuntimeHostInterfaceVtbl const kNaClReverseHostInterfaceVtbl;
27 int NaClReverseHostInterfaceCtor(
28 struct NaClReverseHostInterface *self,
29 struct NaClSecureService *server) {
30 NaClLog(4, "NaClReverseHostInterfaceCtor:"
31 "self 0x%"NACL_PRIxPTR", server 0x%"NACL_PRIxPTR"\n",
32 (uintptr_t) self, (uintptr_t) server);
34 if (!NaClRuntimeHostInterfaceCtor_protected(&self->base)) {
35 NaClLog(3, "NaClReverseHostInterfaceCtor: "
36 "NaClRuntimeHostInterfaceCtor base class ctor failed\n");
39 self->server = (struct NaClSecureService *)
40 NaClRefCountRef((struct NaClRefCount *) server);
41 NACL_VTBL(NaClRefCount, self) =
42 (struct NaClRefCountVtbl const *) &kNaClReverseHostInterfaceVtbl;
46 void NaClReverseHostInterfaceDtor(struct NaClRefCount *vself) {
47 struct NaClReverseHostInterface *self =
48 (struct NaClReverseHostInterface *) vself;
50 NaClRefCountUnref((struct NaClRefCount *) self->server);
52 NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl;
53 (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
56 int NaClReverseHostInterfaceLog(
57 struct NaClRuntimeHostInterface *vself,
58 char const *message) {
59 struct NaClReverseHostInterface *self =
60 (struct NaClReverseHostInterface *) vself;
61 NaClSrpcError rpc_result;
65 "NaClReverseHostInterfaceLog(0x%08"NACL_PRIxPTR", %s)\n",
66 (uintptr_t) self, message);
68 NaClXMutexLock(&self->server->mu);
69 if (NACL_REVERSE_CHANNEL_INITIALIZED ==
70 self->server->reverse_channel_initialization_state) {
71 rpc_result = NaClSrpcInvokeBySignature(&self->server->reverse_channel,
72 NACL_REVERSE_CONTROL_LOG,
74 if (NACL_SRPC_RESULT_OK != rpc_result) {
76 "NaClReverseHostInterfaceLog: RPC failed, result %d\n",
80 NaClLog(4, "NaClReverseHostInterfaceLog: no reverse channel"
81 ", no plugin to talk to.\n");
82 status = -NACL_ABI_ENODEV;
84 NaClXMutexUnlock(&self->server->mu);
88 int NaClReverseHostInterfaceStartupInitializationComplete(
89 struct NaClRuntimeHostInterface *vself) {
90 struct NaClReverseHostInterface *self =
91 (struct NaClReverseHostInterface *) vself;
92 NaClSrpcError rpc_result;
96 ("NaClReverseHostInterfaceStartupInitializationComplete(0x%08"
100 NaClXMutexLock(&self->server->mu);
101 if (NACL_REVERSE_CHANNEL_INITIALIZED ==
102 self->server->reverse_channel_initialization_state) {
103 rpc_result = NaClSrpcInvokeBySignature(&self->server->reverse_channel,
104 NACL_REVERSE_CONTROL_INIT_DONE);
105 if (NACL_SRPC_RESULT_OK != rpc_result) {
107 "NaClReverseHostInterfaceStartupInitializationComplete:"
108 " RPC failed, result %d\n",
112 NaClLog(4, "NaClReverseHostInterfaceStartupInitializationComplete:"
113 " no reverse channel, no plugin to talk to.\n");
114 status = -NACL_ABI_ENODEV;
116 NaClXMutexUnlock(&self->server->mu);
120 int NaClReverseHostInterfaceReportExitStatus(
121 struct NaClRuntimeHostInterface *vself,
123 struct NaClReverseHostInterface *self =
124 (struct NaClReverseHostInterface *) vself;
125 NaClSrpcError rpc_result;
129 "NaClReverseHostInterfaceReportExitStatus:"
130 " self 0x%08"NACL_PRIxPTR", exit_status 0x%x)\n",
131 (uintptr_t) self, exit_status);
133 NaClXMutexLock(&self->server->mu);
134 if (NACL_REVERSE_CHANNEL_INITIALIZED ==
135 self->server->reverse_channel_initialization_state) {
136 rpc_result = NaClSrpcInvokeBySignature(&self->server->reverse_channel,
137 NACL_REVERSE_CONTROL_REPORT_STATUS,
139 if (NACL_SRPC_RESULT_OK != rpc_result) {
140 NaClLog(LOG_FATAL, "NaClReverseHostInterfaceReportExitStatus:"
141 " RPC failed, result %d\n",
145 NaClLog(4, "NaClReverseHostInterfaceReportExitStatus: no reverse channel"
146 ", no plugin to talk to.\n");
147 status = -NACL_ABI_ENODEV;
149 NaClXMutexUnlock(&self->server->mu);
153 ssize_t NaClReverseHostInterfacePostMessage(
154 struct NaClRuntimeHostInterface *vself,
156 size_t message_bytes) {
157 struct NaClReverseHostInterface *self =
158 (struct NaClReverseHostInterface *) vself;
159 NaClSrpcError rpc_result;
163 ("NaClReverseHostInterfacePostMessage(0x%08"NACL_PRIxPTR", %s"
164 ", %08"NACL_PRIdS")\n"),
165 (uintptr_t) self, message, message_bytes);
167 NaClXMutexLock(&self->server->mu);
168 if (message_bytes > NACL_ABI_SIZE_T_MAX) {
169 message_bytes = NACL_ABI_SIZE_T_MAX;
171 if (NACL_REVERSE_CHANNEL_INITIALIZED ==
172 self->server->reverse_channel_initialization_state) {
173 rpc_result = NaClSrpcInvokeBySignature(&self->server->reverse_channel,
174 NACL_REVERSE_CONTROL_POST_MESSAGE,
178 if (NACL_SRPC_RESULT_OK != rpc_result) {
180 "NaClReverseHostInterfacePostMessage: RPC failed, result %d\n",
184 NaClLog(4, "NaClReverseHostInterfacePostMessage: no reverse channel"
185 ", no plugin to talk to.\n");
186 num_written = -NACL_ABI_ENODEV;
188 NaClXMutexUnlock(&self->server->mu);
192 int NaClReverseHostInterfaceCreateProcess(
193 struct NaClRuntimeHostInterface *vself,
194 struct NaClDesc **out_sock_addr,
195 struct NaClDesc **out_app_addr) {
196 struct NaClReverseHostInterface *self =
197 (struct NaClReverseHostInterface *) vself;
198 NaClSrpcError rpc_result;
202 ("NaClReverseHostInterfaceCreateProcess(0x%08"NACL_PRIxPTR
203 ", 0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR")\n"),
205 (uintptr_t) out_sock_addr,
206 (uintptr_t) out_app_addr);
208 NaClXMutexLock(&self->server->mu);
209 if (NACL_REVERSE_CHANNEL_INITIALIZED ==
210 self->server->reverse_channel_initialization_state) {
211 rpc_result = NaClSrpcInvokeBySignature(
212 &self->server->reverse_channel,
213 NACL_REVERSE_CONTROL_CREATE_PROCESS_INTERLOCKED,
217 if (NACL_SRPC_RESULT_OK != rpc_result) {
219 "NaClReverseHostInterfaceCreateProcess: RPC failed, result %d\n",
223 NaClLog(4, "NaClReverseHostInterfaceCreateProcess: no reverse channel"
224 ", no plugin to talk to.\n");
225 pid = -NACL_ABI_ENODEV;
227 NaClXMutexUnlock(&self->server->mu);
231 struct NaClRuntimeHostInterfaceVtbl const kNaClReverseHostInterfaceVtbl = {
233 NaClReverseHostInterfaceDtor,
235 NaClReverseHostInterfaceLog,
236 NaClReverseHostInterfaceStartupInitializationComplete,
237 NaClReverseHostInterfaceReportExitStatus,
238 NaClReverseHostInterfacePostMessage,
239 NaClReverseHostInterfaceCreateProcess,