This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug nptl/2644] Race condition during unwind code after thread cancellation


------- Additional Comments From batneil at thebatcave dot org dot uk  2006-05-07 14:14 -------
To clarify how the problem manifests, here's a snippet of the compiled
_Unwind_ForcedUnwind code from the unpatched libc:

00941360 <_Unwind_ForcedUnwind>:
[...]
  941377:       8b 93 ac 21 00 00       mov    0x21ac(%ebx),%edx
  94137d:       89 7d fc                mov    %edi,0xfffffffc(%ebp)
  941380:       85 d2                   test   %edx,%edx
  941382:       74 23                   je     9413a7 
  941384:       8b 75 10                mov    0x10(%ebp),%esi
  941387:       8b 4d 0c                mov    0xc(%ebp),%ecx
  94138a:       8b 45 08                mov    0x8(%ebp),%eax
  94138d:       89 74 24 08             mov    %esi,0x8(%esp)
  941391:       89 4c 24 04             mov    %ecx,0x4(%esp)
  941395:       89 04 24                mov    %eax,(%esp)
  941398:       ff d2                   call   *%edx
[...]
  9413a6:       c3                      ret
  9413a7:       8b 83 b0 21 00 00       mov    0x21b0(%ebx),%eax
  9413ad:       85 c0                   test   %eax,%eax
  9413af:       75 d3                   jne    941384

If the test at 941380 shows that edx (which is libgcc_s_forcedunwind) contains
0, and the test at 9413ad shows that eax (libgcc_s_getcfa) is non-zero, we jump
back to 941384 and try to call edx without having changed it from 0.

After patching and rebuilding on my system the following code results:

0000c360 <_Unwind_ForcedUnwind>:
[...]
    c377:       8b 83 ac 21 00 00       mov    0x21ac(%ebx),%eax
    c37d:       89 7d fc                mov    %edi,0xfffffffc(%ebp)
    c380:       85 c0                   test   %eax,%eax
    c382:       74 29                   je     c3ad <_Unwind_ForcedUnwind+0x4d>
    c384:       8b 7d 10                mov    0x10(%ebp),%edi
    c387:       8b 75 0c                mov    0xc(%ebp),%esi
    c38a:       8b 4d 08                mov    0x8(%ebp),%ecx
    c38d:       89 7c 24 08             mov    %edi,0x8(%esp)
    c391:       8b 83 ac 21 00 00       mov    0x21ac(%ebx),%eax
    c397:       89 74 24 04             mov    %esi,0x4(%esp)
    c39b:       89 0c 24                mov    %ecx,(%esp)
    c39e:       ff d0                   call   *%eax
[...]
    c3ac:       c3                      ret
    c3ad:       8b 93 b0 21 00 00       mov    0x21b0(%ebx),%edx
    c3b3:       85 d2                   test   %edx,%edx
    c3b5:       75 cd                   jne    c384 <_Unwind_ForcedUnwind+0x24>

In this case eax is used for libgcc_s_forcedunwind, and after returning from the
(inlined) pthread_cancel_init we now reload eax at c391 before calling it.

This bug seems to exist in current CVS and could probably affect most platforms.
 I've searched for any previous reports and the closest I got was the patch
proposed in http://sourceware.org/ml/libc-hacker/2005-11/msg00010.html, which
fixes a different problem with the same code.

I can provide more details of compiler versions etc if required.

-- 


http://sourceware.org/bugzilla/show_bug.cgi?id=2644

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]