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
;
90 * return addr could have been tampered with by another thread, but
91 * the only result would be a bad sysnum.
93 sysnum
= (tramp_ret
- NACL_SYSCALL_START_ADDR
)
94 >> NACL_SYSCALL_BLOCK_SHIFT
;
97 NaClLog(4, "system call %d\n", sysnum
);
100 * keep tramp_ret in user addr; do not bother to ensure tramp_addr +
101 * 8 is valid, since even if we loaded two NaClApps next to each
102 * other this would just load the trampoline code, or hit the
103 * inaccessible page for NULL pointer detection (once we get that
104 * implemented). if it is not a valid address, we would just crash.
106 tramp_ret
= *(uint32_t *) (tramp_addr
+ 8);
107 if (0 != nap
->xlate_base
) {
109 * ensure that tramp_ret value is ok. no need to ensure that this
110 * is in the app's address space, since the syscall return will
111 * just result in a fault after we reconstitute the sandbox and
112 * attempt to pass control to this address.
114 aligned_tramp_ret
= tramp_ret
& ~(nap
->align_boundary
- 1);
115 if (tramp_ret
!= aligned_tramp_ret
) {
116 NaClLog(LOG_FATAL
, ("NaClSyscallCSegHook: tramp_ret infinite loop:"
117 " %08x != %08x\nMake sure NaCl SDK and sel_ldr"
118 " agree on alignment (ELF header of NaCl app"
119 " claims alignment is %d).\n"),
120 tramp_ret
, aligned_tramp_ret
, nap
->align_boundary
);
122 tramp_ret
= aligned_tramp_ret
;
125 user
->esp
+= 0xc; /* call, lcall */
126 if (sysnum
>= NACL_MAX_SYSCALLS
) {
127 NaClLog(2, "INVALID system call %d\n", sysnum
);
128 natp
->sysret
= -NACL_ABI_EINVAL
;
131 NaClLog(4, "making system call %d, handler 0x%08x\n",
132 sysnum
, (uintptr_t) nacl_syscall
[sysnum
].handler
);
135 natp
->x_esp
= (uint32_t *) (tramp_addr
+ 0xc);
136 natp
->sysret
= (*nacl_syscall
[sysnum
].handler
)(natp
);
139 NaClLog(4, "returning from system call %d, return value %d (0x%x)\n",
140 sysnum
, natp
->sysret
, natp
->sysret
);
142 NaClLog(4, "return target 0x%08x\n", tramp_ret
);
143 NaClLog(4, "user esp 0x%08x\n", user
->esp
);
145 NaClSwitchToApp(natp
, tramp_ret
);
148 fprintf(stderr
, "NORETURN NaClSwitchToApp returned!?!\n");