Fix file permissions: set executable bit
[nativeclient.git] / service_runtime / nacl_syscall_hook.c
blob421dd5387a022c01cfb6b8815861205a13f10e54
1 /*
2 * Copyright 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following disclaimer
13 * in the documentation and/or other materials provided with the
14 * distribution.
15 * * Neither the name of Google Inc. nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * NaCl service run-time.
36 #include "native_client/include/portability.h"
37 #include "native_client/include/nacl_platform.h"
39 #include <stdlib.h>
40 #include <errno.h>
41 #if NACL_WINDOWS
42 /* TODO: IS THIS STILL NEEDED FOR WINDOWS ??? */
43 #include <sys/timeb.h>
44 #endif
45 #include <fcntl.h>
46 #include <time.h>
48 #include "native_client/service_runtime/nacl_globals.h"
49 #include "native_client/service_runtime/nacl_config.h"
50 #include "native_client/service_runtime/nacl_log.h"
51 #include "native_client/service_runtime/sel_ldr.h"
52 #include "native_client/service_runtime/nacl_switch_to_app.h"
53 #include "native_client/service_runtime/nacl_syscall_handlers.h"
55 #include "native_client/service_runtime/include/sys/errno.h"
56 #include "native_client/service_runtime/include/bits/nacl_syscalls.h"
59 * Simple RPC support. The default socket file descriptor is invalid.
61 int NaClSrpcFileDescriptor = -1;
65 NORETURN void NaClSyscallCSegHook(int32_t ldt_ix)
67 struct NaClAppThread *natp = nacl_thread[ldt_ix];
68 struct NaClApp *nap = natp->nap;
69 struct NaClThreadContext *user = &natp->user;
70 uintptr_t tramp_addr;
71 uint32_t tramp_ret;
72 uint32_t aligned_tramp_ret;
73 uint32_t sysnum;
75 /* esp must be okay for control to have gotten here */
76 #if !BENCHMARK
77 NaClLog(4, "Entered NaClSyscallCSegHook\n");
78 NaClLog(4, "user esp 0x%08x\n", user->esp);
79 #endif
81 * on user stack:
82 * esp+0: retaddr from lcall
83 * esp+4: code seg from lcall
84 * esp+8: retaddr from syscall wrapper
85 * esp+c: ...
87 tramp_addr = NaClUserToSys(nap, user->esp);
88 tramp_ret = *(uint32_t *) tramp_addr;
89 tramp_ret = NaClUserToSys(nap, tramp_ret);
91 * return addr could have been tampered with by another thread, but
92 * the only result would be a bad sysnum.
94 sysnum = (tramp_ret - (nap->mem_start + NACL_SYSCALL_START_ADDR))
95 >> NACL_SYSCALL_BLOCK_SHIFT;
97 #if !BENCHMARK
98 NaClLog(4, "system call %d\n", sysnum);
99 #endif
101 * keep tramp_ret in user addr; do not bother to ensure tramp_addr +
102 * 8 is valid, since even if we loaded two NaClApps next to each
103 * other this would just load the trampoline code, or hit the
104 * inaccessible page for NULL pointer detection (once we get that
105 * implemented). if it is not a valid address, we would just crash.
107 tramp_ret = *(uint32_t *) (tramp_addr + 8);
108 if (0 != nap->xlate_base) {
110 * ensure that tramp_ret value is ok. no need to ensure that this
111 * is in the app's address space, since the syscall return will
112 * just result in a fault after we reconstitute the sandbox and
113 * attempt to pass control to this address.
115 aligned_tramp_ret = tramp_ret & ~(nap->align_boundary - 1);
116 if (tramp_ret != aligned_tramp_ret) {
117 NaClLog(LOG_FATAL, ("NaClSyscallCSegHook: tramp_ret infinite loop:"
118 " %08x != %08x\nMake sure NaCl SDK and sel_ldr"
119 " agree on alignment (ELF header of NaCl app"
120 " claims alignment is %d).\n"),
121 tramp_ret, aligned_tramp_ret, nap->align_boundary);
123 tramp_ret = aligned_tramp_ret;
126 user->esp += 0xc; /* call, lcall */
127 if (sysnum >= NACL_MAX_SYSCALLS) {
128 NaClLog(2, "INVALID system call %d\n", sysnum);
129 natp->sysret = -NACL_ABI_EINVAL;
130 } else {
131 #if !BENCHMARK
132 NaClLog(4, "making system call %d, handler 0x%08x\n",
133 sysnum, (uintptr_t) nacl_syscall[sysnum].handler);
134 #endif
136 natp->x_esp = (uint32_t *) (tramp_addr + 0xc);
137 natp->sysret = (*nacl_syscall[sysnum].handler)(natp);
139 #if !BENCHMARK
140 NaClLog(4, "returning from system call %d, return value %d (0x%x)\n",
141 sysnum, natp->sysret, natp->sysret);
143 NaClLog(4, "return target 0x%08x\n", tramp_ret);
144 NaClLog(4, "user esp 0x%08x\n", user->esp);
145 #endif
146 NaClSwitchToApp(natp, tramp_ret);
147 /* NOTREACHED */
149 fprintf(stderr, "NORETURN NaClSwitchToApp returned!?!\n");
150 abort();