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