2 * Copyright 2008, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
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
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"
42 /* TODO: IS THIS STILL NEEDED FOR WINDOWS ??? */
43 #include <sys/timeb.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
;
72 uint32_t aligned_tramp_ret
;
75 /* esp must be okay for control to have gotten here */
77 NaClLog(4, "Entered NaClSyscallCSegHook\n");
78 NaClLog(4, "user esp 0x%08x\n", user
->esp
);
82 * esp+0: retaddr from lcall
83 * esp+4: code seg from lcall
84 * esp+8: retaddr from syscall wrapper
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
;
98 NaClLog(4, "system call %d\n", sysnum
);
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
;
132 NaClLog(4, "making system call %d, handler 0x%08x\n",
133 sysnum
, (uintptr_t) nacl_syscall
[sysnum
].handler
);
136 natp
->x_esp
= (uint32_t *) (tramp_addr
+ 0xc);
137 natp
->sysret
= (*nacl_syscall
[sysnum
].handler
)(natp
);
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
);
146 NaClSwitchToApp(natp
, tramp_ret
);
149 fprintf(stderr
, "NORETURN NaClSwitchToApp returned!?!\n");