>Number:         177624
>Category:       misc
>Synopsis:       Swapcontext can get compiled incorrectly
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 04 02:40:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Brian Demsky
>Release:        OS X distribution of libc
>Organization:
UCI
>Environment:
>Description:
Here is the code for swap context:

int
swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
{
      int ret;

      if ((oucp == NULL) || (ucp == NULL)) {
              errno = EINVAL;
              return (-1);
      }
      oucp->uc_flags &= ~UCF_SWAPPED;
      ret = getcontext(oucp);
      if ((ret == 0) && !(oucp->uc_flags & UCF_SWAPPED)) {
              oucp->uc_flags |= UCF_SWAPPED;
              ret = setcontext(ucp);
      }
      return (ret);
}

On the OS X port of libc in Mac OSX 10.7.5, this gets compiled as:

0x00007fff901e86b2 <swapcontext+0>:     push   %r14
0x00007fff901e86b4 <swapcontext+2>:     push   %rbx
0x00007fff901e86b5 <swapcontext+3>:     sub    $0x8,%rsp
0x00007fff901e86b9 <swapcontext+7>:     test   %rdi,%rdi
0x00007fff901e86bc <swapcontext+10>:    je     0x7fff901e86c6 <swapcontext+20>
0x00007fff901e86be <swapcontext+12>:    mov    %rsi,%rbx
0x00007fff901e86c1 <swapcontext+15>:    test   %rbx,%rbx
0x00007fff901e86c4 <swapcontext+18>:    jne    0x7fff901e86d8 <swapcontext+38>
0x00007fff901e86c6 <swapcontext+20>:    callq  0x7fff90262c88 <__error>
0x00007fff901e86cb <swapcontext+25>:    movl   $0x16,(%rax)
0x00007fff901e86d1 <swapcontext+31>:    mov    $0xffffffff,%eax
0x00007fff901e86d6 <swapcontext+36>:    jmp    0x7fff901e86f3 <swapcontext+65>
0x00007fff901e86d8 <swapcontext+38>:    mov    %rdi,%r14
0x00007fff901e86db <swapcontext+41>:    andb   $0x7f,0x3(%r14)
0x00007fff901e86e0 <swapcontext+46>:    mov    %r14,%rdi
0x00007fff901e86e3 <swapcontext+49>:    callq  0x7fff901e87af <getcontext>
0x00007fff901e86e8 <swapcontext+54>:    test   %eax,%eax
0x00007fff901e86ea <swapcontext+56>:    jne    0x7fff901e86f3 <swapcontext+65>
0x00007fff901e86ec <swapcontext+58>:    mov    (%r14),%ecx
0x00007fff901e86ef <swapcontext+61>:    test   %ecx,%ecx
0x00007fff901e86f1 <swapcontext+63>:    jns    0x7fff901e86fb <swapcontext+73>
0x00007fff901e86f3 <swapcontext+65>:    add    $0x8,%rsp
0x00007fff901e86f7 <swapcontext+69>:    pop    %rbx
0x00007fff901e86f8 <swapcontext+70>:    pop    %r14
0x00007fff901e86fa <swapcontext+72>:    retq   
0x00007fff901e86fb <swapcontext+73>:    or     $0x80000000,%ecx
0x00007fff901e8701 <swapcontext+79>:    mov    %ecx,(%r14)
0x00007fff901e8704 <swapcontext+82>:    mov    %rbx,%rdi
0x00007fff901e8707 <swapcontext+85>:    add    $0x8,%rsp
0x00007fff901e870b <swapcontext+89>:    pop    %rbx
0x00007fff901e870c <swapcontext+90>:    pop    %r14
0x00007fff901e870e <swapcontext+92>:    jmpq   0x7fff90262855 <setcontext>

The problem is that rbx is callee saved by compiled version of swapcontext and 
then reused before getcontext is called.  Getcontext then stores the wrong 
value for rbx and setcontext later restores the wrong value for rbx.  If the 
caller had any value in rbx, it has been trashed at this point.

Brian
>How-To-Repeat:

>Fix:


>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to