git: libc - Fix bugs in getcontext(), setcontext(), and swapcontext()

Matthew Dillon dillon at crater.dragonflybsd.org
Mon Dec 21 16:39:20 PST 2015


commit 63261abbc5bc59d5ff6f9015d352ce1782cd1dd7
Author: Matthew Dillon <dillon at apollo.backplane.com>
Date:   Mon Dec 21 00:33:54 2015 -0800

    libc - Fix bugs in getcontext(), setcontext(), and swapcontext()
    
    * Fix multiple bugs revealed by qemu's use of these functions.  Most of
      these fixes are accomplished by calling sigreturn(uctx) to restore the
      state instead of trying to roll our own in userland.  This won't be much
      slower (if at all) because we had to save and restore the signal state
      in the userland code anyway, so we could not avoid making at least one
      system call.
    
      Using sigreturn() handles the signal mask atomicy for us so we don't have
      to deal with it and fixes numerous other issues.  Along with this change,
      adjust getcontext() and makecontext() to fill out additional important
      fields in the ucontext that sigreturn() inspects.
    
    * Fixes two stack corruption bugs. First, getcontext() was calling
      get_mcontext() and get_mcontext() was setting up the setcontext return
      state to return 1 ... from get_mcontext(), NOT from getcontext().  If
      normal operations or signals mess with the stack, the double return
      will not work.  Oops.
    
      Secondly, getcontext scribbled over the red-zone in a way that is not
      permitted.
    
    * setcontext() was restoring the context as saved by makecontext() or
      getcontext(), but setcontext() can also be called with the ucontext
      from the signal handler which requires a full restore.  setcontext()
      was not restoring FPU or scratch registers or rflags.
    
    * Fixes signal restoration bug and corruption that can mess up emulation
      in qemu.
    
    * Fixes issues with qemu related to SMP startup and lack of preemption.
    
    Reported-by: ivadasz

Summary of changes:
 lib/libc/gen/ucontext.c           |  29 +++++------
 lib/libc/x86_64/gen/makecontext.c |  16 +++++-
 lib/libc/x86_64/gen/mcontext.S    |  58 ++++++++++++++++++----
 lib/libc/x86_64/sys/asmcontext.c  |  12 +++++
 lib/libc/x86_64/sys/getcontext.S  | 100 ++++++++++++++++++++++++++++++++------
 5 files changed, 175 insertions(+), 40 deletions(-)

http://gitweb.dragonflybsd.org/dragonfly.git/commitdiff/63261abbc5bc59d5ff6f9015d352ce1782cd1dd7


-- 
DragonFly BSD source repository


More information about the Commits mailing list