OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 #include <stdio.h> | 7 #include <stdio.h> |
8 #include <stdlib.h> | 8 #include <stdlib.h> |
9 #include <string.h> | 9 #include <string.h> |
10 | 10 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 | 60 |
61 /* | 61 /* |
62 * Returns, via is_untrusted, whether the signal happened while | 62 * Returns, via is_untrusted, whether the signal happened while |
63 * executing untrusted code. | 63 * executing untrusted code. |
64 * | 64 * |
65 * Returns, via result_thread, the NaClAppThread that untrusted code | 65 * Returns, via result_thread, the NaClAppThread that untrusted code |
66 * was running in. | 66 * was running in. |
67 * | 67 * |
68 * Note that this should only be called from the thread in which the | 68 * Note that this should only be called from the thread in which the |
69 * signal occurred, because on x86-64 it reads a thread-local variable | 69 * signal occurred, because on x86-64 it reads a thread-local variable |
70 * (nacl_thread_index). | 70 * (nacl_current_thread). |
71 */ | 71 */ |
72 void NaClSignalContextGetCurrentThread(const struct NaClSignalContext *sig_ctx, | 72 void NaClSignalContextGetCurrentThread(const struct NaClSignalContext *sig_ctx, |
73 int *is_untrusted, | 73 int *is_untrusted, |
74 struct NaClAppThread **result_thread) { | 74 struct NaClAppThread **result_thread) { |
75 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32 | 75 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32 |
76 /* | 76 /* |
77 * For x86-32, if %cs does not match, it is untrusted code. | 77 * For x86-32, if %cs does not match, it is untrusted code. |
78 * | 78 * |
79 * Note that this check may not be valid on Mac OS X, because | 79 * Note that this check may not be valid on Mac OS X, because |
80 * thread_get_state() does not return the value of NaClGetGlobalCs() | 80 * thread_get_state() does not return the value of NaClGetGlobalCs() |
81 * for a thread suspended inside a syscall. | 81 * for a thread suspended inside a syscall. |
82 * TODO(mseaborn): Don't define this function on Mac OS X. We can | 82 * TODO(mseaborn): Don't define this function on Mac OS X. We can |
83 * compile this conditionally when NaCl's POSIX signal handler is no | 83 * compile this conditionally when NaCl's POSIX signal handler is no |
84 * longer built for Mac. | 84 * longer built for Mac. |
85 * See https://code.google.com/p/nativeclient/issues/detail?id=2664 | 85 * See https://code.google.com/p/nativeclient/issues/detail?id=2664 |
86 */ | 86 */ |
87 *is_untrusted = (NaClGetGlobalCs() != sig_ctx->cs); | 87 *is_untrusted = (NaClGetGlobalCs() != sig_ctx->cs); |
88 *result_thread = NaClAppThreadGetFromIndex(sig_ctx->gs >> 3); | 88 *result_thread = NaClAppThreadGetFromIndex(sig_ctx->gs >> 3); |
89 #elif (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64) || \ | 89 #elif (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64) || \ |
90 NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm || \ | 90 NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm || \ |
91 NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips | 91 NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips |
92 uint32_t current_thread_index = NaClTlsGetIdx(); | 92 struct NaClAppThread *natp = NaClTlsGetCurrentThread(); |
93 if (NACL_TLS_INDEX_INVALID == current_thread_index) { | 93 if (natp == NULL) { |
94 *is_untrusted = 0; | 94 *is_untrusted = 0; |
95 *result_thread = NULL; | 95 *result_thread = NULL; |
96 } else { | 96 } else { |
97 struct NaClAppThread *thread = | |
98 NaClAppThreadGetFromIndex(current_thread_index); | |
99 /* | 97 /* |
100 * Get the address of an arbitrary local, stack-allocated variable, | 98 * Get the address of an arbitrary local, stack-allocated variable, |
101 * just for the purpose of doing a sanity check. | 99 * just for the purpose of doing a sanity check. |
102 */ | 100 */ |
103 void *pointer_into_stack = &thread; | 101 void *pointer_into_stack = &natp; |
104 /* | 102 /* |
105 * Sanity check: Make sure the stack we are running on is not | 103 * Sanity check: Make sure the stack we are running on is not |
106 * allocated in untrusted memory. This checks that the alternate | 104 * allocated in untrusted memory. This checks that the alternate |
107 * signal stack is correctly set up, because otherwise, if it is | 105 * signal stack is correctly set up, because otherwise, if it is |
108 * not set up, the test case would not detect that. | 106 * not set up, the test case would not detect that. |
109 * | 107 * |
110 * There is little point in doing a CHECK instead of a DCHECK, | 108 * There is little point in doing a CHECK instead of a DCHECK, |
111 * because if we are running off an untrusted stack, we have already | 109 * because if we are running off an untrusted stack, we have already |
112 * lost. | 110 * lost. |
113 * | 111 * |
114 * We do not do the check on Windows because Windows does not have | 112 * We do not do the check on Windows because Windows does not have |
115 * an equivalent of sigaltstack() and this signal handler is | 113 * an equivalent of sigaltstack() and this signal handler is |
116 * insecure there. | 114 * insecure there. |
117 */ | 115 */ |
118 if (!NACL_WINDOWS) { | 116 if (!NACL_WINDOWS) { |
119 DCHECK(!NaClIsUserAddr(thread->nap, (uintptr_t) pointer_into_stack)); | 117 DCHECK(!NaClIsUserAddr(natp->nap, (uintptr_t) pointer_into_stack)); |
120 } | 118 } |
121 *is_untrusted = NaClIsUserAddr(thread->nap, sig_ctx->prog_ctr); | 119 *is_untrusted = NaClIsUserAddr(natp->nap, sig_ctx->prog_ctr); |
122 *result_thread = thread; | 120 *result_thread = natp; |
123 } | 121 } |
124 #else | 122 #else |
125 # error Unsupported architecture | 123 # error Unsupported architecture |
126 #endif | 124 #endif |
127 | 125 |
128 /* | 126 /* |
129 * Trusted code could accidentally jump into sandbox address space, | 127 * Trusted code could accidentally jump into sandbox address space, |
130 * so don't rely on prog_ctr on its own for determining whether a | 128 * so don't rely on prog_ctr on its own for determining whether a |
131 * crash comes from untrusted code. We don't want to restore | 129 * crash comes from untrusted code. We don't want to restore |
132 * control to an untrusted exception handler if trusted code | 130 * control to an untrusted exception handler if trusted code |
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 } | 314 } |
317 | 315 |
318 NaClSignalHandlerInitPlatform(); | 316 NaClSignalHandlerInitPlatform(); |
319 NaClSignalHandlerAdd(NaClSignalHandleUntrusted); | 317 NaClSignalHandlerAdd(NaClSignalHandleUntrusted); |
320 } | 318 } |
321 | 319 |
322 void NaClSignalHandlerFini(void) { | 320 void NaClSignalHandlerFini(void) { |
323 /* We try to lock, but since we are shutting down, we ignore failures. */ | 321 /* We try to lock, but since we are shutting down, we ignore failures. */ |
324 NaClSignalHandlerFiniPlatform(); | 322 NaClSignalHandlerFiniPlatform(); |
325 } | 323 } |
OLD | NEW |