Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / native_client / src / trusted / service_runtime / linux / nacl_signal.c
1 /*
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
4  * found in the LICENSE file.
5  */
6
7 #include <errno.h>
8 #include <signal.h>
9 #include <stddef.h>
10 #include <string.h>
11
12 #include "native_client/src/include/nacl_macros.h"
13 #include "native_client/src/include/portability_io.h"
14 #include "native_client/src/shared/platform/nacl_check.h"
15 #include "native_client/src/shared/platform/nacl_exit.h"
16 #include "native_client/src/shared/platform/nacl_log.h"
17 #include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h"
18 #include "native_client/src/trusted/service_runtime/nacl_app_thread.h"
19 #include "native_client/src/trusted/service_runtime/nacl_config.h"
20 #include "native_client/src/trusted/service_runtime/nacl_exception.h"
21 #include "native_client/src/trusted/service_runtime/nacl_globals.h"
22 #include "native_client/src/trusted/service_runtime/nacl_signal.h"
23 #include "native_client/src/trusted/service_runtime/nacl_tls.h"
24 #include "native_client/src/trusted/service_runtime/sel_ldr.h"
25 #include "native_client/src/trusted/service_runtime/sel_rt.h"
26 #include "native_client/src/trusted/service_runtime/thread_suspension.h"
27
28
29 /*
30  * This module is based on the Posix signal model.  See:
31  * http://www.opengroup.org/onlinepubs/009695399/functions/sigaction.html
32  */
33
34 /*
35  * The signals listed here should either be handled by NaCl (or otherwise
36  * trusted code).
37  */
38 static int s_Signals[] = {
39 #if NACL_ARCH(NACL_BUILD_ARCH) != NACL_mips
40   /* This signal does not exist on MIPS. */
41   SIGSTKFLT,
42 #endif
43   SIGSYS, /* Used to support a seccomp-bpf sandbox. */
44   NACL_THREAD_SUSPEND_SIGNAL,
45   SIGINT, SIGQUIT, SIGILL, SIGTRAP, SIGBUS, SIGFPE, SIGSEGV,
46   /* Handle SIGABRT in case someone sends it asynchronously using kill(). */
47   SIGABRT
48 };
49
50 static struct sigaction s_OldActions[NACL_ARRAY_SIZE_UNSAFE(s_Signals)];
51
52 static NaClSignalHandler g_handler_func;
53
54 void NaClSignalHandlerSet(NaClSignalHandler func) {
55   g_handler_func = func;
56 }
57
58 /*
59  * Returns, via is_untrusted, whether the signal happened while
60  * executing untrusted code.
61  *
62  * Returns, via result_thread, the NaClAppThread that untrusted code
63  * was running in.
64  *
65  * Note that this should only be called from the thread in which the
66  * signal occurred, because on x86-64 it reads a thread-local variable
67  * (nacl_current_thread).
68  */
69 static void GetCurrentThread(const struct NaClSignalContext *sig_ctx,
70                              int *is_untrusted,
71                              struct NaClAppThread **result_thread) {
72 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
73   /*
74    * For x86-32, if %cs does not match, it is untrusted code.
75    *
76    * Note that this check might not be valid on Mac OS X, because
77    * thread_get_state() does not return the value of NaClGetGlobalCs()
78    * for a thread suspended inside a syscall.  However, this code is
79    * not used on Mac OS X.
80    */
81   *is_untrusted = (NaClGetGlobalCs() != sig_ctx->cs);
82   *result_thread = NaClAppThreadGetFromIndex(sig_ctx->gs >> 3);
83 #elif (NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64) || \
84       NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm || \
85       NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
86   struct NaClAppThread *natp = NaClTlsGetCurrentThread();
87   if (natp == NULL) {
88     *is_untrusted = 0;
89     *result_thread = NULL;
90   } else {
91     /*
92      * Get the address of an arbitrary local, stack-allocated variable,
93      * just for the purpose of doing a sanity check.
94      */
95     void *pointer_into_stack = &natp;
96     /*
97      * Sanity check: Make sure the stack we are running on is not
98      * allocated in untrusted memory.  This checks that the alternate
99      * signal stack is correctly set up, because otherwise, if it is
100      * not set up, the test case would not detect that.
101      *
102      * There is little point in doing a CHECK instead of a DCHECK,
103      * because if we are running off an untrusted stack, we have already
104      * lost.
105      */
106     DCHECK(!NaClIsUserAddr(natp->nap, (uintptr_t) pointer_into_stack));
107     *is_untrusted = NaClIsUserAddr(natp->nap, sig_ctx->prog_ctr);
108     *result_thread = natp;
109   }
110 #else
111 # error Unsupported architecture
112 #endif
113
114   /*
115    * Trusted code could accidentally jump into sandbox address space,
116    * so don't rely on prog_ctr on its own for determining whether a
117    * crash comes from untrusted code.  We don't want to restore
118    * control to an untrusted exception handler if trusted code
119    * crashes.
120    */
121   if (*is_untrusted &&
122       ((*result_thread)->suspend_state & NACL_APP_THREAD_UNTRUSTED) == 0) {
123     *is_untrusted = 0;
124   }
125 }
126
127 static void FindAndRunHandler(int sig, siginfo_t *info, void *uc) {
128   unsigned int a;
129
130   /* If we need to keep searching, try the old signal handler. */
131   for (a = 0; a < NACL_ARRAY_SIZE(s_Signals); a++) {
132     /* If we handle this signal */
133     if (s_Signals[a] == sig) {
134       /* If this is a real sigaction pointer... */
135       if ((s_OldActions[a].sa_flags & SA_SIGINFO) != 0) {
136         /*
137          * On Mac OS X, sigaction() can return a "struct sigaction"
138          * with SA_SIGINFO set but with a NULL sa_sigaction if no
139          * signal handler was previously registered.  This is allowed
140          * by POSIX, which does not require a struct returned by
141          * sigaction() to be intelligible.  We check for NULL here to
142          * avoid a crash.
143          */
144         if (s_OldActions[a].sa_sigaction != NULL) {
145           /* then call the old handler. */
146           s_OldActions[a].sa_sigaction(sig, info, uc);
147           break;
148         }
149       } else {
150         /* otherwise check if it is a real signal pointer */
151         if ((s_OldActions[a].sa_handler != SIG_DFL) &&
152             (s_OldActions[a].sa_handler != SIG_IGN)) {
153           /* and call the old signal. */
154           s_OldActions[a].sa_handler(sig);
155           break;
156         }
157       }
158       /*
159        * We matched the signal, but didn't handle it, so we emulate
160        * the default behavior which is to exit the app with the signal
161        * number as the error code.
162        */
163       NaClExit(-sig);
164     }
165   }
166 }
167
168 /*
169  * This function checks whether we can dispatch the signal to an
170  * untrusted exception handler.  If we can, it modifies the register
171  * state to call the handler and writes a stack frame into into
172  * untrusted address space, and returns true.  Otherwise, it returns
173  * false.
174  */
175 static int DispatchToUntrustedHandler(struct NaClAppThread *natp,
176                                       struct NaClSignalContext *regs) {
177   struct NaClApp *nap = natp->nap;
178   uintptr_t frame_addr;
179   volatile struct NaClExceptionFrame *frame;
180   uint32_t new_stack_ptr;
181   uintptr_t context_user_addr;
182
183   if (!NaClSignalCheckSandboxInvariants(regs, natp)) {
184     return 0;
185   }
186   if (nap->exception_handler == 0) {
187     return 0;
188   }
189   if (natp->exception_flag) {
190     return 0;
191   }
192
193   natp->exception_flag = 1;
194
195   if (natp->exception_stack == 0) {
196     new_stack_ptr = regs->stack_ptr - NACL_STACK_RED_ZONE;
197   } else {
198     new_stack_ptr = natp->exception_stack;
199   }
200   /* Allocate space for the stack frame, and ensure its alignment. */
201   new_stack_ptr -=
202       sizeof(struct NaClExceptionFrame) - NACL_STACK_PAD_BELOW_ALIGN;
203   new_stack_ptr = new_stack_ptr & ~NACL_STACK_ALIGN_MASK;
204   new_stack_ptr -= NACL_STACK_ARGS_SIZE;
205   new_stack_ptr -= NACL_STACK_PAD_BELOW_ALIGN;
206   frame_addr = NaClUserToSysAddrRange(nap, new_stack_ptr,
207                                       sizeof(struct NaClExceptionFrame));
208   if (frame_addr == kNaClBadAddress) {
209     /* We cannot write the stack frame. */
210     return 0;
211   }
212   context_user_addr = new_stack_ptr + offsetof(struct NaClExceptionFrame,
213                                                context);
214
215   frame = (struct NaClExceptionFrame *) frame_addr;
216   NaClSignalSetUpExceptionFrame(frame, regs, context_user_addr);
217
218 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
219   regs->prog_ctr = nap->exception_handler;
220   regs->stack_ptr = new_stack_ptr;
221 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
222   regs->rdi = context_user_addr; /* Argument 1 */
223   regs->prog_ctr = NaClUserToSys(nap, nap->exception_handler);
224   regs->stack_ptr = NaClUserToSys(nap, new_stack_ptr);
225 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_arm
226   /*
227    * Returning from the exception handler is not possible, so to avoid
228    * any confusion that might arise from jumping to an uninitialised
229    * address, we set the return address to zero.
230    */
231   regs->lr = 0;
232   regs->r0 = context_user_addr;  /* Argument 1 */
233   regs->prog_ctr = NaClUserToSys(nap, nap->exception_handler);
234   regs->stack_ptr = NaClUserToSys(nap, new_stack_ptr);
235 #elif NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips
236   regs->return_addr = 0;
237   regs->a0 = context_user_addr;
238   regs->prog_ctr = NaClUserToSys(nap, nap->exception_handler);
239   regs->stack_ptr = NaClUserToSys(nap, new_stack_ptr);
240   /*
241    * Per Linux/MIPS convention, PIC functions assume that t9 holds
242    * the function's address on entry.
243    */
244   regs->t9 = regs->prog_ctr;
245 #else
246 # error Unsupported architecture
247 #endif
248
249 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
250   regs->flags &= ~NACL_X86_DIRECTION_FLAG;
251 #endif
252
253   return 1;
254 }
255
256 static void SignalCatch(int sig, siginfo_t *info, void *uc) {
257   struct NaClSignalContext sig_ctx;
258   int is_untrusted;
259   struct NaClAppThread *natp;
260
261 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86
262   /*
263    * Reset the x86 direction flag.  New versions of gcc and libc
264    * assume that the direction flag is clear on entry to a function,
265    * as the x86 ABI requires.  However, untrusted code can set this
266    * flag, and versions of Linux before 2.6.25 do not clear the flag
267    * before running the signal handler, so we clear it here for safety.
268    * See http://code.google.com/p/nativeclient/issues/detail?id=1495
269    */
270   __asm__("cld");
271 #endif
272
273   NaClSignalContextFromHandler(&sig_ctx, uc);
274   GetCurrentThread(&sig_ctx, &is_untrusted, &natp);
275
276 #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 32
277   /*
278    * On Linux, the kernel does not restore %gs when entering the
279    * signal handler, so we must do that here.  We need to do this for
280    * TLS to work and for glibc's syscall wrappers to work, because
281    * some builds of glibc fetch a syscall function pointer from the
282    * static TLS area.  There is the potential for vulnerabilities if
283    * we call glibc without restoring %gs (such as
284    * http://code.google.com/p/nativeclient/issues/detail?id=1607),
285    * although the risk is reduced because the untrusted %gs segment
286    * has an extent of only 4 bytes (see
287    * http://code.google.com/p/nativeclient/issues/detail?id=2176).
288    *
289    * Note that, in comparison, Breakpad tries to avoid using libc
290    * calls at all when a crash occurs.
291    *
292    * For comparison, on Mac OS X, the kernel *does* restore the
293    * original %gs when entering the signal handler.  On Mac, our
294    * assignment to %gs here wouldn't be necessary, but it wouldn't be
295    * harmful either.  However, this code is not currently used on Mac
296    * OS X.
297    *
298    * Both Linux and Mac OS X necessarily restore %cs, %ds, and %ss
299    * otherwise we would have a hard time handling signals generated by
300    * untrusted code at all.
301    *
302    * Note that we check natp (which is based on %gs) rather than
303    * is_untrusted (which is based on %cs) because we need to handle
304    * the case where %gs is set to the untrusted-code value but %cs is
305    * not.
306    *
307    * GCC's stack protector (-fstack-protector) will make use of %gs even before
308    * we have a chance to restore it. It is important that this function is not
309    * compiled with -fstack-protector.
310    */
311   if (natp != NULL) {
312     NaClSetGs(natp->user.trusted_gs);
313   }
314 #endif
315
316   if (sig != SIGINT && sig != SIGQUIT) {
317     if (NaClThreadSuspensionSignalHandler(sig, &sig_ctx, is_untrusted, natp)) {
318       NaClSignalContextToHandler(uc, &sig_ctx);
319       /* Resume untrusted code using possibly modified register state. */
320       return;
321     }
322   }
323
324   if (is_untrusted &&
325       (sig == SIGSEGV || sig == SIGILL || sig == SIGFPE ||
326        (NACL_ARCH(NACL_BUILD_ARCH) == NACL_mips && sig == SIGTRAP))) {
327     if (DispatchToUntrustedHandler(natp, &sig_ctx)) {
328       NaClSignalContextToHandler(uc, &sig_ctx);
329       /* Resume untrusted code using the modified register state. */
330       return;
331     }
332   }
333
334   if (g_handler_func != NULL) {
335     g_handler_func(sig, &sig_ctx, is_untrusted);
336     return;
337   }
338
339   NaClSignalHandleUntrusted(sig, &sig_ctx, is_untrusted);
340
341   FindAndRunHandler(sig, info, uc);
342 }
343
344
345 /*
346  * Check that the current process has no signal handlers registered
347  * that we won't override with safe handlers.
348  *
349  * We want to discourage Chrome or libraries from registering signal
350  * handlers themselves, because those signal handlers are often not
351  * safe when triggered from untrusted code.  For background, see:
352  * http://code.google.com/p/nativeclient/issues/detail?id=1607
353  */
354 static void AssertNoOtherSignalHandlers(void) {
355   unsigned int index;
356   int signum;
357   char handled_by_nacl[NSIG];
358
359   /* 0 is not a valid signal number. */
360   for (signum = 1; signum < NSIG; signum++) {
361     handled_by_nacl[signum] = 0;
362   }
363   for (index = 0; index < NACL_ARRAY_SIZE(s_Signals); index++) {
364     signum = s_Signals[index];
365     CHECK(signum > 0);
366     CHECK(signum < NSIG);
367     handled_by_nacl[signum] = 1;
368   }
369   for (signum = 1; signum < NSIG; signum++) {
370     struct sigaction sa;
371
372     if (handled_by_nacl[signum])
373       continue;
374
375     if (sigaction(signum, NULL, &sa) != 0) {
376       /*
377        * Don't complain if the kernel does not consider signum to be a
378        * valid signal number, which produces EINVAL.
379        */
380       if (errno != EINVAL) {
381         NaClLog(LOG_FATAL, "AssertNoOtherSignalHandlers: "
382                 "sigaction() call failed for signal %d: errno=%d\n",
383                 signum, errno);
384       }
385     } else {
386       if ((sa.sa_flags & SA_SIGINFO) == 0) {
387         if (sa.sa_handler == SIG_DFL || sa.sa_handler == SIG_IGN)
388           continue;
389       } else {
390         /*
391          * It is not strictly legal for sa_sigaction to contain NULL
392          * or SIG_IGN, but Valgrind reports SIG_IGN for signal 64, so
393          * we allow it here.
394          */
395         if (sa.sa_sigaction == NULL ||
396             sa.sa_sigaction == (void (*)(int, siginfo_t *, void *)) SIG_IGN)
397           continue;
398       }
399       NaClLog(LOG_FATAL, "AssertNoOtherSignalHandlers: "
400               "A signal handler is registered for signal %d\n", signum);
401     }
402   }
403 }
404
405 void NaClSignalHandlerInit(void) {
406   struct sigaction sa;
407   unsigned int a;
408
409   /*
410    * Android adds a handler for SIGPIPE in the dynamic linker.
411    */
412   if (NACL_ANDROID)
413     CHECK(signal(SIGPIPE, SIG_IGN) != SIG_ERR);
414
415   AssertNoOtherSignalHandlers();
416
417   memset(&sa, 0, sizeof(sa));
418   sigemptyset(&sa.sa_mask);
419   sa.sa_sigaction = SignalCatch;
420   sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
421
422   /*
423    * Mask all signals we catch to prevent re-entry.
424    *
425    * In particular, NACL_THREAD_SUSPEND_SIGNAL must be masked while we
426    * are handling a fault from untrusted code, otherwise the
427    * suspension signal will interrupt the trusted fault handler.  That
428    * would cause NaClAppThreadGetSuspendedRegisters() to report
429    * trusted-code register state rather than untrusted-code register
430    * state from the point where the fault occurred.
431    */
432   for (a = 0; a < NACL_ARRAY_SIZE(s_Signals); a++) {
433     sigaddset(&sa.sa_mask, s_Signals[a]);
434   }
435
436   /* Install all handlers */
437   for (a = 0; a < NACL_ARRAY_SIZE(s_Signals); a++) {
438     if (sigaction(s_Signals[a], &sa, &s_OldActions[a]) != 0) {
439       NaClLog(LOG_FATAL, "Failed to install handler for %d.\n\tERR:%s\n",
440                           s_Signals[a], strerror(errno));
441     }
442   }
443 }
444
445 void NaClSignalHandlerFini(void) {
446   unsigned int a;
447
448   /* Remove all handlers */
449   for (a = 0; a < NACL_ARRAY_SIZE(s_Signals); a++) {
450     if (sigaction(s_Signals[a], &s_OldActions[a], NULL) != 0) {
451       NaClLog(LOG_FATAL, "Failed to unregister handler for %d.\n\tERR:%s\n",
452                           s_Signals[a], strerror(errno));
453     }
454   }
455 }