Description of Problem: In glibc-2.2.4-19.3, __mpn_construct_double has been compiled incorrectly. The generated code stores and fetches at addresses below the stack pointer. If a signal is delivered at just the right time, then the result of __mpn_construct_double will be bad because the storage is overwritten by signal delivery. __mpn_construct_double is used by strtod [for certain[ and *scanf [probably]. Version-Release number of selected component (if applicable): gblic-2.2.4-19.3 How Reproducible: Inspect code using gdb. Steps to Reproduce: gdb /lib/libc.so.6 x/35i __mpn_construct_double --also-- gdb /lib/i686/libc.so.6 x/35i __mpn_construct_double Actual Results: for i686 [i386 is same except begins at 0x55810]: 0x55740 <__mpn_construct_double>: push %ebp 0x55741 <__mpn_construct_double+1>: mov %esp,%ebp 0x55743 <__mpn_construct_double+3>: mov 0x10(%ebp),%eax 0x55746 <__mpn_construct_double+6>: push %edi 0x55747 <__mpn_construct_double+7>: mov %edi,%edx 0x55749 <__mpn_construct_double+9>: and $0x7fffffff,%edx 0x5574f <__mpn_construct_double+15>: push %esi ## frame size is 8 bytes 0x55750 <__mpn_construct_double+16>: shl $0x1f,%eax 0x55753 <__mpn_construct_double+19>: mov 0x8(%ebp),%ecx 0x55756 <__mpn_construct_double+22>: mov %edx,%edi 0x55758 <__mpn_construct_double+24>: or %eax,%edi 0x5575a <__mpn_construct_double+26>: mov 0xc(%ebp),%eax 0x5575d <__mpn_construct_double+29>: mov %edi,%edx 0x5575f <__mpn_construct_double+31>: and $0x800fffff,%edx 0x55765 <__mpn_construct_double+37>: add $0x3ff,%eax 0x5576a <__mpn_construct_double+42>: and $0x7ff,%eax 0x5576f <__mpn_construct_double+47>: mov (%ecx),%esi 0x55771 <__mpn_construct_double+49>: shl $0x14,%eax 0x55774 <__mpn_construct_double+52>: mov %edx,%edi 0x55776 <__mpn_construct_double+54>: mov 0x4(%ecx),%edx 0x55779 <__mpn_construct_double+57>: or %eax,%edi 0x5577b <__mpn_construct_double+59>: mov %esi,0xfffffff0(%ebp) ## requires 16 bytes of local stack frame # change above to pushl %edi; pushl %esi; nop 0x5577e <__mpn_construct_double+62>: mov %edi,%eax 0x55780 <__mpn_construct_double+64>: and $0xfffff,%edx 0x55786 <__mpn_construct_double+70>: pop %esi # change above to nop 0x55787 <__mpn_construct_double+71>: and $0xfff00000,%eax 0x5578c <__mpn_construct_double+76>: mov %eax,%edi 0x5578e <__mpn_construct_double+78>: or %edx,%edi 0x55790 <__mpn_construct_double+80>: mov %edi,0xfffffff4(%ebp) 0x55793 <__mpn_construct_double+83>: pop %edi # change above to nop 0x55794 <__mpn_construct_double+84>: fldl 0xfffffff0(%ebp) # change to popl %esi; popl %edi; popl %esi; popl %edi; popl %ebp; ret; nop; nop; nop 0x55797 <__mpn_construct_double+87>: pop %ebp 0x55798 <__mpn_construct_double+88>: ret 0x55799 <__mpn_construct_double+89>: lea 0x0(%esi,1),%esi 0x557a0<__mpn_construct_long_double>: push %ebp Expected Results: Additional Information: As a workaround, the code can be binary patched in place as noted above. The gdb commands for i386 on a writable file would be set *(char *)0x5584b=0x57 set *(char *)0x5584c=0x56 set *(char *)0x5584d=0x90 set *(char *)0x55856=0x90 set *(char *)0x55863=0x90 set *(char *)0x55867=0x5e set *(char *)0x55868=0x5f set *(char *)0x55869=0x5e set *(char *)0x5586a=0x5f set *(char *)0x5586b=0x5d set *(char *)0x5586c=0xc3 set *(char *)0x5586d=0x90 set *(char *)0x5586e=0x90 set *(char *)0x5586f=0x90
Should be fixed in glibc-2.2.4-24.