struct NaClDescDirDesc *NaClDescDirDescOpen(char *path) { struct NaClHostDir *nhdp; nhdp = malloc(sizeof *nhdp); if (NULL == nhdp) { NaClLog(LOG_FATAL, "NaClDescDirDescOpen: no memory for %s\n", path); } if (!NaClHostDirOpen(nhdp, path)) { NaClLog(LOG_FATAL, "NaClDescDirDescOpen: NaClHostDirOpen failed for %s\n", path); } return NaClDescDirDescMake(nhdp); }
int32_t NaClSysOpen(struct NaClAppThread *natp, uint32_t pathname, int flags, int mode) { struct NaClApp *nap = natp->nap; uint32_t retval = -NACL_ABI_EINVAL; char path[NACL_CONFIG_PATH_MAX]; nacl_host_stat_t stbuf; int allowed_flags; NaClLog(3, "NaClSysOpen(0x%08"NACL_PRIxPTR", " "0x%08"NACL_PRIx32", 0x%x, 0x%x)\n", (uintptr_t) natp, pathname, flags, mode); if (!NaClAclBypassChecks) { return -NACL_ABI_EACCES; } retval = CopyPathFromUser(nap, path, sizeof path, (uintptr_t) pathname); if (0 != retval) goto cleanup; allowed_flags = (NACL_ABI_O_ACCMODE | NACL_ABI_O_CREAT | NACL_ABI_O_EXCL | NACL_ABI_O_TRUNC | NACL_ABI_O_APPEND | NACL_ABI_O_DIRECTORY); if (0 != (flags & ~allowed_flags)) { NaClLog(LOG_WARNING, "Invalid open flags 0%o, ignoring extraneous bits\n", flags); flags &= allowed_flags; } if (0 != (mode & ~0600)) { NaClLog(1, "IGNORING Invalid access mode bits 0%o\n", mode); mode &= 0600; } /* * Perform a stat to determine whether the file is a directory. * * NB: it is okay for the stat to fail, since the request may be to * create a new file. * * There is a race conditions here: between the stat and the * open-as-a-file and open-as-a-dir, the type of the object that the * path refers to can change. */ retval = NaClHostDescStat(path, &stbuf); /* Windows does not have S_ISDIR(m) macro */ if (0 == retval && S_IFDIR == (S_IFDIR & stbuf.st_mode)) { struct NaClHostDir *hd; /* * Directories cannot be opened with O_EXCL. Technically, due to the above * race condition we might no longer be dealing with a directory, but * until the race is fixed this is best we can do. */ if (flags & NACL_ABI_O_EXCL) { retval = -NACL_ABI_EEXIST; goto cleanup; } hd = malloc(sizeof *hd); if (NULL == hd) { retval = -NACL_ABI_ENOMEM; goto cleanup; } retval = NaClHostDirOpen(hd, path); NaClLog(1, "NaClHostDirOpen(0x%08"NACL_PRIxPTR", %s) returned %d\n", (uintptr_t) hd, path, retval); if (0 == retval) { retval = NaClAppSetDescAvail( nap, (struct NaClDesc *) NaClDescDirDescMake(hd)); NaClLog(1, "Entered directory into open file table at %d\n", retval); } } else { struct NaClHostDesc *hd; if (flags & NACL_ABI_O_DIRECTORY) { retval = -NACL_ABI_ENOTDIR; goto cleanup; } hd = malloc(sizeof *hd); if (NULL == hd) { retval = -NACL_ABI_ENOMEM; goto cleanup; } retval = NaClHostDescOpen(hd, path, flags, mode); NaClLog(1, "NaClHostDescOpen(0x%08"NACL_PRIxPTR", %s, 0%o, 0%o) returned %d\n", (uintptr_t) hd, path, flags, mode, retval); if (0 == retval) { struct NaClDesc *desc = (struct NaClDesc *) NaClDescIoDescMake(hd); if ((flags & NACL_ABI_O_ACCMODE) == NACL_ABI_O_RDONLY) { /* * Let any read-only open be used for PROT_EXEC mmap * calls. Under -a, the user informally warrants that * files' code segments won't be changed after open. */ NaClDescSetFlags(desc, NaClDescGetFlags(desc) | NACL_DESC_FLAGS_MMAP_EXEC_OK); } retval = NaClAppSetDescAvail(nap, desc); NaClLog(1, "Entered into open file table at %d\n", retval); } } cleanup: return retval; }