| 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 |