int32_t NaClSysImcMakeBoundSock(struct NaClAppThread *natp, uint32_t descs_addr) { /* * Create a bound socket descriptor and a socket address descriptor. */ struct NaClApp *nap = natp->nap; int32_t retval = -NACL_ABI_EINVAL; struct NaClDesc *pair[2]; int32_t usr_pair[2]; /* This syscall is not used in Chromium so is disabled by default. */ if (!NaClAclBypassChecks) { return -NACL_ABI_EACCES; } NaClLog(3, ("Entered NaClSysImcMakeBoundSock(0x%08"NACL_PRIxPTR"," " 0x%08"NACL_PRIx32")\n"), (uintptr_t) natp, descs_addr); retval = NaClCommonDescMakeBoundSock(pair); if (0 != retval) { goto cleanup; } usr_pair[0] = NaClAppSetDescAvail(nap, pair[0]); usr_pair[1] = NaClAppSetDescAvail(nap, pair[1]); if (!NaClCopyOutToUser(nap, descs_addr, usr_pair, sizeof usr_pair)) { /* * NB: The descriptors were briefly observable to untrusted code * in this window, even though the syscall had not returned yet, * and another thread which guesses their numbers could actually * use them, so the NaClDescSafeUnref inside NaClAppSetDesc below * might not actually deallocate right away. To avoid this, we * could grab the descriptor lock and hold it until after the * copyout is done, but that imposes an ordering between the * descriptor lock and the VM lock which can cause problems * elsewhere. */ NaClAppSetDesc(nap, usr_pair[0], NULL); NaClAppSetDesc(nap, usr_pair[1], NULL); retval = -NACL_ABI_EFAULT; goto cleanup; } retval = 0; cleanup: return retval; }
int main(int argc, char **argv) { struct NaClApp app; NaClHandleBootstrapArgs(&argc, &argv); if (argc != 2) { NaClLog(LOG_FATAL, "Expected 1 argument: executable filename\n"); } NaClAllModulesInit(); CHECK(NaClAppCtor(&app)); CHECK(NaClAppLoadFileFromFilename(&app, argv[1]) == LOAD_OK); NaClAppInitialDescriptorHookup(&app); g_nap = &app; g_expected_desc = MakeExampleDesc(); NaClAppSetDesc(&app, 10, g_expected_desc); CHECK(NaClCreateMainThread(&app, 0, NULL, NULL)); CHECK(NaClWaitForMainThreadToExit(&app) == 0); /* Check for leaks. */ CHECK(g_object_count == 0); /* * Avoid calling exit() because it runs process-global destructors * which might break code that is running in our unjoined threads. */ NaClExit(0); return 0; }
int32_t NaClSysDup2(struct NaClAppThread *natp, int oldfd, int newfd) { struct NaClApp *nap = natp->nap; int retval; struct NaClDesc *old_nd; NaClLog(3, "NaClSysDup(0x%08"NACL_PRIxPTR", %d, %d)\n", (uintptr_t) natp, oldfd, newfd); if (newfd < 0) { retval = -NACL_ABI_EINVAL; goto done; } /* * TODO(bsy): is this a reasonable largest sane value? The * descriptor array shouldn't get too large. */ if (newfd >= NACL_MAX_FD) { retval = -NACL_ABI_EINVAL; goto done; } old_nd = NaClAppGetDesc(nap, oldfd); if (NULL == old_nd) { retval = -NACL_ABI_EBADF; goto done; } NaClAppSetDesc(nap, newfd, old_nd); retval = newfd; done: return retval; }
int32_t NaClSysImcSocketPair(struct NaClAppThread *natp, uint32_t descs_out) { struct NaClApp *nap = natp->nap; int32_t usr_pair[2]; struct NaClDesc *pair[2]; int32_t retval; NaClLog(3, ("Entered NaClSysImcSocketPair(0x%08"NACL_PRIxPTR " 0x%08"NACL_PRIx32")\n"), (uintptr_t) natp, descs_out); /* This syscall is not used in Chromium so is disabled by default. */ if (!NaClAclBypassChecks) { return -NACL_ABI_EACCES; } retval = NaClCommonDescSocketPair(pair); if (0 != retval) { goto cleanup; } usr_pair[0] = NaClAppSetDescAvail(nap, pair[0]); usr_pair[1] = NaClAppSetDescAvail(nap, pair[1]); if (!NaClCopyOutToUser(nap, (uintptr_t) descs_out, usr_pair, sizeof usr_pair)) { NaClAppSetDesc(nap, usr_pair[0], NULL); NaClAppSetDesc(nap, usr_pair[1], NULL); retval = -NACL_ABI_EFAULT; goto cleanup; } retval = 0; cleanup: return retval; }