Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Side by Side Diff: src/trusted/service_runtime/nacl_syscall_common.c

Issue 23484041: Split filename-based syscall implementations into a separate file (Closed) Base URL: svn://svn.chromium.org/native_client/trunk/src/native_client
Patch Set: Fix missing #includes for Windows Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. 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 3 * Use of this source code is governed by a BSD-style license that can be
4 * found in the LICENSE file. 4 * found in the LICENSE file.
5 */ 5 */
6 6
7 /* 7 /*
8 * NaCl service run-time, non-platform specific system call helper routines. 8 * NaCl service run-time, non-platform specific system call helper routines.
9 */ 9 */
10 #include <sys/types.h> 10 #include <sys/types.h>
11 #include <sys/stat.h> 11 #include <sys/stat.h>
12 12
13 #include <errno.h>
13 #include <stdio.h> 14 #include <stdio.h>
14 #if NACL_WINDOWS 15 #if NACL_WINDOWS
15 #include <windows.h> 16 #include <windows.h>
16 #endif 17 #endif
17 18
18 #include "native_client/src/trusted/service_runtime/nacl_syscall_common.h" 19 #include "native_client/src/trusted/service_runtime/nacl_syscall_common.h"
19 20
20 #include "native_client/src/include/nacl_assert.h" 21 #include "native_client/src/include/nacl_assert.h"
21 #include "native_client/src/include/nacl_macros.h" 22 #include "native_client/src/include/nacl_macros.h"
22 #include "native_client/src/include/nacl_platform.h" 23 #include "native_client/src/include/nacl_platform.h"
23 #include "native_client/src/include/portability_process.h" 24 #include "native_client/src/include/portability_process.h"
24 #include "native_client/src/include/portability_string.h" 25 #include "native_client/src/include/portability_string.h"
25 26
26 #include "native_client/src/shared/platform/nacl_check.h" 27 #include "native_client/src/shared/platform/nacl_check.h"
27 #include "native_client/src/shared/platform/nacl_clock.h" 28 #include "native_client/src/shared/platform/nacl_clock.h"
28 #include "native_client/src/shared/platform/nacl_exit.h" 29 #include "native_client/src/shared/platform/nacl_exit.h"
29 #include "native_client/src/shared/platform/nacl_host_desc.h"
30 #include "native_client/src/shared/platform/nacl_host_dir.h"
31 #include "native_client/src/shared/platform/nacl_sync_checked.h" 30 #include "native_client/src/shared/platform/nacl_sync_checked.h"
32 #include "native_client/src/shared/platform/nacl_time.h" 31 #include "native_client/src/shared/platform/nacl_time.h"
33 32
34 #include "native_client/src/trusted/desc/nacl_desc_base.h" 33 #include "native_client/src/trusted/desc/nacl_desc_base.h"
35 #include "native_client/src/trusted/desc/nacl_desc_cond.h" 34 #include "native_client/src/trusted/desc/nacl_desc_cond.h"
36 #include "native_client/src/trusted/desc/nacl_desc_dir.h"
37 #include "native_client/src/trusted/desc/nacl_desc_effector_trusted_mem.h" 35 #include "native_client/src/trusted/desc/nacl_desc_effector_trusted_mem.h"
38 #include "native_client/src/trusted/desc/nacl_desc_io.h" 36 #include "native_client/src/trusted/desc/nacl_desc_io.h"
39 #include "native_client/src/trusted/desc/nacl_desc_mutex.h" 37 #include "native_client/src/trusted/desc/nacl_desc_mutex.h"
40 #include "native_client/src/trusted/desc/nacl_desc_semaphore.h" 38 #include "native_client/src/trusted/desc/nacl_desc_semaphore.h"
41 #include "native_client/src/trusted/desc/nrd_xfer.h" 39 #include "native_client/src/trusted/desc/nrd_xfer.h"
42 40
43 #include "native_client/src/trusted/fault_injection/fault_injection.h" 41 #include "native_client/src/trusted/fault_injection/fault_injection.h"
44 42
45 #include "native_client/src/trusted/service_runtime/include/bits/mman.h" 43 #include "native_client/src/trusted/service_runtime/include/bits/mman.h"
46 #include "native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h " 44 #include "native_client/src/trusted/service_runtime/include/bits/nacl_syscalls.h "
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 268
271 void NaClInsecurelyBypassAllAclChecks(void) { 269 void NaClInsecurelyBypassAllAclChecks(void) {
272 NaClLog(LOG_WARNING, "BYPASSING ALL ACL CHECKS\n"); 270 NaClLog(LOG_WARNING, "BYPASSING ALL ACL CHECKS\n");
273 NaClAclBypassChecks = 1; 271 NaClAclBypassChecks = 1;
274 } 272 }
275 273
276 int NaClHighResolutionTimerEnabled(void) { 274 int NaClHighResolutionTimerEnabled(void) {
277 return NaClAclBypassChecks; 275 return NaClAclBypassChecks;
278 } 276 }
279 277
280 /*
281 * NaClOpenAclCheck: Is the NaCl app authorized to open this file? The
282 * return value is syscall return convention, so 0 is success and
283 * small negative numbers are negated errno values.
284 */
285 int32_t NaClOpenAclCheck(struct NaClApp *nap,
286 char const *path,
287 int flags,
288 int mode) {
289 /*
290 * TODO(bsy): provide some minimal authorization check, based on
291 * whether a debug flag is set; eventually provide a data-driven
292 * authorization configuration mechanism, perhaps persisted via
293 * gears. need GUI for user configuration, as well as designing an
294 * appropriate language (with sufficient expressiveness), however.
295 */
296 NaClLog(1, "NaClOpenAclCheck(0x%08"NACL_PRIxPTR", %s, 0%o, 0%o)\n",
297 (uintptr_t) nap, path, flags, mode);
298 if (3 < NaClLogGetVerbosity()) {
299 NaClLog(0, "O_ACCMODE: 0%o\n", flags & NACL_ABI_O_ACCMODE);
300 NaClLog(0, "O_RDONLY = %d\n", NACL_ABI_O_RDONLY);
301 NaClLog(0, "O_WRONLY = %d\n", NACL_ABI_O_WRONLY);
302 NaClLog(0, "O_RDWR = %d\n", NACL_ABI_O_RDWR);
303 #define FLOG(VAR, BIT) do {\
304 NaClLog(1, "%s: %s\n", #BIT, (VAR & BIT) ? "yes" : "no");\
305 } while (0)
306 FLOG(flags, NACL_ABI_O_CREAT);
307 FLOG(flags, NACL_ABI_O_TRUNC);
308 FLOG(flags, NACL_ABI_O_APPEND);
309 #undef FLOG
310 }
311 if (NaClAclBypassChecks) {
312 return 0;
313 }
314 return -NACL_ABI_EACCES;
315 }
316
317 /*
318 * NaClStatAclCheck: Is the NaCl app authorized to stat this pathname? The
319 * return value is syscall return convention, so 0 is success and
320 * small negative numbers are negated errno values.
321 *
322 * This is primarily for debug use. File access should be through
323 * SRPC-based file servers.
324 */
325 int32_t NaClStatAclCheck(struct NaClApp *nap,
326 char const *path) {
327 NaClLog(2,
328 "NaClStatAclCheck(0x%08"NACL_PRIxPTR", %s)\n", (uintptr_t) nap, path);
329 if (NaClAclBypassChecks) {
330 return 0;
331 }
332 return -NACL_ABI_EACCES;
333 }
334
335 int32_t NaClIoctlAclCheck(struct NaClApp *nap, 278 int32_t NaClIoctlAclCheck(struct NaClApp *nap,
336 struct NaClDesc *ndp, 279 struct NaClDesc *ndp,
337 int request, 280 int request,
338 void *arg) { 281 void *arg) {
339 NaClLog(2, 282 NaClLog(2,
340 ("NaClIoctlAclCheck(0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR"," 283 ("NaClIoctlAclCheck(0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR","
341 " %d, 0x%08"NACL_PRIxPTR"\n"), 284 " %d, 0x%08"NACL_PRIxPTR"\n"),
342 (uintptr_t) nap, (uintptr_t) ndp, request, (uintptr_t) arg); 285 (uintptr_t) nap, (uintptr_t) ndp, request, (uintptr_t) arg);
343 if (NaClAclBypassChecks) { 286 if (NaClAclBypassChecks) {
344 return 0; 287 return 0;
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 if (NULL == old_nd) { 442 if (NULL == old_nd) {
500 retval = -NACL_ABI_EBADF; 443 retval = -NACL_ABI_EBADF;
501 goto done; 444 goto done;
502 } 445 }
503 NaClSetDesc(nap, newfd, old_nd); 446 NaClSetDesc(nap, newfd, old_nd);
504 retval = newfd; 447 retval = newfd;
505 done: 448 done:
506 return retval; 449 return retval;
507 } 450 }
508 451
509 static uint32_t CopyPathFromUser(struct NaClApp *nap,
510 char *dest,
511 size_t num_bytes,
512 uintptr_t src) {
513 /*
514 * NaClCopyInFromUserZStr may (try to) get bytes that is outside the
515 * app's address space and generate a fault.
516 */
517 if (!NaClCopyInFromUserZStr(nap, dest, num_bytes, src)) {
518 if (dest[0] == '\0') {
519 NaClLog(LOG_ERROR, "NaClSys: invalid address for pathname\n");
520 return -NACL_ABI_EFAULT;
521 }
522
523 NaClLog(LOG_ERROR, "NaClSys: pathname string too long\n");
524 return -NACL_ABI_ENAMETOOLONG;
525 }
526
527 return 0;
528 }
529
530 int32_t NaClSysOpen(struct NaClAppThread *natp,
531 char *pathname,
532 int flags,
533 int mode) {
534 struct NaClApp *nap = natp->nap;
535 uint32_t retval = -NACL_ABI_EINVAL;
536 char path[NACL_CONFIG_PATH_MAX];
537 nacl_host_stat_t stbuf;
538 int allowed_flags;
539
540 NaClLog(3, "NaClSysOpen(0x%08"NACL_PRIxPTR", "
541 "0x%08"NACL_PRIxPTR", 0x%x, 0x%x)\n",
542 (uintptr_t) natp, (uintptr_t) pathname, flags, mode);
543
544 retval = CopyPathFromUser(nap, path, sizeof path, (uintptr_t) pathname);
545 if (0 != retval)
546 goto cleanup;
547
548 allowed_flags = (NACL_ABI_O_ACCMODE | NACL_ABI_O_CREAT
549 | NACL_ABI_O_TRUNC | NACL_ABI_O_APPEND);
550 if (0 != (flags & ~allowed_flags)) {
551 NaClLog(LOG_WARNING, "Invalid open flags 0%o, ignoring extraneous bits\n",
552 flags);
553 flags &= allowed_flags;
554 }
555 if (0 != (mode & ~0600)) {
556 NaClLog(1, "IGNORING Invalid access mode bits 0%o\n", mode);
557 mode &= 0600;
558 }
559
560 retval = NaClOpenAclCheck(nap, path, flags, mode);
561 if (0 != retval) {
562 NaClLog(3, "Open ACL check rejected \"%s\".\n", path);
563 goto cleanup;
564 }
565
566 /*
567 * Perform a stat to determine whether the file is a directory.
568 *
569 * NB: it is okay for the stat to fail, since the request may be to
570 * create a new file.
571 *
572 * There is a race conditions here: between the stat and the
573 * open-as-a-file and open-as-a-dir, the type of the object that the
574 * path refers to can change.
575 */
576 retval = NaClHostDescStat(path, &stbuf);
577
578 /* Windows does not have S_ISDIR(m) macro */
579 if (0 == retval && S_IFDIR == (S_IFDIR & stbuf.st_mode)) {
580 struct NaClHostDir *hd;
581
582 hd = malloc(sizeof *hd);
583 if (NULL == hd) {
584 retval = -NACL_ABI_ENOMEM;
585 goto cleanup;
586 }
587 retval = NaClHostDirOpen(hd, path);
588 NaClLog(1, "NaClHostDirOpen(0x%08"NACL_PRIxPTR", %s) returned %d\n",
589 (uintptr_t) hd, path, retval);
590 if (0 == retval) {
591 retval = NaClSetAvail(nap,
592 ((struct NaClDesc *) NaClDescDirDescMake(hd)));
593 NaClLog(1, "Entered directory into open file table at %d\n",
594 retval);
595 }
596 } else {
597 struct NaClHostDesc *hd;
598
599 hd = malloc(sizeof *hd);
600 if (NULL == hd) {
601 retval = -NACL_ABI_ENOMEM;
602 goto cleanup;
603 }
604 retval = NaClHostDescOpen(hd, path, flags, mode);
605 NaClLog(1,
606 "NaClHostDescOpen(0x%08"NACL_PRIxPTR", %s, 0%o, 0%o) returned %d\n",
607 (uintptr_t) hd, path, flags, mode, retval);
608 if (0 == retval) {
609 struct NaClDesc *desc = (struct NaClDesc *) NaClDescIoDescMake(hd);
610 if ((flags & NACL_ABI_O_ACCMODE) == NACL_ABI_O_RDONLY) {
611 /*
612 * Let any read-only open be used for PROT_EXEC mmap
613 * calls. Under -a, the user informally warrants that
614 * files' code segments won't be changed after open.
615 */
616 NaClDescSetFlags(desc,
617 NaClDescGetFlags(desc) | NACL_DESC_FLAGS_MMAP_EXEC_OK);
618 }
619 retval = NaClSetAvail(nap, desc);
620 NaClLog(1, "Entered into open file table at %d\n", retval);
621 }
622 }
623 cleanup:
624 return retval;
625 }
626
627 int32_t NaClSysClose(struct NaClAppThread *natp, 452 int32_t NaClSysClose(struct NaClAppThread *natp,
628 int d) { 453 int d) {
629 struct NaClApp *nap = natp->nap; 454 struct NaClApp *nap = natp->nap;
630 int retval = -NACL_ABI_EBADF; 455 int retval = -NACL_ABI_EBADF;
631 struct NaClDesc *ndp; 456 struct NaClDesc *ndp;
632 457
633 NaClLog(3, "Entered NaClSysClose(0x%08"NACL_PRIxPTR", %d)\n", 458 NaClLog(3, "Entered NaClSysClose(0x%08"NACL_PRIxPTR", %d)\n",
634 (uintptr_t) natp, d); 459 (uintptr_t) natp, d);
635 460
636 NaClFastMutexLock(&nap->desc_mu); 461 NaClFastMutexLock(&nap->desc_mu);
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
1014 &result, sizeof result)) { 839 &result, sizeof result)) {
1015 retval = -NACL_ABI_EFAULT; 840 retval = -NACL_ABI_EFAULT;
1016 } 841 }
1017 } 842 }
1018 843
1019 NaClDescUnref(ndp); 844 NaClDescUnref(ndp);
1020 cleanup: 845 cleanup:
1021 return retval; 846 return retval;
1022 } 847 }
1023 848
1024 int32_t NaClSysStat(struct NaClAppThread *natp,
1025 const char *pathname,
1026 struct nacl_abi_stat *buf) {
1027 struct NaClApp *nap = natp->nap;
1028 int32_t retval = -NACL_ABI_EINVAL;
1029 char path[NACL_CONFIG_PATH_MAX];
1030 nacl_host_stat_t stbuf;
1031
1032 NaClLog(3,
1033 ("Entered NaClSysStat(0x%08"NACL_PRIxPTR", 0x%08"NACL_PRIxPTR","
1034 " 0x%08"NACL_PRIxPTR")\n"),
1035 (uintptr_t) natp, (uintptr_t) pathname, (uintptr_t) buf);
1036
1037 retval = CopyPathFromUser(nap, path, sizeof path, (uintptr_t) pathname);
1038 if (0 != retval)
1039 goto cleanup;
1040
1041 retval = NaClStatAclCheck(nap, path);
1042 if (0 != retval)
1043 goto cleanup;
1044
1045 /*
1046 * Perform a host stat.
1047 */
1048 retval = NaClHostDescStat(path, &stbuf);
1049 if (0 == retval) {
1050 struct nacl_abi_stat abi_stbuf;
1051
1052 retval = NaClAbiStatHostDescStatXlateCtor(&abi_stbuf,
1053 &stbuf);
1054 if (!NaClCopyOutToUser(nap, (uintptr_t) buf,
1055 &abi_stbuf, sizeof abi_stbuf)) {
1056 retval = -NACL_ABI_EFAULT;
1057 }
1058 }
1059 cleanup:
1060 return retval;
1061 }
1062
1063 int32_t NaClSysMkdir(struct NaClAppThread *natp,
1064 uint32_t pathname,
1065 int mode) {
1066 struct NaClApp *nap = natp->nap;
1067 char path[NACL_CONFIG_PATH_MAX];
1068 int32_t retval = -NACL_ABI_EINVAL;
1069
1070 if (!NaClAclBypassChecks) {
1071 retval = -NACL_ABI_EACCES;
1072 goto cleanup;
1073 }
1074
1075 retval = CopyPathFromUser(nap, path, sizeof path, pathname);
1076 if (0 != retval)
1077 goto cleanup;
1078
1079 retval = NaClHostDescMkdir(path, mode);
1080 cleanup:
1081 return retval;
1082 }
1083
1084 int32_t NaClSysRmdir(struct NaClAppThread *natp,
1085 uint32_t pathname) {
1086 struct NaClApp *nap = natp->nap;
1087 char path[NACL_CONFIG_PATH_MAX];
1088 int32_t retval = -NACL_ABI_EINVAL;
1089
1090 if (!NaClAclBypassChecks) {
1091 retval = -NACL_ABI_EACCES;
1092 goto cleanup;
1093 }
1094
1095 retval = CopyPathFromUser(nap, path, sizeof path, pathname);
1096 if (0 != retval)
1097 goto cleanup;
1098
1099 retval = NaClHostDescRmdir(path);
1100 cleanup:
1101 return retval;
1102 }
1103
1104 int32_t NaClSysChdir(struct NaClAppThread *natp,
1105 uint32_t pathname) {
1106 struct NaClApp *nap = natp->nap;
1107 char path[NACL_CONFIG_PATH_MAX];
1108 int32_t retval = -NACL_ABI_EINVAL;
1109
1110 if (!NaClAclBypassChecks) {
1111 retval = -NACL_ABI_EACCES;
1112 goto cleanup;
1113 }
1114
1115 retval = CopyPathFromUser(nap, path, sizeof path, pathname);
1116 if (0 != retval)
1117 goto cleanup;
1118
1119 retval = NaClHostDescChdir(path);
1120 cleanup:
1121 return retval;
1122 }
1123
1124 int32_t NaClSysGetcwd(struct NaClAppThread *natp,
1125 uint32_t buffer,
1126 int len) {
1127 struct NaClApp *nap = natp->nap;
1128 int32_t retval = -NACL_ABI_EINVAL;
1129 char path[NACL_CONFIG_PATH_MAX];
1130
1131 if (!NaClAclBypassChecks) {
1132 retval = -NACL_ABI_EACCES;
1133 goto cleanup;
1134 }
1135
1136 if (len >= NACL_CONFIG_PATH_MAX)
1137 len = NACL_CONFIG_PATH_MAX - 1;
1138
1139 retval = NaClHostDescGetcwd(path, len);
1140 if (retval != 0)
1141 goto cleanup;
1142
1143 if (!NaClCopyOutToUser(nap, buffer, &path, strlen(path) + 1))
1144 retval = -NACL_ABI_EFAULT;
1145
1146 cleanup:
1147 return retval;
1148 }
1149
1150 int32_t NaClSysUnlink(struct NaClAppThread *natp,
1151 uint32_t pathname) {
1152 struct NaClApp *nap = natp->nap;
1153 char path[NACL_CONFIG_PATH_MAX];
1154 int32_t retval = -NACL_ABI_EINVAL;
1155
1156 if (!NaClAclBypassChecks) {
1157 retval = -NACL_ABI_EACCES;
1158 goto cleanup;
1159 }
1160
1161 retval = CopyPathFromUser(nap, path, sizeof path, pathname);
1162 if (0 != retval)
1163 goto cleanup;
1164
1165 retval = NaClHostDescUnlink(path);
1166 cleanup:
1167 return retval;
1168 }
1169
1170 int NaClSysCommonAddrRangeContainsExecutablePages(struct NaClApp *nap, 849 int NaClSysCommonAddrRangeContainsExecutablePages(struct NaClApp *nap,
1171 uintptr_t usraddr, 850 uintptr_t usraddr,
1172 size_t length) { 851 size_t length) {
1173 /* 852 /*
1174 * NOTE: currently only trampoline and text region are executable, 853 * NOTE: currently only trampoline and text region are executable,
1175 * and they are at the beginning of the address space, so this code 854 * and they are at the beginning of the address space, so this code
1176 * is fine. We will probably never allow users to mark other pages 855 * is fine. We will probably never allow users to mark other pages
1177 * as executable; but if so, we will have to revisit how this check 856 * as executable; but if so, we will have to revisit how this check
1178 * is implemented. 857 * is implemented.
1179 * 858 *
(...skipping 1985 matching lines...) Expand 10 before | Expand all | Expand 10 after
3165 return NaClSysClockGetCommon(natp, clk_id, (uintptr_t) tsp, 2844 return NaClSysClockGetCommon(natp, clk_id, (uintptr_t) tsp,
3166 NaClClockGetRes); 2845 NaClClockGetRes);
3167 } 2846 }
3168 2847
3169 int32_t NaClSysClockGetTime(struct NaClAppThread *natp, 2848 int32_t NaClSysClockGetTime(struct NaClAppThread *natp,
3170 int clk_id, 2849 int clk_id,
3171 uint32_t tsp) { 2850 uint32_t tsp) {
3172 return NaClSysClockGetCommon(natp, clk_id, (uintptr_t) tsp, 2851 return NaClSysClockGetCommon(natp, clk_id, (uintptr_t) tsp,
3173 NaClClockGetTime); 2852 NaClClockGetTime);
3174 } 2853 }
OLDNEW
« no previous file with comments | « src/trusted/service_runtime/nacl_syscall_common.h ('k') | src/trusted/service_runtime/nacl_syscall_handlers_gen.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698