From owner-freebsd-bugs@FreeBSD.ORG Thu Apr 4 02:10:03 2013 Return-Path: Delivered-To: freebsd-bugs@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 24B54A0E for ; Thu, 4 Apr 2013 02:10:03 +0000 (UTC) (envelope-from bdemsky@uci.edu) Received: from mda3.es.uci.edu (mda3.es.uci.edu [128.200.80.6]) by mx1.freebsd.org (Postfix) with ESMTP id 0FCB8F69 for ; Thu, 4 Apr 2013 02:10:02 +0000 (UTC) Received: from ismtp1.es.uci.edu (ismtp1.es.uci.edu [128.195.153.31]) by mda3.es.uci.edu (8.13.8/8.13.8) with ESMTP id r3425JjZ257077 for ; Wed, 3 Apr 2013 19:05:19 -0700 Received: from dhcp-v000-160.mobile.uci.edu (dhcp-v000-160.mobile.uci.edu [169.234.0.160]) (authenticated bits=0) by ismtp1.es.uci.edu (8.13.8/8.13.8) with ESMTP id r3425CJQ283512 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NOT) for ; Wed, 3 Apr 2013 19:05:13 -0700 X-UCInetID: bdemsky From: Brian Demsky Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable Subject: Bug in swapcontext method Date: Wed, 3 Apr 2013 19:05:18 -0700 Message-Id: To: freebsd-bugs@freebsd.org Mime-Version: 1.0 (Apple Message framework v1283) X-Mailer: Apple Mail (2.1283) X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 04 Apr 2013 02:10:03 -0000 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 : push %r14 0x00007fff901e86b4 : push %rbx 0x00007fff901e86b5 : sub $0x8,%rsp 0x00007fff901e86b9 : test %rdi,%rdi 0x00007fff901e86bc : je 0x7fff901e86c6 = 0x00007fff901e86be : mov %rsi,%rbx 0x00007fff901e86c1 : test %rbx,%rbx 0x00007fff901e86c4 : jne 0x7fff901e86d8 = 0x00007fff901e86c6 : callq 0x7fff90262c88 <__error> 0x00007fff901e86cb : movl $0x16,(%rax) 0x00007fff901e86d1 : mov $0xffffffff,%eax 0x00007fff901e86d6 : jmp 0x7fff901e86f3 = 0x00007fff901e86d8 : mov %rdi,%r14 0x00007fff901e86db : andb $0x7f,0x3(%r14) 0x00007fff901e86e0 : mov %r14,%rdi 0x00007fff901e86e3 : callq 0x7fff901e87af = 0x00007fff901e86e8 : test %eax,%eax 0x00007fff901e86ea : jne 0x7fff901e86f3 = 0x00007fff901e86ec : mov (%r14),%ecx 0x00007fff901e86ef : test %ecx,%ecx 0x00007fff901e86f1 : jns 0x7fff901e86fb = 0x00007fff901e86f3 : add $0x8,%rsp 0x00007fff901e86f7 : pop %rbx 0x00007fff901e86f8 : pop %r14 0x00007fff901e86fa : retq =20 0x00007fff901e86fb : or $0x80000000,%ecx 0x00007fff901e8701 : mov %ecx,(%r14) 0x00007fff901e8704 : mov %rbx,%rdi 0x00007fff901e8707 : add $0x8,%rsp 0x00007fff901e870b : pop %rbx 0x00007fff901e870c : pop %r14 0x00007fff901e870e : jmpq 0x7fff90262855 = 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=