1 : /*
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.
5 : */
6 :
7 : #include "native_client/src/trusted/service_runtime/nacl_reverse_host_interface.h"
8 :
9 : #include "native_client/src/include/nacl_base.h"
10 :
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"
15 :
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"
23 :
24 :
25 : struct NaClRuntimeHostInterfaceVtbl const kNaClReverseHostInterfaceVtbl;
26 :
27 : int NaClReverseHostInterfaceCtor(
28 3 : struct NaClReverseHostInterface *self,
29 3 : struct NaClSecureService *server) {
30 3 : NaClLog(4, "NaClReverseHostInterfaceCtor:"
31 : "self 0x%"NACL_PRIxPTR", server 0x%"NACL_PRIxPTR"\n",
32 : (uintptr_t) self, (uintptr_t) server);
33 :
34 3 : if (!NaClRuntimeHostInterfaceCtor_protected(&self->base)) {
35 0 : NaClLog(3, "NaClReverseHostInterfaceCtor: "
36 : "NaClRuntimeHostInterfaceCtor base class ctor failed\n");
37 0 : return 0;
38 : }
39 : self->server = (struct NaClSecureService *)
40 3 : NaClRefCountRef((struct NaClRefCount *) server);
41 3 : NACL_VTBL(NaClRefCount, self) =
42 : (struct NaClRefCountVtbl const *) &kNaClReverseHostInterfaceVtbl;
43 3 : return 1;
44 3 : }
45 :
46 0 : void NaClReverseHostInterfaceDtor(struct NaClRefCount *vself) {
47 0 : struct NaClReverseHostInterface *self =
48 : (struct NaClReverseHostInterface *) vself;
49 :
50 0 : NaClRefCountUnref((struct NaClRefCount *) self->server);
51 :
52 0 : NACL_VTBL(NaClRefCount, self) = &kNaClRefCountVtbl;
53 0 : (*NACL_VTBL(NaClRefCount, self)->Dtor)(vself);
54 0 : }
55 :
56 : int NaClReverseHostInterfaceStartupInitializationComplete(
57 0 : struct NaClRuntimeHostInterface *vself) {
58 0 : struct NaClReverseHostInterface *self =
59 : (struct NaClReverseHostInterface *) vself;
60 0 : NaClSrpcError rpc_result;
61 0 : int status = 0;
62 :
63 0 : NaClLog(3,
64 : ("NaClReverseHostInterfaceStartupInitializationComplete(0x%08"
65 : NACL_PRIxPTR")\n"),
66 : (uintptr_t) self);
67 :
68 0 : NaClXMutexLock(&self->server->mu);
69 0 : if (NACL_REVERSE_CHANNEL_INITIALIZED ==
70 : self->server->reverse_channel_initialization_state) {
71 0 : rpc_result = NaClSrpcInvokeBySignature(&self->server->reverse_channel,
72 : NACL_REVERSE_CONTROL_INIT_DONE);
73 0 : if (NACL_SRPC_RESULT_OK != rpc_result) {
74 0 : NaClLog(LOG_FATAL,
75 : "NaClReverseHostInterfaceStartupInitializationComplete:"
76 : " RPC failed, result %d\n",
77 : rpc_result);
78 0 : }
79 0 : } else {
80 0 : NaClLog(4, "NaClReverseHostInterfaceStartupInitializationComplete:"
81 : " no reverse channel, no plugin to talk to.\n");
82 0 : status = -NACL_ABI_ENODEV;
83 : }
84 0 : NaClXMutexUnlock(&self->server->mu);
85 0 : return status;
86 : }
87 :
88 : int NaClReverseHostInterfaceReportExitStatus(
89 0 : struct NaClRuntimeHostInterface *vself,
90 0 : int exit_status) {
91 0 : struct NaClReverseHostInterface *self =
92 : (struct NaClReverseHostInterface *) vself;
93 0 : NaClSrpcError rpc_result;
94 0 : int status = 0;
95 :
96 0 : NaClLog(3,
97 : "NaClReverseHostInterfaceReportExitStatus:"
98 : " self 0x%08"NACL_PRIxPTR", exit_status 0x%x)\n",
99 : (uintptr_t) self, exit_status);
100 :
101 0 : NaClXMutexLock(&self->server->mu);
102 0 : if (NACL_REVERSE_CHANNEL_INITIALIZED ==
103 : self->server->reverse_channel_initialization_state) {
104 0 : rpc_result = NaClSrpcInvokeBySignature(&self->server->reverse_channel,
105 : NACL_REVERSE_CONTROL_REPORT_STATUS,
106 : exit_status);
107 0 : if (NACL_SRPC_RESULT_OK != rpc_result) {
108 0 : NaClLog(LOG_FATAL, "NaClReverseHostInterfaceReportExitStatus:"
109 : " RPC failed, result %d\n",
110 : rpc_result);
111 0 : }
112 0 : } else {
113 0 : NaClLog(4, "NaClReverseHostInterfaceReportExitStatus: no reverse channel"
114 : ", no plugin to talk to.\n");
115 0 : status = -NACL_ABI_ENODEV;
116 : }
117 0 : NaClXMutexUnlock(&self->server->mu);
118 0 : return status;
119 : }
120 :
121 : ssize_t NaClReverseHostInterfacePostMessage(
122 0 : struct NaClRuntimeHostInterface *vself,
123 0 : char const *message,
124 0 : size_t message_bytes) {
125 0 : struct NaClReverseHostInterface *self =
126 : (struct NaClReverseHostInterface *) vself;
127 0 : NaClSrpcError rpc_result;
128 0 : ssize_t num_written;
129 :
130 0 : NaClLog(3,
131 : ("NaClReverseHostInterfacePostMessage(0x%08"NACL_PRIxPTR", %s"
132 : ", %08"NACL_PRIuS")\n"),
133 : (uintptr_t) self, message, message_bytes);
134 :
135 0 : NaClXMutexLock(&self->server->mu);
136 0 : if (message_bytes > NACL_ABI_SIZE_T_MAX) {
137 0 : message_bytes = NACL_ABI_SIZE_T_MAX;
138 0 : }
139 0 : if (NACL_REVERSE_CHANNEL_INITIALIZED ==
140 : self->server->reverse_channel_initialization_state) {
141 0 : rpc_result = NaClSrpcInvokeBySignature(&self->server->reverse_channel,
142 : NACL_REVERSE_CONTROL_POST_MESSAGE,
143 : message_bytes,
144 : message,
145 : &num_written);
146 0 : if (NACL_SRPC_RESULT_OK != rpc_result) {
147 0 : NaClLog(LOG_FATAL,
148 : "NaClReverseHostInterfacePostMessage: RPC failed, result %d\n",
149 : rpc_result);
150 0 : }
151 0 : } else {
152 0 : NaClLog(4, "NaClReverseHostInterfacePostMessage: no reverse channel"
153 : ", no plugin to talk to.\n");
154 0 : num_written = -NACL_ABI_ENODEV;
155 : }
156 0 : NaClXMutexUnlock(&self->server->mu);
157 0 : return num_written;
158 : }
159 :
160 : int NaClReverseHostInterfaceCreateProcess(
161 1 : struct NaClRuntimeHostInterface *vself,
162 1 : struct NaClDesc **out_sock_addr,
163 1 : struct NaClDesc **out_app_addr) {
164 1 : struct NaClReverseHostInterface *self =
165 : (struct NaClReverseHostInterface *) vself;
166 1 : NaClSrpcError rpc_result;
167 1 : int pid = 0;
168 :
169 1 : NaClLog(3,
170 : ("NaClReverseHostInterfaceCreateProcess(0x%08"NACL_PRIxPTR
171 : ", 0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR")\n"),
172 : (uintptr_t) self,
173 : (uintptr_t) out_sock_addr,
174 : (uintptr_t) out_app_addr);
175 :
176 1 : NaClXMutexLock(&self->server->mu);
177 1 : if (NACL_REVERSE_CHANNEL_INITIALIZED ==
178 : self->server->reverse_channel_initialization_state) {
179 1 : rpc_result = NaClSrpcInvokeBySignature(
180 : &self->server->reverse_channel,
181 : NACL_REVERSE_CONTROL_CREATE_PROCESS_INTERLOCKED,
182 : out_sock_addr,
183 : out_app_addr,
184 : &pid);
185 1 : if (NACL_SRPC_RESULT_OK != rpc_result) {
186 0 : NaClLog(LOG_FATAL,
187 : "NaClReverseHostInterfaceCreateProcess: RPC failed, result %d\n",
188 : rpc_result);
189 0 : }
190 1 : } else {
191 0 : NaClLog(4, "NaClReverseHostInterfaceCreateProcess: no reverse channel"
192 : ", no plugin to talk to.\n");
193 0 : pid = -NACL_ABI_ENODEV;
194 : }
195 1 : NaClXMutexUnlock(&self->server->mu);
196 1 : return pid;
197 : }
198 :
199 : struct NaClRuntimeHostInterfaceVtbl const kNaClReverseHostInterfaceVtbl = {
200 : {
201 : NaClReverseHostInterfaceDtor,
202 : },
203 : NaClReverseHostInterfaceStartupInitializationComplete,
204 : NaClReverseHostInterfaceReportExitStatus,
205 : NaClReverseHostInterfacePostMessage,
206 : NaClReverseHostInterfaceCreateProcess,
207 : };
|