Changeset 14066 for branches


Ignore:
Timestamp:
Jul 27, 2010, 11:08:50 PM (9 years ago)
Author:
gb
Message:

Lots of changes to support stack-overflow detection on ARM Linux.
(Write protect the control stack, handle SIGSEGV on an alternate
signal stack ...) The sigaltstack mechanism doesn't work if the
specified signal stack is within the allocated control stack region
(we generally use the top few pages of the control stack on x86;
here, we map a few pages and need to remember to free them when the
thread dies.)
Also: need some recovery mechanism, so that after the thread unwinds
out of the "yellow zone" the yellow zone is re-protected.

Location:
branches/arm/lisp-kernel
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/arm/lisp-kernel/arm-exceptions.c

    r13992 r14066  
    468468        OSErr err;
    469469        extern OSErr save_application(unsigned, Boolean);
    470         TCR *tcr = TCR_FROM_TSD(xpGPR(xp, rcontext));
     470        TCR *tcr = get_tcr(true);
    471471        area *vsarea = tcr->vs_area;
    472472       
     
    563563reset_lisp_process(ExceptionInformation *xp)
    564564{
    565   TCR *tcr = TCR_FROM_TSD(xpGPR(xp,rcontext));
     565  TCR *tcr = get_tcr(true);
    566566  catch_frame *last_catch = (catch_frame *) ptr_from_lispobj(untag(tcr->catch_top));
    567567
     
    694694                signed_natural param)
    695695{
    696   TCR *tcr = TCR_FROM_TSD(xpGPR(xp, rcontext)), *other_tcr;
     696  TCR *tcr = get_tcr(true), *other_tcr;
    697697  int result;
    698698  signed_natural inhibit;
     
    924924do_vsp_overflow (ExceptionInformation *xp, BytePtr addr)
    925925{
    926   TCR* tcr = TCR_FROM_TSD(xpGPR(xp, rcontext));
     926  TCR* tcr = get_tcr(true);
    927927  area *a = tcr->vs_area;
    928928  protected_area_ptr vsp_soft = a->softprot;
     
    941941     signal an error_stack_overflow condition.
    942942      */
    943   do_vsp_overflow(xp,addr);
     943  if (prot_area->why == kVSPsoftguard) {
     944    return do_vsp_overflow(xp,addr);
     945  }
     946  unprotect_area(prot_area);
     947  signal_stack_soft_overflow(xp,Rsp);
     948  return 0;
    944949}
    945950
     
    13991404}
    14001405
     1406#ifdef USE_SIGALTSTACK
     1407void
     1408invoke_handler_on_main_stack(int signo, siginfo_t *info, ExceptionInformation *xp, void *return_address, void *handler)
     1409{
     1410  ExceptionInformation *xp_copy;
     1411  siginfo_t *info_copy;
     1412  extern void call_handler_on_main_stack(int, siginfo_t *, ExceptionInformation *,void *, void *);
     1413 
     1414  BytePtr target_sp= (BytePtr)xpGPR(xp,Rsp);
     1415  target_sp -= sizeof(ucontext_t);
     1416  xp_copy = (ExceptionInformation *)target_sp;
     1417  memmove(target_sp,xp,sizeof(*xp));
     1418  xp_copy->uc_stack.ss_sp = 0;
     1419  xp_copy->uc_stack.ss_size = 0;
     1420  xp_copy->uc_stack.ss_flags = 0;
     1421  xp_copy->uc_link = NULL;
     1422  target_sp -= sizeof(siginfo_t);
     1423  info_copy = (siginfo_t *)target_sp;
     1424  memmove(target_sp,info,sizeof(*info));
     1425  call_handler_on_main_stack(signo, info_copy, xp_copy, return_address, handler);
     1426}
     1427 
     1428void
     1429altstack_signal_handler(int signo, siginfo_t *info, ExceptionInformation *xp)
     1430{
     1431  TCR *tcr=get_tcr(true);
     1432  if (signo == SIGSEGV) {
     1433    BytePtr addr = (BytePtr)(xp->uc_mcontext.fault_address);
     1434    area *a = tcr->cs_area;
     1435   
     1436    if ((addr >= a->low) &&
     1437        (addr < a->softlimit)) {
     1438      if (addr < a->hardlimit) {
     1439        Bug(xp, "hard stack overflow");
     1440      } else {
     1441        UnProtectMemory(a->hardlimit,a->softlimit-a->hardlimit);
     1442      }
     1443    }
     1444  }
     1445  invoke_handler_on_main_stack(signo, info, xp, __builtin_return_address(0), signal_handler);
     1446}
     1447#endif
     1448
    14011449/*
    14021450  If it looks like we're in the middle of an atomic operation, make
     
    16101658}
    16111659
    1612 
    1613 
    1614 void
    1615 install_signal_handler(int signo, void *handler)
     1660#ifdef USE_SIGALTSTACK
     1661void
     1662altstack_interrupt_handler(int signum, siginfo_t *info, ExceptionInformation *context)
     1663{
     1664  invoke_handler_on_main_stack(signum, info, context, __builtin_return_address(0),interrupt_handler);
     1665}
     1666#endif
     1667
     1668
     1669void
     1670install_signal_handler(int signo, void *handler, Boolean system_p, Boolean on_altstack)
    16161671{
    16171672  struct sigaction sa;
     
    16221677    0 /* SA_RESTART */
    16231678    | SA_SIGINFO
     1679#ifdef USE_SIGALTSTACK
     1680    | (on_altstack ? SA_ONSTACK : 0)
     1681#endif
    16241682    ;
    16251683
    16261684  sigaction(signo, &sa, NULL);
    16271685}
     1686
    16281687
    16291688void
     
    16421701    ;
    16431702  if (install_signal_handlers_for_exceptions) {
    1644     extern int no_sigtrap;
    1645     install_signal_handler(SIGILL, (void *)signal_handler);
    1646     if (no_sigtrap != 1) {
    1647       install_signal_handler(SIGTRAP, (void *)signal_handler);
    1648     }
    1649     install_signal_handler(SIGBUS,  (void *)signal_handler);
    1650     install_signal_handler(SIGSEGV, (void *)signal_handler);
    1651     install_signal_handler(SIGFPE, (void *)signal_handler);
     1703    install_signal_handler(SIGILL, (void *)signal_handler, true, false);
     1704    install_signal_handler(SIGSEGV, (void *)ALTSTACK(signal_handler),true, true);
     1705
    16521706  }
    16531707 
    16541708  install_signal_handler(SIGNAL_FOR_PROCESS_INTERRUPT,
    1655                          (void *)interrupt_handler);
     1709                         (void *)interrupt_handler, true, false);
    16561710  signal(SIGPIPE, SIG_IGN);
    16571711}
     1712
     1713#ifdef USE_SIGALTSTACK
     1714void
     1715setup_sigaltstack(area *a)
     1716{
     1717  stack_t stack;
     1718#if 0
     1719  stack.ss_sp = a->low;
     1720  a->low += SIGSTKSZ*8;
     1721#endif
     1722  stack.ss_size = SIGSTKSZ*8;
     1723  stack.ss_flags = 0;
     1724  stack.ss_sp = mmap(NULL,stack.ss_size, PROT_READ|PROT_WRITE|PROT_EXEC,MAP_ANON|MAP_PRIVATE,-1,0);
     1725  if (sigaltstack(&stack, NULL) != 0) {
     1726    perror("sigaltstack");
     1727    exit(-1);
     1728  }
     1729}
     1730#endif
    16581731
    16591732void
     
    16821755}
    16831756
     1757#ifdef USE_SIGALTSTACK
     1758void
     1759altstack_thread_kill_handler(int signo, siginfo_t *info, ExceptionInformation *xp)
     1760{
     1761  invoke_handler_on_main_stack(signo, info, xp, __builtin_return_address(0), thread_kill_handler);
     1762}
     1763#endif
     1764
    16841765void
    16851766thread_signal_setup()
     
    16881769  thread_kill_signal = SIG_KILL_THREAD;
    16891770
    1690   install_signal_handler(thread_suspend_signal, (void *) suspend_resume_handler);
    1691   install_signal_handler(thread_kill_signal, (void *)thread_kill_handler);
     1771  install_signal_handler(thread_suspend_signal, (void *) suspend_resume_handler, true, false);
     1772  install_signal_handler(thread_kill_signal, (void *)thread_kill_handler, true, false);
    16921773}
    16931774
  • branches/arm/lisp-kernel/arm-exceptions.h

    r13989 r14066  
    148148extern natural ror(natural, natural);
    149149#endif
     150
     151#ifdef DARWIN
     152#undef USE_SIGALTSTACK
     153#else
     154#define USE_SIGALTSTACK 1
     155#endif
     156
     157#ifdef USE_SIGALTSTACK
     158void
     159invoke_handler_on_main_stack(int, siginfo_t*, ExceptionInformation *, void *, void*);
     160#endif
     161
     162#ifdef USE_SIGALTSTACK
     163#define ALTSTACK(handler) altstack_ ## handler
     164#else
     165#define ALTSTACK(handler) handler
     166#endif
  • branches/arm/lisp-kernel/lisp.h

    r13629 r14066  
    9595extern FILE *dbgout;
    9696
     97void
     98install_signal_handler(int, void*, Boolean, Boolean);
     99
    97100#endif /* __lisp__ */
  • branches/arm/lisp-kernel/memory.c

    r13431 r14066  
    350350  if (status) {
    351351    status = errno;
     352   
     353    if (status == ENOMEM) {
     354      void *mapaddr = mmap(addr,nbytes, PROT_READ | PROT_EXEC, MAP_ANON|MAP_PRIVATE|MAP_FIXED,-1,0);
     355      if (mapaddr != MAP_FAILED) {
     356        return 0;
     357      }
     358    }
    352359    Bug(NULL, "couldn't protect " DECIMAL " bytes at " LISP ", errno = %d", nbytes, addr, status);
    353360  }
  • branches/arm/lisp-kernel/platform-linuxarm.h

    r13962 r14066  
    4747#include "os-linux.h"
    4848
     49#define PROTECT_CSTACK 1
  • branches/arm/lisp-kernel/pmcl-kernel.c

    r13789 r14066  
    170170ensure_stack_limit(size_t stack_size)
    171171{
    172 #ifdef WINDOWS
    173172  extern void os_get_current_thread_stack_bounds(void **, natural*);
    174173  natural totalsize;
     
    176175 
    177176  os_get_current_thread_stack_bounds(&ignored, &totalsize);
     177#ifdef WINDOWS
    178178
    179179  return (size_t)totalsize-(size_t)(CSTACK_HARDPROT+CSTACK_SOFTPROT);
     
    314314#ifdef USE_SIGALTSTACK
    315315  setup_sigaltstack(a);
     316#endif
     317#ifdef PROTECT_CSTACK
     318  a->softprot=new_protected_area(a->hardlimit,a->softlimit,kSPsoftguard,CSTACK_SOFTPROT,true);
     319  a->hardprot=new_protected_area(lowlimit,a->hardlimit,kSPhardguard,CSTACK_HARDPROT,true);
    316320#endif
    317321  add_area_holding_area_lock(a);
     
    785789  SetConsoleCtrlHandler(ControlEventHandler,TRUE);
    786790#else
    787   install_signal_handler(SIGINT, (void *)user_signal_handler);
    788   install_signal_handler(SIGTERM, (void *)user_signal_handler);
     791  install_signal_handler(SIGINT, (void *)user_signal_handler, false, false);
     792  install_signal_handler(SIGTERM, (void *)user_signal_handler, false, false);
    789793#endif
    790794}
Note: See TracChangeset for help on using the changeset viewer.