Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(514)

Side by Side Diff: components/nacl/loader/nonsfi/irt_thread.cc

Issue 248463005: [WIP] Plan B: no service_runtime dependency with more copy-paste. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « components/nacl/loader/nonsfi/irt_exception_handling.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <errno.h> 5 #include <errno.h>
6 #include <pthread.h> 6 #include <pthread.h>
7 #include <signal.h>
7 #include <stdlib.h> 8 #include <stdlib.h>
9 #include <sys/mman.h>
8 10
9 #include "base/logging.h" 11 #include "base/logging.h"
10 #include "base/macros.h" 12 #include "base/macros.h"
11 #include "base/memory/scoped_ptr.h" 13 #include "base/memory/scoped_ptr.h"
12 #include "components/nacl/loader/nonsfi/irt_interfaces.h" 14 #include "components/nacl/loader/nonsfi/irt_interfaces.h"
13 #include "native_client/src/trusted/service_runtime/nacl_signal.h"
14 15
15 namespace nacl { 16 namespace nacl {
16 namespace nonsfi { 17 namespace nonsfi {
17 namespace { 18 namespace {
18 19
19 // We heuristically chose 1M for the stack size per thread. 20 // We heuristically chose 1M for the stack size per thread.
20 const int kStackSize = 1024 * 1024; 21 const int kStackSize = 1024 * 1024;
21 22
22 // For RAII of pthread_attr_t. 23 // For RAII of pthread_attr_t.
23 class ScopedPthreadAttrPtr { 24 class ScopedPthreadAttrPtr {
(...skipping 13 matching lines...) Expand all
37 void* thread_ptr; 38 void* thread_ptr;
38 void* signal_stack; 39 void* signal_stack;
39 }; 40 };
40 41
41 // A thread local pointer to support nacl_irt_tls. 42 // A thread local pointer to support nacl_irt_tls.
42 // This should be initialized at the beginning of ThreadMain, which is a thin 43 // This should be initialized at the beginning of ThreadMain, which is a thin
43 // wrapper of a user function called on a newly created thread, and may be 44 // wrapper of a user function called on a newly created thread, and may be
44 // reset via IrtTlsInit(). The pointer can be obtained via IrtTlsGet(). 45 // reset via IrtTlsInit(). The pointer can be obtained via IrtTlsGet().
45 __thread void* g_thread_ptr; 46 __thread void* g_thread_ptr;
46 47
48 const int kSignalStackSize = SIGSTKSZ + 4096;
49 const int kNonSfiPageSize = 4096; // really?
50 const int kStackGuardSize = kNonSfiPageSize;
51
52 void NaClSignalStackRegister(void *stack) {
53 /*
54 * If we set up signal handlers, we must ensure that any thread that
55 * runs untrusted code has an alternate signal stack set up. The
56 * default for a new thread is to use the stack pointer from the
57 * point at which the fault occurs, but it would not be safe to use
58 * untrusted code's %esp/%rsp value.
59 */
60 stack_t st;
61 st.ss_size = kSignalStackSize;
62 st.ss_sp = ((uint8_t *) stack) + kStackGuardSize;
63 st.ss_flags = 0;
64 if (sigaltstack(&st, NULL) != 0) {
65 PLOG(FATAL) << "Failed to register signal stack";
66 }
67 }
68
69 int NaClSignalStackAllocate(void **result) {
70 /*
71 * We use mmap() to allocate the signal stack for two reasons:
72 *
73 * 1) By page-aligning the memory allocation (which malloc() does
74 * not do for small allocations), we avoid allocating any real
75 * memory in the common case in which the signal handler is never
76 * run.
77 *
78 * 2) We get to create a guard page, to guard against the unlikely
79 * occurrence of the signal handler both overrunning and doing so in
80 * an exploitable way.
81 */
82 void *stack = mmap(NULL, kSignalStackSize + kStackGuardSize,
83 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON,
84 -1, 0);
85 if (stack == MAP_FAILED) {
86 return 0;
87 }
88 /* We assume that the stack grows downwards. */
89 if (mprotect(stack, kStackGuardSize, PROT_NONE) != 0) {
90 PLOG(FATAL) << "Failed to mprotect() the stack guard page";
91 }
92 *result = stack;
93 return 1;
94 }
95
47 void* ThreadMain(void *arg) { 96 void* ThreadMain(void *arg) {
48 ::scoped_ptr<ThreadContext> context(static_cast<ThreadContext*>(arg)); 97 ::scoped_ptr<ThreadContext> context(static_cast<ThreadContext*>(arg));
49 g_thread_ptr = context->thread_ptr; 98 g_thread_ptr = context->thread_ptr;
50 99
51 DVLOG(4) << "Registering alternate signal stack: " << context->signal_stack; 100 DVLOG(4) << "Registering alternate signal stack: " << context->signal_stack;
52 NaClSignalStackRegister(context->signal_stack); 101 NaClSignalStackRegister(context->signal_stack);
53 102
54 // Release the memory of context before running start_func. 103 // Release the memory of context before running start_func.
55 void (*start_func)() = context->start_func; 104 void (*start_func)() = context->start_func;
56 context.reset(); 105 context.reset();
(...skipping 30 matching lines...) Expand all
87 error = pthread_create(&tid, &attr, ThreadMain, context.get()); 136 error = pthread_create(&tid, &attr, ThreadMain, context.get());
88 if (error != 0) 137 if (error != 0)
89 return error; 138 return error;
90 139
91 // The ownership of the context is taken by the created thread. So, here we 140 // The ownership of the context is taken by the created thread. So, here we
92 // just manually release it. 141 // just manually release it.
93 ignore_result(context.release()); 142 ignore_result(context.release());
94 return 0; 143 return 0;
95 } 144 }
96 145
146 void* NaClSignalStackUnregister(void) {
147 /*
148 * Unregister the signal stack in case a fault occurs between the
149 * thread deallocating the signal stack and exiting. Such a fault
150 * could be unsafe if the address space were reallocated before the
151 * fault, although that is unlikely.
152 */
153 stack_t st;
154 st.ss_size = 0;
155 st.ss_sp = NULL;
156 st.ss_flags = SS_DISABLE;
157 stack_t old_stack;
158 if (sigaltstack(&st, &old_stack) != 0) {
159 PLOG(FATAL) << "Failed to unregister signal stack.";
160 }
161 return old_stack.ss_sp;
162 }
163
164 void NaClSignalStackFree(void *stack) {
165 CHECK(stack != NULL);
166 if (munmap(stack, kSignalStackSize + kStackGuardSize) != 0) {
167 PLOG(FATAL) << "Failed to munmap() signal stack.";
168 }
169 }
170
97 void IrtThreadExit(int32_t* stack_flag) { 171 void IrtThreadExit(int32_t* stack_flag) {
98 // As we actually don't use stack given to thread_create, it means that the 172 // As we actually don't use stack given to thread_create, it means that the
99 // memory can be released whenever. 173 // memory can be released whenever.
100 if (stack_flag) 174 if (stack_flag)
101 *stack_flag = 0; 175 *stack_flag = 0;
176 NaClSignalStackUnregister();
177 // TODO: How do I know altstack address ? Should I trust sigaltstack
178 // return value ?
179 // NaClSignalStackFree(signal_stack);
102 pthread_exit(NULL); 180 pthread_exit(NULL);
103 } 181 }
104 182
105 int IrtThreadNice(const int nice) { 183 int IrtThreadNice(const int nice) {
106 // TODO(https://code.google.com/p/nativeclient/issues/detail?id=3734): 184 // TODO(https://code.google.com/p/nativeclient/issues/detail?id=3734):
107 // Implement this method. 185 // Implement this method.
108 // Note that this is just a hint, so here we just return success without 186 // Note that this is just a hint, so here we just return success without
109 // do anything. 187 // do anything.
110 return 0; 188 return 0;
111 } 189 }
(...skipping 15 matching lines...) Expand all
127 IrtThreadNice, 205 IrtThreadNice,
128 }; 206 };
129 207
130 const nacl_irt_tls kIrtTls = { 208 const nacl_irt_tls kIrtTls = {
131 IrtTlsInit, 209 IrtTlsInit,
132 IrtTlsGet, 210 IrtTlsGet,
133 }; 211 };
134 212
135 } // namespace nonsfi 213 } // namespace nonsfi
136 } // namespace nacl 214 } // namespace nacl
OLDNEW
« no previous file with comments | « components/nacl/loader/nonsfi/irt_exception_handling.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698