/* serve trap invoked from the untrusted code */ NORETURN void SyscallHook() { struct NaClApp *nap; struct ThreadContext *user; uintptr_t tramp_ret; nacl_reg_t user_ret; size_t sysnum; uintptr_t sp_user; uintptr_t sp_sys; /* restore trusted side environment */ nap = gnap; /* restore NaClApp object */ user = nacl_user; sp_user = GetThreadCtxSp(user); sp_sys = sp_user; /* * sp_sys points to the top of user stack where there is a retaddr to * trampoline slot */ tramp_ret = *(uintptr_t *)sp_sys; sysnum = (tramp_ret - (nap->mem_start + NACL_SYSCALL_START_ADDR)) >> NACL_SYSCALL_BLOCK_SHIFT; /* * getting user return address (the address where we need to return after * system call) from the user stack. (see stack layout above) */ user_ret = *(uintptr_t *)(sp_sys + NACL_USERRET_FIX); /* * Fix the user stack, throw away return addresses from the top of the stack. * After this fix, the first argument to a system call must be on the top of * the user stack (see user stack layout above) */ sp_sys += NACL_SYSARGS_FIX; sp_user += NACL_SYSCALLRET_FIX; SetThreadCtxSp(user, sp_user); /* fail if nacl syscall received */ ZLOGFAIL(sysnum != 0, EINVAL, "nacl syscall #%d received", sysnum); /* * syscall_args must point to the first argument of a system call. * System call arguments are placed on the untrusted user stack. */ nap->sysret = TrapHandler(nap, *(uint32_t*)sp_sys); /* * before switching back to user module, we need to make sure that the * user_ret is properly sandboxed. */ user_ret = (nacl_reg_t)NaClSandboxCodeAddr(nap, (uintptr_t)user_ret); /* d'b: give control to the user side */ SwitchToApp(nap, user_ret); ZLOGFAIL(1, EFAULT, "the unreachable has been reached"); }
__cdecl Exhandler(EXCEPTION_RECORD *rec, void *frame, CONTEXT *context, void *dcon) { EXCEPTION_POINTERS ep; ep.ExceptionRecord = rec; ep.ContextRecord = context; TrapHandler(&ep); return ExceptionContinueExecution; }
/* d'b: trap(). see documentation for the details */ static int32_t TrapDecoder(struct NaClApp *nap) { struct TrapDecoderArgs { uint32_t args; } p = *(struct TrapDecoderArgs*) nap->syscall_args; return TrapHandler(nap, p.args); }