int __write(int desc, void const *buf, size_t count) { int (*__gnacl_write)(int desc, void const *buf, size_t count) = NACL_SYSCALL_ADDR(NACL_sys_write); int result = __gnacl_write(desc, buf, count); if (result < 0) { errno = -result; return -1; } return result; }
int __fxstat64(int vers, int fd, struct stat64 *buf) { int (*nacl_fstat)(int fd, struct stat64 *buf) = NACL_SYSCALL_ADDR(NACL_sys_fstat); int result = nacl_fstat(fd, buf); if (result < 0) { errno = -result; return -1; } return result; }
int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "Expected 1 argument: <memory-address>\n"); return 1; } char *end; struct NaClSignalContext *expected_regs = (struct NaClSignalContext *) strtoul(argv[1], &end, 0); assert(*end == '\0'); struct NaClSignalContext call_regs; char stack[0x10000]; RegsFillTestValues(&call_regs); call_regs.stack_ptr = (uintptr_t) stack + sizeof(stack); call_regs.prog_ctr = (uintptr_t) SyscallReturnAddress; RegsApplySandboxConstraints(&call_regs); RegsUnsetNonCalleeSavedRegisters(&call_regs); uintptr_t syscall_addr = NACL_SYSCALL_ADDR(NACL_sys_test_syscall_1); #if defined(__i386__) call_regs.esi = syscall_addr; *expected_regs = call_regs; ASM_WITH_REGS( &call_regs, "SyscallLoop:\n" "naclcall %%esi\n" "SyscallReturnAddress:\n" "jmp SyscallLoop\n"); #elif defined(__x86_64__) call_regs.r12 = syscall_addr; *expected_regs = call_regs; ASM_WITH_REGS( &call_regs, "SyscallLoop:\n" /* Call via a temporary register so as not to modify %r12. */ "mov %%r12d, %%eax\n" "naclcall %%eax, %%r15\n" "SyscallReturnAddress:\n" "jmp SyscallLoop\n"); #else # error Unsupported architecture #endif }
/* * Set registers to known values and call a NaCl syscall in an * infinite loop. This is used for testing that the same register * state is reported while the thread is in untrusted code or inside * the syscall. */ static void SyscallRegisterSetterLoopThread(struct SuspendTestShm *test_shm) { struct NaClSignalContext *regs = &test_shm->expected_regs; char stack[0x10000]; RegsFillTestValues(regs, /* seed= */ 0); regs->stack_ptr = (uintptr_t) stack + sizeof(stack); regs->prog_ctr = (uintptr_t) SyscallReturnAddress; RegsApplySandboxConstraints(regs); RegsUnsetNonCalleeSavedRegisters(regs); uintptr_t syscall_addr = NACL_SYSCALL_ADDR(NACL_sys_test_syscall_2); #if defined(__i386__) regs->esi = syscall_addr; #elif defined(__x86_64__) regs->r12 = syscall_addr; #elif defined(__arm__) regs->r4 = syscall_addr; #elif defined(__mips__) regs->s0 = syscall_addr; #else # error Unsupported architecture #endif JUMP_WITH_REGS(regs, SyscallReturnAddress); }
int main(int argc, char **argv) { if (argc != 2) { fprintf(stderr, "Expected 1 argument: <memory-address>\n"); return 1; } char *end; struct RegsTestShm *test_shm = (struct RegsTestShm *) strtoul(argv[1], &end, 0); assert(*end == '\0'); test_shm->regs_should_match = &g_regs_should_match; struct NaClSignalContext call_regs; char stack[0x10000]; int call_count = 0; for (call_count = 0; ; call_count++) { uintptr_t syscall_addr; /* * Test fast-path TLS syscalls. We shoe-horn these in after the * first call to test_syscall_1 has enabled single-stepping. */ if (call_count == 1) { syscall_addr = NACL_SYSCALL_ADDR(NACL_sys_tls_get); } else if (call_count == 2) { syscall_addr = NACL_SYSCALL_ADDR(NACL_sys_second_tls_get); } else { syscall_addr = NACL_SYSCALL_ADDR(NACL_sys_test_syscall_1); } /* * Use different expected register values for each call. * Otherwise, the test could accidentally pass because the * stack_ptr reported during the entry to a syscall can happen to * match the stack_ptr saved by the previous syscall. */ RegsFillTestValues(&call_regs, /* seed= */ call_count); #if defined(__i386__) call_regs.esi = syscall_addr; #elif defined(__x86_64__) call_regs.r12 = syscall_addr; #elif defined(__arm__) call_regs.r4 = syscall_addr; call_regs.r5 = (uintptr_t) &g_regs_should_match; call_regs.r6 = 1; call_regs.r7 = 0; #elif defined(__mips__) call_regs.s0 = syscall_addr; call_regs.s1 = (uintptr_t) &g_regs_should_match; call_regs.s2 = 1; #else # error Unsupported architecture #endif call_regs.prog_ctr = (uintptr_t) (call_count % 2 == 0 ? SyscallReturnAddress1 : SyscallReturnAddress2); call_regs.stack_ptr = (uintptr_t) stack + sizeof(stack) - (call_count % 2) * 0x100; RegsApplySandboxConstraints(&call_regs); RegsUnsetNonCalleeSavedRegisters(&call_regs); test_shm->expected_regs = call_regs; if (!setjmp(g_jmp_buf)) { if (call_count % 2 == 0) { JUMP_WITH_REGS(&call_regs, SyscallCaller1); } else { JUMP_WITH_REGS(&call_regs, SyscallCaller2); } } } }
#include <stdlib.h> #include <nacl_rpc.h> int (*imc_sendmsg)(int fd, const struct NaClImcMsgHdr *msg, int flags) = NACL_SYSCALL_ADDR(NACL_sys_imc_sendmsg); int (*imc_recvmsg)(int fd, struct NaClImcMsgHdr *msg, int flags) = NACL_SYSCALL_ADDR(NACL_sys_imc_recvmsg); hidden_def (imc_sendmsg); hidden_def (imc_recvmsg); static int is_initialised = 0; static int use_rpc = 0; int nacl_should_use_rpc(void) { if(!is_initialised) { use_rpc = getenv("NACL_FD") != NULL; is_initialised = 1; } return use_rpc; } hidden_def (nacl_should_use_rpc);