Bug 7066

Summary: Probable buffer overrun in strtold()
Product: glibc Reporter: Nix <nix>
Component: libcAssignee: Ulrich Drepper <drepper.fsp>
Status: RESOLVED FIXED    
Severity: normal CC: fweimer, glibc-bugs
Priority: P2 Flags: fweimer: security+
Version: unspecified   
Target Milestone: ---   
Host: i686-pc-linux-gnu Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu Last reconfirmed:
Attachments: One-liner reproducing the crash

Description Nix 2008-12-04 00:49:09 UTC
When testing with the stack-protector patch in #7065, test-strtod is killed by 
the stack-protector:

strtod ("12.345") test 0        OK
strtod ("12.345e19") test 1     OK
strtod ("-.1e+9") test 2        OK
strtod (".125") test 3  OK
strtod ("1e20") test 4  OK
strtod ("0e-19") test 5 OK
strtod ("4") test 6     OK
strtod ("5.9e-76") test 7       OK
strtod ("0x1.4p+3") test 8      OK
strtod ("0xAp0") test 9 OK
strtod ("0x0Ap0") test 10       OK
strtod ("0x0A") test 11 OK
strtod ("0xA0") test 12 OK
strtod ("0x0.A0p8") test 13     OK
strtod ("0x0.50p9") test 14     OK
strtod ("0x0.28p10") test 15    OK
strtod ("0x0.14p11") test 16    OK
strtod ("0x0.0A0p12") test 17   OK
strtod ("0x0.050p13") test 18   OK
strtod ("0x0.028p14") test 19   OK
strtod ("0x0.014p15") test 20   OK
strtod ("0x00.00A0p16") test 21 OK
strtod ("0x00.0050p17") test 22 OK
strtod ("0x00.0028p18") test 23 OK
strtod ("0x00.0014p19") test 24 OK
strtod ("0x1p-1023") test 25    OK
strtod ("0x0.8p-1022") test 26  OK
strtod ("Inf") test 27  OK
strtod ("-Inf") test 28 OK
strtod ("+InFiNiTy") test 29    OK
strtod ("0x80000Ap-23") test 30 OK
*** stack smashing detected ***: tst-strtod - terminated
tst-strtod: stack smashing attack in function <unknown> - terminated
tst-strtod: stack smashing attack in function <unknown> - terminated

The backtrace (when linked against -lc_g) is as follows:

#0  0xb80f2424 in __kernel_vsyscall ()
#1  0x0806bc2b in __stack_chk_fail () at stack_chk_fail.c:295
#2  0x08057426 in ____strtold_l_internal (nptr=0x80ae069 "42.", '0' <repeats 19 
times>, "1", endptr=0x0, group=0, loc=0x80cc020) at ../stdlib/strtod_l.c:1571
#3  0x080509a7 in strtold (nptr=0x80ae069 "42.", '0' <repeats 19 times>, "1", 
endptr=0x0) at strtod.c:70
#4  0x0804863e in main (argc=1, argv=0xbf9f1af4) at tst-strtod.c:168

I'll attach a one-liner to reproduce it as soon as I strip the test down (I 
used to have one, but that was six months ago).
Comment 1 Nix 2008-12-04 12:12:30 UTC
Created attachment 3090 [details]
One-liner reproducing the crash

Backtrace with this one-liner, with glibc compiled with -fstack-protector-all:

Program received signal SIGABRT, Aborted.
0xb804a424 in __kernel_vsyscall ()
(gdb) bt
#0  0xb804a424 in __kernel_vsyscall ()
#1  0x08054a4b in __stack_chk_fail () at stack_chk_fail.c:295
#2  0x0804ad96 in ____strtold_l_internal (nptr=0x80ad488 "42.", '0' <repeats 19
times>, "1", endptr=0x0, group=0, loc=0x80cb0a0) at ../stdlib/strtod_l.c:1571
#3  0x08048cb7 in strtold (nptr=0x80ad488 "42.", '0' <repeats 19 times>, "1",
endptr=0x0) at strtod.c:70
#4  0x08048255 in main (argc=1, argv=0xbfa47364) at strtold-crash.c:7
Comment 2 Petr Baudis 2008-12-04 14:08:36 UTC
Are you compiling with -std=c99 or similar? (i.e. do you have the correct
prototype?)
Comment 3 Nix 2008-12-05 00:17:39 UTC
It's using the same compile line that glibc's 'make check' uses, which 
passes -std=gnu99 (IIRC: I don't have a build tree at the right point to verify 
this right now).

The original testcase in glibc calls strtold() with many different inputs: only 
this one crashes under -fstack-protector-all, and the corrupted stack is not in 
the testing function but within glibc itself. So I don't see how e.g. pointer 
width differences (not applicable on x86-32 anyway as far as I can see) could 
cause a problem. It's not as if this is a varargs function on AIX or something.
Comment 4 Ulrich Drepper 2010-09-01 19:40:51 UTC
Should be handled in git.