LCOV - code coverage report
Current view: directory - src/trusted/service_runtime - nacl_signal_frame_test.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 17 16 94.1 %
Date: 2012-02-16 Functions: 0 0 -

       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 <signal.h>
       8                 : #include <stdio.h>
       9                 : #include <stdlib.h>
      10                 : #include <string.h>
      11                 : 
      12                 : #include "native_client/src/shared/platform/nacl_check.h"
      13                 : #include "native_client/src/shared/platform/nacl_log.h"
      14                 : #include "native_client/src/trusted/service_runtime/nacl_signal.h"
      15                 : #include "native_client/src/trusted/service_runtime/sel_ldr.h"
      16                 : #include "native_client/src/trusted/service_runtime/sel_rt.h"
      17                 : 
      18                 : 
      19                 : /*
      20                 :  * This test case checks for an obscure gotcha in the Linux kernel.
      21                 :  *
      22                 :  * Some kernels do not assign to the top 2 bytes of the REG_CS array
      23                 :  * entry when writing %cs to the stack.  If NaCl's signal handler does
      24                 :  * not disregard the top 16 bits of REG_CS, it will incorrectly treat
      25                 :  * a fault in trusted code as coming from untrusted code, and it will
      26                 :  * crash while attempting to restore %gs.
      27                 :  *
      28                 :  * Specifically, this happens in 32-bit processes on the 64-bit kernel
      29                 :  * from Ubuntu Hardy.
      30                 :  *
      31                 :  * See http://code.google.com/p/nativeclient/issues/detail?id=1486
      32                 :  */
      33                 : 
      34               1 : int main() {
      35               1 :   size_t stack_size = SIGSTKSZ;
      36                 :   char *stack;
      37                 :   stack_t st;
      38                 :   int rc;
      39                 : 
      40               1 :   NaClLogModuleInit();
      41               1 :   NaClInitGlobals();
      42               1 :   NaClSignalHandlerInit();
      43                 : 
      44                 :   /*
      45                 :    * Allocate and register a signal stack, and ensure that it is
      46                 :    * filled with non-zero bytes.
      47                 :    */
      48               1 :   stack = malloc(stack_size);
      49               1 :   CHECK(stack != NULL);
      50               1 :   memset(stack, 0xff, stack_size);
      51               1 :   st.ss_size = stack_size;
      52               1 :   st.ss_sp = stack;
      53               1 :   st.ss_flags = 0;
      54               1 :   rc = sigaltstack(&st, NULL);
      55               1 :   CHECK(rc == 0);
      56                 : 
      57                 :   /*
      58                 :    * Trigger a signal.  This should produce a "** Signal X from
      59                 :    * trusted code" message, which the test runner checks for.
      60                 :    */
      61               1 :   fprintf(stderr, "** intended_exit_status=trusted_segfault\n");
      62                 : 
      63                 :   /*
      64                 :    * Clang transmutes a NULL pointer reference into a generic "undefined"
      65                 :    * case.  That code crashes with a different signal than an actual bad
      66                 :    * pointer reference, violating the tests' expectations.  A pointer that
      67                 :    * is known bad but is not literally NULL does not get this treatment.
      68                 :    */
      69               1 :   *(volatile int *) 1 = 0;
      70                 : 
      71               1 :   fprintf(stderr, "Should never reach here.\n");
      72               0 :   return 1;
      73                 : }

Generated by: LCOV version 1.7