Date: Wed, 3 Apr 2013 19:05:18 -0700 From: Brian Demsky <bdemsky@uci.edu> To: freebsd-bugs@freebsd.org Subject: Bug in swapcontext method Message-ID: <F99A8507-A452-4FFD-BC73-544578DE812D@uci.edu>
next in thread | raw e-mail | index | archive | help
Here is the code for swap context: int swapcontext(ucontext_t *oucp, const ucontext_t *ucp) { int ret; if ((oucp =3D=3D NULL) || (ucp =3D=3D NULL)) { errno =3D EINVAL; return (-1); } oucp->uc_flags &=3D ~UCF_SWAPPED; ret =3D getcontext(oucp); if ((ret =3D=3D 0) && !(oucp->uc_flags & UCF_SWAPPED)) { oucp->uc_flags |=3D UCF_SWAPPED; ret =3D setcontext(ucp); } return (ret); } On the OS X port of libc, 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 =20 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=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?F99A8507-A452-4FFD-BC73-544578DE812D>