1 : /*
2 : * Copyright 2008 The Native Client Authors. All rights reserved.
3 : * Use of this source code is governed by a BSD-style license that can
4 : * be found in the LICENSE file.
5 : */
6 :
7 : /*
8 : * NaCl Service Runtime. I/O Descriptor / Handle abstraction. Memory
9 : * mapping using descriptors.
10 : */
11 :
12 : #include <stdlib.h>
13 : #include <string.h>
14 : #include <sys/types.h>
15 : #include <sys/stat.h>
16 :
17 : #include "native_client/src/include/portability.h"
18 : #include "native_client/src/include/nacl_platform.h"
19 :
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_checked.h"
23 :
24 : #if NACL_LINUX
25 : #include "native_client/src/trusted/desc/linux/nacl_desc_sysv_shm.h"
26 : #endif /* NACL_LINUX */
27 : #include "native_client/src/trusted/desc/nacl_desc_base.h"
28 : #include "native_client/src/trusted/desc/nacl_desc_cond.h"
29 : #include "native_client/src/trusted/desc/nacl_desc_conn_cap.h"
30 : #include "native_client/src/trusted/desc/nacl_desc_dir.h"
31 : #include "native_client/src/trusted/desc/nacl_desc_imc.h"
32 : #include "native_client/src/trusted/desc/nacl_desc_imc_bound_desc.h"
33 : #include "native_client/src/trusted/desc/nacl_desc_imc_shm.h"
34 : #include "native_client/src/trusted/desc/nacl_desc_invalid.h"
35 : #include "native_client/src/trusted/desc/nacl_desc_io.h"
36 : #include "native_client/src/trusted/desc/nacl_desc_mutex.h"
37 : #include "native_client/src/trusted/desc/nacl_desc_rng.h"
38 : #include "native_client/src/trusted/desc/nacl_desc_quota.h"
39 : #include "native_client/src/trusted/desc/nacl_desc_sync_socket.h"
40 :
41 : #include "native_client/src/trusted/nacl_base/nacl_refcount.h"
42 :
43 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
44 : #include "native_client/src/trusted/service_runtime/include/sys/mman.h"
45 : #include "native_client/src/trusted/service_runtime/include/sys/stat.h"
46 : #include "native_client/src/trusted/service_runtime/nacl_config.h"
47 : #include "native_client/src/trusted/service_runtime/sel_util.h"
48 :
49 : /*
50 : * This file contains base class code for NaClDesc.
51 : *
52 : * The implementation for following subclasses are elsewhere, but here
53 : * is an enumeration of them with a brief description:
54 : *
55 : * NaClDescIoDesc is the subclass that wraps host-OS descriptors
56 : * provided by NaClHostDesc (which gives an OS-independent abstraction
57 : * for host-OS descriptors).
58 : *
59 : * NaClDescImcDesc is the subclass that wraps IMC descriptors.
60 : *
61 : * NaClDescMutex and NaClDescCondVar are the subclasses that
62 : * wrap the non-transferrable synchronization objects.
63 : *
64 : * These NaClDesc objects are impure in that they know about the
65 : * virtual memory subsystem restriction of requiring mappings to occur
66 : * in NACL_MAP_PAGESIZE (64KB) chunks, so the Map and Unmap virtual
67 : * functions, at least, will enforce this restriction.
68 : */
69 :
70 : /*
71 : * TODO(bsy): remove when we put SIZE_T_MAX in a common header file.
72 : */
73 : #if !defined(SIZE_T_MAX)
74 : # define SIZE_T_MAX ((size_t) -1)
75 : #endif
76 :
77 315 : int NaClDescCtor(struct NaClDesc *ndp) {
78 : /* this should be a compile-time test */
79 : if (0 != (sizeof(struct NaClInternalHeader) & 0xf)) {
80 : NaClLog(LOG_FATAL,
81 : "Internal error. NaClInternalHeader size not a"
82 : " multiple of 16\n");
83 : }
84 315 : return NaClRefCountCtor(&ndp->base);
85 : }
86 :
87 155 : static void NaClDescDtor(struct NaClRefCount *nrcp) {
88 155 : nrcp->vtbl = &kNaClRefCountVtbl;
89 155 : (*nrcp->vtbl->Dtor)(nrcp);
90 155 : }
91 :
92 1350 : struct NaClDesc *NaClDescRef(struct NaClDesc *ndp) {
93 1350 : return (struct NaClDesc *) NaClRefCountRef(&ndp->base);
94 : }
95 :
96 306 : void NaClDescUnref(struct NaClDesc *ndp) {
97 306 : NaClRefCountUnref(&ndp->base);
98 306 : }
99 :
100 167 : void NaClDescSafeUnref(struct NaClDesc *ndp) {
101 167 : if (NULL != ndp) {
102 109 : NaClRefCountUnref(&ndp->base);
103 : }
104 167 : }
105 :
106 : int (*NaClDescInternalize[NACL_DESC_TYPE_MAX])(
107 : struct NaClDesc **,
108 : struct NaClDescXferState *,
109 : struct NaClDescQuotaInterface *) = {
110 : NaClDescInvalidInternalize,
111 : NaClDescDirInternalize,
112 : NaClDescIoInternalize,
113 : #if NACL_WINDOWS
114 : NaClDescConnCapInternalize,
115 : NaClDescInternalizeNotImplemented,
116 : #else
117 : NaClDescInternalizeNotImplemented,
118 : NaClDescConnCapFdInternalize,
119 : #endif
120 : NaClDescInternalizeNotImplemented, /* bound sockets cannot be transferred */
121 : NaClDescInternalizeNotImplemented, /* connected abstract base class */
122 : NaClDescImcShmInternalize,
123 : #if NACL_LINUX
124 : NaClDescSysvShmInternalize,
125 : #else
126 : NULL,
127 : #endif /* NACL_LINUX */
128 : NaClDescInternalizeNotImplemented, /* mutex */
129 : NaClDescInternalizeNotImplemented, /* condvar */
130 : NaClDescInternalizeNotImplemented, /* semaphore */
131 : NaClDescSyncSocketInternalize,
132 : NaClDescXferableDataDescInternalize,
133 : NaClDescInternalizeNotImplemented, /* imc socket */
134 : NaClDescQuotaInternalize, /* quota wrapper */
135 : NaClDescRngInternalize, /* device: rng */
136 : NaClDescInternalizeNotImplemented /* device: postmessage */
137 : };
138 :
139 2 : char const *NaClDescTypeString(enum NaClDescTypeTag type_tag) {
140 : /* default functions for the vtable - return NOT_IMPLEMENTED */
141 2 : switch (type_tag) {
142 : #define MAP(E) case E: do { return #E; } while (0)
143 0 : MAP(NACL_DESC_INVALID);
144 0 : MAP(NACL_DESC_DIR);
145 0 : MAP(NACL_DESC_HOST_IO);
146 0 : MAP(NACL_DESC_CONN_CAP);
147 0 : MAP(NACL_DESC_CONN_CAP_FD);
148 0 : MAP(NACL_DESC_BOUND_SOCKET);
149 0 : MAP(NACL_DESC_CONNECTED_SOCKET);
150 0 : MAP(NACL_DESC_SHM);
151 0 : MAP(NACL_DESC_SYSV_SHM);
152 0 : MAP(NACL_DESC_MUTEX);
153 0 : MAP(NACL_DESC_CONDVAR);
154 0 : MAP(NACL_DESC_SEMAPHORE);
155 0 : MAP(NACL_DESC_SYNC_SOCKET);
156 0 : MAP(NACL_DESC_TRANSFERABLE_DATA_SOCKET);
157 2 : MAP(NACL_DESC_IMC_SOCKET);
158 0 : MAP(NACL_DESC_QUOTA);
159 0 : MAP(NACL_DESC_DEVICE_RNG);
160 0 : MAP(NACL_DESC_DEVICE_POSTMESSAGE);
161 : }
162 0 : return "BAD TYPE TAG";
163 : }
164 :
165 :
166 0 : void NaClDescDtorNotImplemented(struct NaClRefCount *vself) {
167 : UNREFERENCED_PARAMETER(vself);
168 :
169 0 : NaClLog(LOG_FATAL, "Must implement a destructor!\n");
170 0 : }
171 :
172 : uintptr_t NaClDescMapNotImplemented(struct NaClDesc *vself,
173 : struct NaClDescEffector *effp,
174 : void *start_addr,
175 : size_t len,
176 : int prot,
177 : int flags,
178 0 : nacl_off64_t offset) {
179 : UNREFERENCED_PARAMETER(effp);
180 : UNREFERENCED_PARAMETER(start_addr);
181 : UNREFERENCED_PARAMETER(len);
182 : UNREFERENCED_PARAMETER(prot);
183 : UNREFERENCED_PARAMETER(flags);
184 : UNREFERENCED_PARAMETER(offset);
185 :
186 0 : NaClLog(LOG_ERROR,
187 : "Map method is not implemented for object of type %s\n",
188 : NaClDescTypeString(((struct NaClDescVtbl const *)
189 : vself->base.vtbl)->typeTag));
190 0 : return -NACL_ABI_EINVAL;
191 : }
192 :
193 : int NaClDescUnmapUnsafeNotImplemented(struct NaClDesc *vself,
194 : struct NaClDescEffector *effp,
195 : void *start_addr,
196 0 : size_t len) {
197 : UNREFERENCED_PARAMETER(effp);
198 : UNREFERENCED_PARAMETER(start_addr);
199 : UNREFERENCED_PARAMETER(len);
200 :
201 0 : NaClLog(LOG_ERROR,
202 : "Map method is not implemented for object of type %s\n",
203 : NaClDescTypeString(((struct NaClDescVtbl const *)
204 : vself->base.vtbl)->typeTag));
205 0 : return -NACL_ABI_EINVAL;
206 : }
207 :
208 : int NaClDescUnmapNotImplemented(struct NaClDesc *vself,
209 : struct NaClDescEffector *effp,
210 : void *start_addr,
211 0 : size_t len) {
212 : UNREFERENCED_PARAMETER(effp);
213 : UNREFERENCED_PARAMETER(start_addr);
214 : UNREFERENCED_PARAMETER(len);
215 :
216 0 : NaClLog(LOG_ERROR,
217 : "Unmap method is not implemented for object of type %s\n",
218 : NaClDescTypeString(((struct NaClDescVtbl const *)
219 : vself->base.vtbl)->typeTag));
220 0 : return -NACL_ABI_EINVAL;
221 : }
222 :
223 : ssize_t NaClDescReadNotImplemented(struct NaClDesc *vself,
224 : void *buf,
225 0 : size_t len) {
226 : UNREFERENCED_PARAMETER(buf);
227 : UNREFERENCED_PARAMETER(len);
228 :
229 0 : NaClLog(LOG_ERROR,
230 : "Read method is not implemented for object of type %s\n",
231 : NaClDescTypeString(((struct NaClDescVtbl const *)
232 : vself->base.vtbl)->typeTag));
233 0 : return -NACL_ABI_EINVAL;
234 : }
235 :
236 : ssize_t NaClDescWriteNotImplemented(struct NaClDesc *vself,
237 : void const *buf,
238 0 : size_t len) {
239 : UNREFERENCED_PARAMETER(buf);
240 : UNREFERENCED_PARAMETER(len);
241 :
242 0 : NaClLog(LOG_ERROR,
243 : "Write method is not implemented for object of type %s\n",
244 : NaClDescTypeString(((struct NaClDescVtbl const *)
245 : vself->base.vtbl)->typeTag));
246 0 : return -NACL_ABI_EINVAL;
247 : }
248 :
249 : nacl_off64_t NaClDescSeekNotImplemented(struct NaClDesc *vself,
250 : nacl_off64_t offset,
251 0 : int whence) {
252 : UNREFERENCED_PARAMETER(offset);
253 : UNREFERENCED_PARAMETER(whence);
254 :
255 0 : NaClLog(LOG_ERROR,
256 : "Seek method is not implemented for object of type %s\n",
257 : NaClDescTypeString(((struct NaClDescVtbl const *)
258 : vself->base.vtbl)->typeTag));
259 0 : return -NACL_ABI_EINVAL;
260 : }
261 :
262 : int NaClDescIoctlNotImplemented(struct NaClDesc *vself,
263 : int request,
264 0 : void *arg) {
265 : UNREFERENCED_PARAMETER(request);
266 : UNREFERENCED_PARAMETER(arg);
267 :
268 0 : NaClLog(LOG_ERROR,
269 : "Ioctl method is not implemented for object of type %s\n",
270 : NaClDescTypeString(((struct NaClDescVtbl const *)
271 : vself->base.vtbl)->typeTag));
272 0 : return -NACL_ABI_EINVAL;
273 : }
274 :
275 : int NaClDescFstatNotImplemented(struct NaClDesc *vself,
276 0 : struct nacl_abi_stat *statbuf) {
277 : UNREFERENCED_PARAMETER(statbuf);
278 :
279 0 : NaClLog(LOG_ERROR,
280 : "Fstat method is not implemented for object of type %s\n",
281 : NaClDescTypeString(((struct NaClDescVtbl const *)
282 : vself->base.vtbl)->typeTag));
283 0 : return -NACL_ABI_EINVAL;
284 : }
285 :
286 : ssize_t NaClDescGetdentsNotImplemented(struct NaClDesc *vself,
287 : void *dirp,
288 0 : size_t count) {
289 : UNREFERENCED_PARAMETER(dirp);
290 : UNREFERENCED_PARAMETER(count);
291 :
292 0 : NaClLog(LOG_ERROR,
293 : "Getdents method is not implemented for object of type %s\n",
294 : NaClDescTypeString(((struct NaClDescVtbl const *)
295 : vself->base.vtbl)->typeTag));
296 0 : return -NACL_ABI_EINVAL;
297 : }
298 :
299 : int NaClDescExternalizeSizeNotImplemented(struct NaClDesc *vself,
300 : size_t *nbytes,
301 0 : size_t *nhandles) {
302 : UNREFERENCED_PARAMETER(nbytes);
303 : UNREFERENCED_PARAMETER(nhandles);
304 :
305 0 : NaClLog(LOG_ERROR,
306 : "ExternalizeSize method is not implemented for object of type %s\n",
307 : NaClDescTypeString(((struct NaClDescVtbl const *)
308 : vself->base.vtbl)->typeTag));
309 0 : return -NACL_ABI_EINVAL;
310 : }
311 :
312 : int NaClDescExternalizeNotImplemented(struct NaClDesc *vself,
313 0 : struct NaClDescXferState *xfer) {
314 : UNREFERENCED_PARAMETER(xfer);
315 :
316 0 : NaClLog(LOG_ERROR,
317 : "Externalize method is not implemented for object of type %s\n",
318 : NaClDescTypeString(((struct NaClDescVtbl const *)
319 : vself->base.vtbl)->typeTag));
320 0 : return -NACL_ABI_EINVAL;
321 : }
322 :
323 0 : int NaClDescLockNotImplemented(struct NaClDesc *vself) {
324 0 : NaClLog(LOG_ERROR,
325 : "Lock method is not implemented for object of type %s\n",
326 : NaClDescTypeString(((struct NaClDescVtbl const *)
327 : vself->base.vtbl)->typeTag));
328 0 : return -NACL_ABI_EINVAL;
329 : }
330 :
331 0 : int NaClDescTryLockNotImplemented(struct NaClDesc *vself) {
332 0 : NaClLog(LOG_ERROR,
333 : "TryLock method is not implemented for object of type %s\n",
334 : NaClDescTypeString(((struct NaClDescVtbl const *)
335 : vself->base.vtbl)->typeTag));
336 0 : return -NACL_ABI_EINVAL;
337 : }
338 :
339 0 : int NaClDescUnlockNotImplemented(struct NaClDesc *vself) {
340 0 : NaClLog(LOG_ERROR,
341 : "Unlock method is not implemented for object of type %s\n",
342 : NaClDescTypeString(((struct NaClDescVtbl const *)
343 : vself->base.vtbl)->typeTag));
344 0 : return -NACL_ABI_EINVAL;
345 : }
346 :
347 : int NaClDescWaitNotImplemented(struct NaClDesc *vself,
348 0 : struct NaClDesc *mutex) {
349 : UNREFERENCED_PARAMETER(mutex);
350 :
351 0 : NaClLog(LOG_ERROR,
352 : "Wait method is not implemented for object of type %s\n",
353 : NaClDescTypeString(((struct NaClDescVtbl const *)
354 : vself->base.vtbl)->typeTag));
355 0 : return -NACL_ABI_EINVAL;
356 : }
357 :
358 : int NaClDescTimedWaitAbsNotImplemented(struct NaClDesc *vself,
359 : struct NaClDesc *mutex,
360 0 : struct nacl_abi_timespec const *ts) {
361 : UNREFERENCED_PARAMETER(mutex);
362 : UNREFERENCED_PARAMETER(ts);
363 :
364 0 : NaClLog(LOG_ERROR,
365 : "TimedWaitAbs method is not implemented for object of type %s\n",
366 : NaClDescTypeString(((struct NaClDescVtbl const *)
367 : vself->base.vtbl)->typeTag));
368 0 : return -NACL_ABI_EINVAL;
369 : }
370 :
371 0 : int NaClDescSignalNotImplemented(struct NaClDesc *vself) {
372 0 : NaClLog(LOG_ERROR,
373 : "Signal method is not implemented for object of type %s\n",
374 : NaClDescTypeString(((struct NaClDescVtbl const *)
375 : vself->base.vtbl)->typeTag));
376 0 : return -NACL_ABI_EINVAL;
377 : }
378 :
379 0 : int NaClDescBroadcastNotImplemented(struct NaClDesc *vself) {
380 0 : NaClLog(LOG_ERROR,
381 : "Broadcast method is not implemented for object of type %s\n",
382 : NaClDescTypeString(((struct NaClDescVtbl const *)
383 : vself->base.vtbl)->typeTag));
384 0 : return -NACL_ABI_EINVAL;
385 : }
386 :
387 : ssize_t NaClDescSendMsgNotImplemented(struct NaClDesc *vself,
388 : struct NaClMessageHeader const *dgram,
389 0 : int flags) {
390 : UNREFERENCED_PARAMETER(dgram);
391 : UNREFERENCED_PARAMETER(flags);
392 :
393 0 : NaClLog(LOG_ERROR,
394 : "SendMsg method is not implemented for object of type %s\n",
395 : NaClDescTypeString(((struct NaClDescVtbl const *)
396 : vself->base.vtbl)->typeTag));
397 0 : return -NACL_ABI_EINVAL;
398 : }
399 :
400 : ssize_t NaClDescRecvMsgNotImplemented(struct NaClDesc *vself,
401 : struct NaClMessageHeader *dgram,
402 0 : int flags) {
403 : UNREFERENCED_PARAMETER(dgram);
404 : UNREFERENCED_PARAMETER(flags);
405 :
406 0 : NaClLog(LOG_ERROR,
407 : "RecvMsg method is not implemented for object of type %s\n",
408 : NaClDescTypeString(((struct NaClDescVtbl const *)
409 : vself->base.vtbl)->typeTag));
410 0 : return -NACL_ABI_EINVAL;
411 : }
412 :
413 : int NaClDescConnectAddrNotImplemented(struct NaClDesc *vself,
414 1 : struct NaClDesc **result) {
415 : UNREFERENCED_PARAMETER(result);
416 :
417 1 : NaClLog(LOG_ERROR,
418 : "ConnectAddr method is not implemented for object of type %s\n",
419 : NaClDescTypeString(((struct NaClDescVtbl const *)
420 : vself->base.vtbl)->typeTag));
421 1 : return -NACL_ABI_EINVAL;
422 : }
423 :
424 : int NaClDescAcceptConnNotImplemented(struct NaClDesc *vself,
425 1 : struct NaClDesc **result) {
426 : UNREFERENCED_PARAMETER(result);
427 :
428 1 : NaClLog(LOG_ERROR,
429 : "AcceptConn method is not implemented for object of type %s\n",
430 : NaClDescTypeString(((struct NaClDescVtbl const *)
431 : vself->base.vtbl)->typeTag));
432 1 : return -NACL_ABI_EINVAL;
433 : }
434 :
435 0 : int NaClDescPostNotImplemented(struct NaClDesc *vself) {
436 0 : NaClLog(LOG_ERROR,
437 : "Post method is not implemented for object of type %s\n",
438 : NaClDescTypeString(((struct NaClDescVtbl const *)
439 : vself->base.vtbl)->typeTag));
440 0 : return -NACL_ABI_EINVAL;
441 : }
442 :
443 0 : int NaClDescSemWaitNotImplemented(struct NaClDesc *vself) {
444 0 : NaClLog(LOG_ERROR,
445 : "SemWait method is not implemented for object of type %s\n",
446 : NaClDescTypeString(((struct NaClDescVtbl const *)
447 : vself->base.vtbl)->typeTag));
448 0 : return -NACL_ABI_EINVAL;
449 : }
450 :
451 0 : int NaClDescGetValueNotImplemented(struct NaClDesc *vself) {
452 0 : NaClLog(LOG_ERROR,
453 : "GetValue method is not implemented for object of type %s\n",
454 : NaClDescTypeString(((struct NaClDescVtbl const *)
455 : vself->base.vtbl)->typeTag));
456 0 : return -NACL_ABI_EINVAL;
457 : }
458 :
459 : int NaClDescInternalizeNotImplemented(
460 : struct NaClDesc **out_desc,
461 : struct NaClDescXferState *xfer,
462 0 : struct NaClDescQuotaInterface *quota_interface) {
463 : UNREFERENCED_PARAMETER(out_desc);
464 : UNREFERENCED_PARAMETER(xfer);
465 : UNREFERENCED_PARAMETER(quota_interface);
466 :
467 0 : NaClLog(LOG_ERROR,
468 : "Attempted transfer of non-transferable descriptor\n");
469 0 : return -NACL_ABI_EIO;
470 : }
471 :
472 : int NaClDescMapDescriptor(struct NaClDesc *desc,
473 : struct NaClDescEffector *effector,
474 : void **addr,
475 0 : size_t *size) {
476 : struct nacl_abi_stat st;
477 0 : size_t rounded_size = 0;
478 0 : const int kMaxTries = 10;
479 0 : int tries = 0;
480 0 : void *map_addr = NULL;
481 : int rval;
482 : uintptr_t rval_ptr;
483 :
484 0 : *addr = NULL;
485 0 : *size = 0;
486 :
487 0 : rval = (*((struct NaClDescVtbl const *) desc->base.vtbl)->Fstat)(desc, &st);
488 0 : if (0 != rval) {
489 : /* Failed to get the size - return failure. */
490 0 : return rval;
491 : }
492 :
493 : /*
494 : * on sane systems, sizef(size_t) <= sizeof(nacl_abi_off_t) must hold.
495 : */
496 0 : if (st.nacl_abi_st_size < 0) {
497 0 : return -NACL_ABI_ENOMEM;
498 : }
499 : if (sizeof(size_t) < sizeof(nacl_abi_off_t)) {
500 0 : if ((nacl_abi_off_t) SIZE_T_MAX < st.nacl_abi_st_size) {
501 0 : return -NACL_ABI_ENOMEM;
502 : }
503 : }
504 : /*
505 : * size_t and uintptr_t and void * should have the same number of
506 : * bits (well, void * could be smaller than uintptr_t, and on weird
507 : * architectures one could imagine the maximum size is smaller than
508 : * all addr bits, but we're talking sane architectures...).
509 : */
510 :
511 : /*
512 : * When probing by VirtualAlloc/mmap, use the same granularity
513 : * as the Map virtual function (64KB).
514 : */
515 0 : rounded_size = NaClRoundAllocPage((size_t) st.nacl_abi_st_size);
516 :
517 : /* Find an address range to map the object into. */
518 : do {
519 0 : ++tries;
520 : #if NACL_WINDOWS
521 : map_addr = VirtualAlloc(NULL, rounded_size, MEM_RESERVE, PAGE_READWRITE);
522 : if (NULL == map_addr ||!VirtualFree(map_addr, 0, MEM_RELEASE)) {
523 : continue;
524 : }
525 : #else
526 0 : map_addr = mmap(NULL,
527 : rounded_size,
528 : PROT_READ | PROT_WRITE,
529 : MAP_SHARED | MAP_ANONYMOUS,
530 : 0,
531 : 0);
532 0 : if (MAP_FAILED == map_addr || munmap(map_addr, rounded_size)) {
533 0 : map_addr = NULL;
534 0 : continue;
535 : }
536 : #endif
537 0 : NaClLog(4,
538 : "NaClDescMapDescriptor: mapping to address %"NACL_PRIxPTR"\n",
539 : (uintptr_t) map_addr);
540 0 : rval_ptr = (*((struct NaClDescVtbl const *)
541 : desc->base.vtbl)->Map)
542 : (desc,
543 : effector,
544 : map_addr,
545 : rounded_size,
546 : NACL_ABI_PROT_READ | NACL_ABI_PROT_WRITE,
547 : NACL_ABI_MAP_SHARED | NACL_ABI_MAP_FIXED,
548 : 0);
549 0 : NaClLog(4,
550 : "NaClDescMapDescriptor: result is %"NACL_PRIxPTR"\n",
551 : rval_ptr);
552 0 : if (NaClPtrIsNegErrno(&rval_ptr)) {
553 : /*
554 : * A nonzero return from NaClIsNegErrno
555 : * indicates that the value is within the range
556 : * reserved for errors, which is representable
557 : * with 32 bits.
558 : */
559 0 : rval = (int) rval_ptr;
560 : } else {
561 : /*
562 : * Map() did not return an error, so set our
563 : * return code to 0 (success)
564 : */
565 0 : rval = 0;
566 0 : map_addr = (void*) rval_ptr;
567 0 : break;
568 : }
569 :
570 0 : } while (NULL == map_addr && tries < kMaxTries);
571 :
572 0 : if (NULL == map_addr) {
573 0 : return rval;
574 : }
575 :
576 0 : *addr = map_addr;
577 0 : *size = rounded_size;
578 0 : return 0;
579 : }
580 :
581 92 : int NaClSafeCloseNaClHandle(NaClHandle h) {
582 92 : if (NACL_INVALID_HANDLE != h) {
583 0 : return NaClClose(h);
584 : }
585 92 : return 0;
586 : }
587 :
588 :
589 : struct NaClDescVtbl const kNaClDescVtbl = {
590 : {
591 : NaClDescDtor,
592 : },
593 : NaClDescMapNotImplemented,
594 : NaClDescUnmapUnsafeNotImplemented,
595 : NaClDescUnmapNotImplemented,
596 : NaClDescReadNotImplemented,
597 : NaClDescWriteNotImplemented,
598 : NaClDescSeekNotImplemented,
599 : NaClDescIoctlNotImplemented,
600 : NaClDescFstatNotImplemented,
601 : NaClDescGetdentsNotImplemented,
602 : (enum NaClDescTypeTag) -1, /* NaClDesc is an abstract base class */
603 : NaClDescExternalizeSizeNotImplemented,
604 : NaClDescExternalizeNotImplemented,
605 : NaClDescLockNotImplemented,
606 : NaClDescTryLockNotImplemented,
607 : NaClDescUnlockNotImplemented,
608 : NaClDescWaitNotImplemented,
609 : NaClDescTimedWaitAbsNotImplemented,
610 : NaClDescSignalNotImplemented,
611 : NaClDescBroadcastNotImplemented,
612 : NaClDescSendMsgNotImplemented,
613 : NaClDescRecvMsgNotImplemented,
614 : NaClDescConnectAddrNotImplemented,
615 : NaClDescAcceptConnNotImplemented,
616 : NaClDescPostNotImplemented,
617 : NaClDescSemWaitNotImplemented,
618 : NaClDescGetValueNotImplemented,
619 : };
|