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 : /*
8 : * NaCl Service Runtime. I/O Descriptor / Handle abstraction.
9 : * Bound IMC descriptors.
10 : */
11 :
12 : #include <stdlib.h>
13 : #include <string.h>
14 : #include <errno.h>
15 :
16 : #include "native_client/src/include/portability.h"
17 : #include "native_client/src/shared/imc/nacl_imc_c.h"
18 : #include "native_client/src/shared/platform/nacl_log.h"
19 :
20 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
21 : #include "native_client/src/trusted/desc/nacl_desc_imc.h"
22 : #include "native_client/src/trusted/desc/nacl_desc_imc_bound_desc.h"
23 :
24 : #include "native_client/src/trusted/service_runtime/nacl_config.h"
25 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
26 : #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
27 :
28 :
29 : static struct NaClDescVtbl const kNaClDescImcBoundDescVtbl; /* fwd */
30 :
31 : int NaClDescImcBoundDescCtor(struct NaClDescImcBoundDesc *self,
32 2 : NaClHandle h) {
33 2 : struct NaClDesc *basep = (struct NaClDesc *) self;
34 :
35 2 : basep->base.vtbl = (struct NaClRefCountVtbl const *) NULL;
36 2 : if (!NaClDescCtor(basep)) {
37 0 : return 0;
38 : }
39 2 : self->h = h;
40 : basep->base.vtbl = (struct NaClRefCountVtbl const *)
41 2 : &kNaClDescImcBoundDescVtbl;
42 2 : return 1;
43 2 : }
44 :
45 0 : static void NaClDescImcBoundDescDtor(struct NaClRefCount *vself) {
46 0 : struct NaClDescImcBoundDesc *self = (struct NaClDescImcBoundDesc *) vself;
47 :
48 0 : (void) NaClClose(self->h);
49 0 : self->h = NACL_INVALID_HANDLE;
50 0 : vself->vtbl = (struct NaClRefCountVtbl const *) &kNaClDescVtbl;
51 0 : (*vself->vtbl->Dtor)(vself);
52 : return;
53 0 : }
54 :
55 : static int NaClDescImcBoundDescFstat(struct NaClDesc *vself,
56 0 : struct nacl_abi_stat *statbuf) {
57 : UNREFERENCED_PARAMETER(vself);
58 :
59 0 : memset(statbuf, 0, sizeof *statbuf);
60 0 : statbuf->nacl_abi_st_mode = NACL_ABI_S_IFBOUNDSOCK;
61 0 : return 0;
62 0 : }
63 :
64 : static int NaClDescImcBoundDescAcceptConn(struct NaClDesc *vself,
65 2 : struct NaClDesc **result) {
66 : /*
67 : * See NaClDescConnCapConnectAddr code in nacl_desc_conn_cap.c
68 : */
69 : struct NaClDescImcBoundDesc *self;
70 : int retval;
71 : NaClHandle nh;
72 : int nbytes;
73 : struct NaClMessageHeader conn_msg;
74 : struct NaClDescImcDesc *peer;
75 :
76 2 : self = (struct NaClDescImcBoundDesc *) vself;
77 :
78 2 : if (NULL == (peer = malloc(sizeof *peer))) {
79 0 : return -NACL_ABI_ENOMEM;
80 : }
81 :
82 2 : conn_msg.iov = 0;
83 2 : conn_msg.iov_length = 0;
84 2 : conn_msg.handle_count = 1;
85 2 : conn_msg.handles = &nh;
86 2 : conn_msg.flags = 0;
87 2 : nh = NACL_INVALID_HANDLE;
88 :
89 : NaClLog(3,
90 : ("NaClDescImcBoundDescAcceptConn(0x%08"NACL_PRIxPTR"):"
91 : " h = %d\n"),
92 : (uintptr_t) vself,
93 2 : self->h);
94 :
95 2 : if (-1 == (nbytes = NaClReceiveDatagram(self->h, &conn_msg, 0))) {
96 : NaClLog(LOG_ERROR,
97 : ("NaClDescImcBoundDescAcceptConn:"
98 : " could not receive connection message, errno %d\n"),
99 0 : errno);
100 0 : retval = -NACL_ABI_EMFILE;
101 0 : goto cleanup;
102 : }
103 2 : if (0 != nbytes) {
104 : NaClLog(LOG_ERROR, ("NaClDescImcBoundDescAcceptConn:"
105 0 : " connection message contains data?!?\n"));
106 0 : retval = -NACL_ABI_EMFILE; /* TODO(bsy): better errno? */
107 0 : goto cleanup;
108 : }
109 2 : if (1 != conn_msg.handle_count) {
110 : NaClLog(LOG_ERROR, ("NaClDescImcBoundDescAcceptConn: connection"
111 : " message contains %"NACL_PRIdS" descriptors?!?\n"),
112 0 : conn_msg.handle_count);
113 0 : retval = -NACL_ABI_EMFILE; /* TODO(bsy): better errno? */
114 0 : goto cleanup;
115 : }
116 2 : if (!NaClDescImcDescCtor(peer, nh)) {
117 0 : retval = -NACL_ABI_EMFILE;
118 0 : goto cleanup;
119 : }
120 2 : nh = NACL_INVALID_HANDLE;
121 :
122 2 : *result = (struct NaClDesc *) peer;
123 2 : retval = 0;
124 :
125 : cleanup:
126 2 : if (retval < 0) {
127 0 : if (NACL_INVALID_HANDLE != nh) {
128 0 : (void) NaClClose(nh);
129 0 : nh = NACL_INVALID_HANDLE;
130 : }
131 0 : free(peer);
132 : }
133 2 : return retval;
134 2 : }
135 :
136 : static struct NaClDescVtbl const kNaClDescImcBoundDescVtbl = {
137 : {
138 : NaClDescImcBoundDescDtor,
139 : },
140 : NaClDescMapNotImplemented,
141 : NACL_DESC_UNMAP_NOT_IMPLEMENTED
142 : NaClDescReadNotImplemented,
143 : NaClDescWriteNotImplemented,
144 : NaClDescSeekNotImplemented,
145 : NaClDescPReadNotImplemented,
146 : NaClDescPWriteNotImplemented,
147 : NaClDescImcBoundDescFstat,
148 : NaClDescGetdentsNotImplemented,
149 : NaClDescExternalizeSizeNotImplemented,
150 : NaClDescExternalizeNotImplemented,
151 : NaClDescLockNotImplemented,
152 : NaClDescTryLockNotImplemented,
153 : NaClDescUnlockNotImplemented,
154 : NaClDescWaitNotImplemented,
155 : NaClDescTimedWaitAbsNotImplemented,
156 : NaClDescSignalNotImplemented,
157 : NaClDescBroadcastNotImplemented,
158 : NaClDescSendMsgNotImplemented,
159 : NaClDescRecvMsgNotImplemented,
160 : NaClDescLowLevelSendMsgNotImplemented,
161 : NaClDescLowLevelRecvMsgNotImplemented,
162 : NaClDescConnectAddrNotImplemented,
163 : NaClDescImcBoundDescAcceptConn,
164 : NaClDescPostNotImplemented,
165 : NaClDescSemWaitNotImplemented,
166 : NaClDescGetValueNotImplemented,
167 : NaClDescSetMetadata,
168 : NaClDescGetMetadata,
169 : NaClDescSetFlags,
170 : NaClDescGetFlags,
171 : NaClDescIsattyNotImplemented,
172 : NACL_DESC_BOUND_SOCKET,
173 : };
|