Description of problem: wget buffer overflow detected Version-Release number of selected component (if applicable): wget-1.10.2-3.3.fc5 How reproducible: Seems to be evertime Steps to Reproduce: Actual results: $ wget -c http://public.www.planetmirror.com/pub/ubcd/3.4/ubcd34-basic.zip --15:55:54-- http://public.www.planetmirror.com/pub/ubcd/3.4/ubcd34-basic.zip Resolving public.www.planetmirror.com... 203.16.234.20, 203.16.234.90, 203.16.234.91, ... Connecting to public.www.planetmirror.com|203.16.234.20|:80... connected. HTTP request sent, awaiting response... 302 Moved Temporarily Location: ftp://ftp.planetmirror.com/pub/ubcd/3.4/ubcd34-basic.zip [following] --15:55:54-- ftp://ftp.planetmirror.com/pub/ubcd/3.4/ubcd34-basic.zip => `ubcd34-basic.zip' Resolving ftp.planetmirror.com... 203.16.234.85, 203.16.234.86 Connecting to ftp.planetmirror.com|203.16.234.85|:21... connected. Logging in as anonymous ... Logged in! ==> SYST ... done. ==> PWD ... done. ==> TYPE I ... done. ==> CWD /pub/ubcd/3.4 ... done. ==> SIZE ubcd34-basic.zip ... 98948071 ==> PASV ... done. ==> REST 98948071 ... REST failed, starting from scratch. ==> RETR ubcd34-basic.zip ... done. Length: 98948071 (94M), 0 (0) remaining 0% [ ] 0 --.-K/s *** buffer overflow detected ***: wget terminated ======= Backtrace: ========= /lib64/libc.so.6(__chk_fail+0x2f)[0x3ac6cdf24f] /lib64/libc.so.6[0x3ac6cde809] /lib64/libc.so.6(_IO_default_xsputn+0x8e)[0x3ac6c69a3e] /lib64/libc.so.6(_IO_vfprintf+0x1621)[0x3ac6c421d1] /lib64/libc.so.6(__vsprintf_chk+0x9d)[0x3ac6cde8ad] /lib64/libc.so.6(__sprintf_chk+0x80)[0x3ac6cde7f0] wget[0x41c1d8] wget[0x41c58d] wget[0x41ca75] wget[0x41fdd0] wget[0x408bf2] wget[0x40a2e8] wget[0x40ac80] wget[0x41f366] wget[0x41ae90] /lib64/libc.so.6(__libc_start_main+0xf4)[0x3ac6c1c784] wget(fnmatch+0x1d9)[0x403e69] ======= Memory map: ======== 00400000-00436000 r-xp 00000000 08:13 15558033 /usr/bin/wget 00535000-00539000 rw-p 00035000 08:13 15558033 /usr/bin/wget 00539000-00543000 rw-p 00539000 00:00 0 00638000-0063a000 rw-p 00038000 08:13 15558033 /usr/bin/wget 0063a000-0065b000 rw-p 0063a000 00:00 0 [heap] 3528f00000-3528f0d000 r-xp 00000000 08:13 4190223 /lib64/libgcc_s-4.1.1-20070108.so.1 3528f0d000-352900c000 ---p 0000d000 08:13 4190223 /lib64/libgcc_s-4.1.1-20070108.so.1 352900c000-352900d000 rw-p 0000c000 08:13 4190223 /lib64/libgcc_s-4.1.1-20070108.so.1 3565300000-3565343000 r-xp 00000000 08:13 4190333 /lib64/libssl.so.0.9.8a 3565343000-3565443000 ---p 00043000 08:13 4190333 /lib64/libssl.so.0.9.8a 3565443000-3565449000 rw-p 00043000 08:13 4190333 /lib64/libssl.so.0.9.8a 3565b00000-3565b14000 r-xp 00000000 08:13 15578427 /usr/lib64/libz.so.1.2.3 3565b14000-3565c13000 ---p 00014000 08:13 15578427 /usr/lib64/libz.so.1.2.3 3565c13000-3565c14000 rw-p 00013000 08:13 15578427 /usr/lib64/libz.so.1.2.3 3565f00000-3566028000 r-xp 00000000 08:13 4190327 /lib64/libcrypto.so.0.9.8a 3566028000-3566128000 ---p 00128000 08:13 4190327 /lib64/libcrypto.so.0.9.8a 3566128000-3566148000 rw-p 00128000 08:13 4190327 /lib64/libcrypto.so.0.9.8a 3566148000-356614b000 rw-p 3566148000 00:00 0 389bc00000-389bc74000 r-xp 00000000 08:13 15578344 /usr/lib64/libkrb5.so.3.2 389bc74000-389bd74000 ---p 00074000 08:13 15578344 /usr/lib64/libkrb5.so.3.2 389bd74000-389bd78000 rw-p 00074000 08:13 15578344 /usr/lib64/libkrb5.so.3.2 389be00000-389be17000 r-xp 00000000 08:13 15578345 /usr/lib64/libgssapi_krb5.so.2.2 389be17000-389bf17000 ---p 00017000 08:13 15578345 /usr/lib64/libgssapi_krb5.so.2.2 389bf17000-389bf18000 rw-p 00017000 08:13 15578345 /usr/lib64/libgssapi_krb5.so.2.2 389c000000-389c022000 r-xp 00000000 08:13 15578343 /usr/lib64/libk5crypto.so.3.0 389c022000-389c121000 ---p 00022000 08:13 15578343 /usr/lib64/libk5crypto.so.3.0 389c121000-389c123000 rw-p 00021000 08:13 15578343 /usr/lib64/libk5crypto.so.3.0 389c200000-389c203000 r-xp 00000000 08:13 15567211 /usr/lib64/libkrb5support.so.0.0 389c203000-389c302000 ---p 00003000 08:13 15567211 /usr/lib64/libkrb5support.so.0.0 389c302000-389c303000 rw-p 00002000 08:13 15567211 /usr/lib64/libkrb5support.so.0.0 3ac6a00000-3ac6a1a000 r-xp 00000000 08:13 4190366 /lib64/ld-2.4.so 3ac6b19000-3ac6b1a000 r--p 00019000 08:13 4190366 /lib64/ld-2.4.so 3ac6b1a000-3ac6b1b000 rw-p 0001a000 08:13 4190366 /lib64/ld-2.4.so 3ac6c00000-3ac6d3f000 r-xp 00000000 08:13 4190390 /lib64/libc-2.4.so 3ac6d3f000-3ac6e3e000 ---p 0013f000 08:13 4190390 /lib64/libc-2.4.so 3ac6e3e000-3ac6e42000 r--p 0013e000 08:13 4190390 /lib64/libc-Aborted Expected results: Additional info: $ wget -c http://public.www.planetmirror.com/pub/ubcd/3.4/ubcd34-basic.zip --16:06:28-- http://public.www.planetmirror.com/pub/ubcd/3.4/ubcd34-basic.zip Resolving public.www.planetmirror.com... 203.16.234.91, 203.16.234.19, 203.16.234.20, ... Connecting to public.www.planetmirror.com|203.16.234.91|:80... connected. HTTP request sent, awaiting response... 302 Moved Temporarily Location: ftp://ftp.planetmirror.com/pub/ubcd/3.4/ubcd34-basic.zip [following] --16:06:28-- ftp://ftp.planetmirror.com/pub/ubcd/3.4/ubcd34-basic.zip => `ubcd34-basic.zip' Resolving ftp.planetmirror.com... 203.16.234.86, 203.16.234.85 Connecting to ftp.planetmirror.com|203.16.234.86|:21... connected. Logging in as anonymous ... Logged in! ==> SYST ... done. ==> PWD ... done. ==> TYPE I ... done. ==> CWD /pub/ubcd/3.4 ... done. ==> SIZE ubcd34-basic.zip ... 98948071 ==> PASV ... done. ==> REST 98948071 ... REST failed, starting from scratch. ==> RETR ubcd34-basic.zip ... done. Length: 98948071 (94M), 0 (0) remaining 0% [ ] 0 --.-K/s *** buffer overflow detected ***: wget terminated ======= Backtrace: ========= /lib64/libc.so.6(__chk_fail+0x2f)[0x3ac6cdf24f] /lib64/libc.so.6[0x3ac6cde809] /lib64/libc.so.6(_IO_default_xsputn+0x8e)[0x3ac6c69a3e] /lib64/libc.so.6(_IO_vfprintf+0x1621)[0x3ac6c421d1] /lib64/libc.so.6(__vsprintf_chk+0x9d)[0x3ac6cde8ad] /lib64/libc.so.6(__sprintf_chk+0x80)[0x3ac6cde7f0] wget[0x41c1d8] wget[0x41c58d] wget[0x41ca75] wget[0x41fdd0] wget[0x408bf2] wget[0x40a2e8] wget[0x40ac80] wget[0x41f366] wget[0x41ae90] /lib64/libc.so.6(__libc_start_main+0xf4)[0x3ac6c1c784] wget(fnmatch+0x1d9)[0x403e69] ======= Memory map: ======== 00400000-00436000 r-xp 00000000 08:13 15558033 /usr/bin/wget 00535000-00539000 rw-p 00035000 08:13 15558033 /usr/bin/wget 00539000-00543000 rw-p 00539000 00:00 0 00638000-0063a000 rw-p 00038000 08:13 15558033 /usr/bin/wget 0063a000-0065b000 rw-p 0063a000 00:00 0 [heap] 3528f00000-3528f0d000 r-xp 00000000 08:13 4190223 /lib64/libgcc_s-4.1.1-20070108.so.1 3528f0d000-352900c000 ---p 0000d000 08:13 4190223 /lib64/libgcc_s-4.1.1-20070108.so.1 352900c000-352900d000 rw-p 0000c000 08:13 4190223 /lib64/libgcc_s-4.1.1-20070108.so.1 3565300000-3565343000 r-xp 00000000 08:13 4190333 /lib64/libssl.so.0.9.8a 3565343000-3565443000 ---p 00043000 08:13 4190333 /lib64/libssl.so.0.9.8a 3565443000-3565449000 rw-p 00043000 08:13 4190333 /lib64/libssl.so.0.9.8a 3565b00000-3565b14000 r-xp 00000000 08:13 15578427 /usr/lib64/libz.so.1.2.3 3565b14000-3565c13000 ---p 00014000 08:13 15578427 /usr/lib64/libz.so.1.2.3 3565c13000-3565c14000 rw-p 00013000 08:13 15578427 /usr/lib64/libz.so.1.2.3 3565f00000-3566028000 r-xp 00000000 08:13 4190327 /lib64/libcrypto.so.0.9.8a 3566028000-3566128000 ---p 00128000 08:13 4190327 /lib64/libcrypto.so.0.9.8a 3566128000-3566148000 rw-p 00128000 08:13 4190327 /lib64/libcrypto.so.0.9.8a 3566148000-356614b000 rw-p 3566148000 00:00 0 389bc00000-389bc74000 r-xp 00000000 08:13 15578344 /usr/lib64/libkrb5.so.3.2 389bc74000-389bd74000 ---p 00074000 08:13 15578344 /usr/lib64/libkrb5.so.3.2 389bd74000-389bd78000 rw-p 00074000 08:13 15578344 /usr/lib64/libkrb5.so.3.2 389be00000-389be17000 r-xp 00000000 08:13 15578345 /usr/lib64/libgssapi_krb5.so.2.2 389be17000-389bf17000 ---p 00017000 08:13 15578345 /usr/lib64/libgssapi_krb5.so.2.2 389bf17000-389bf18000 rw-p 00017000 08:13 15578345 /usr/lib64/libgssapi_krb5.so.2.2 389c000000-389c022000 r-xp 00000000 08:13 15578343 /usr/lib64/libk5crypto.so.3.0 389c022000-389c121000 ---p 00022000 08:13 15578343 /usr/lib64/libk5crypto.so.3.0 389c121000-389c123000 rw-p 00021000 08:13 15578343 /usr/lib64/libk5crypto.so.3.0 389c200000-389c203000 r-xp 00000000 08:13 15567211 /usr/lib64/libkrb5support.so.0.0 389c203000-389c302000 ---p 00003000 08:13 15567211 /usr/lib64/libkrb5support.so.0.0 389c302000-389c303000 rw-p 00002000 08:13 15567211 /usr/lib64/libkrb5support.so.0.0 3ac6a00000-3ac6a1a000 r-xp 00000000 08:13 4190366 /lib64/ld-2.4.so 3ac6b19000-3ac6b1a000 r--p 00019000 08:13 4190366 /lib64/ld-2.4.so 3ac6b1a000-3ac6b1b000 rw-p 0001a000 08:13 4190366 /lib64/ld-2.4.so 3ac6c00000-3ac6d3f000 r-xp 00000000 08:13 4190390 /lib64/libc-2.4.so 3ac6d3f000-3ac6e3e000 ---p 0013f000 08:13 4190390 /lib64/libc-2.4.so 3ac6e3e000-3ac6e42000 r--p 0013e000 08:13 4190390 /lib64/libc-Aborted
Created attachment 147664 [details] valgrind.log
Reproduced on an i386 machine too. Currently seems reproducible 100% of the time using: wget -c 'ftp://203.16.234.86/pub/ubcd/3.4/ubcd34-basic.zip' Valgrind does not seem to pick up on the problem. gdb backtrace to follow: Program received signal SIGABRT, Aborted. [Switching to Thread -1208387904 (LWP 22569)] 0x0081d402 in __kernel_vsyscall () (gdb) bt #0 0x0081d402 in __kernel_vsyscall () #1 0x426e0d40 in raise () from /lib/libc.so.6 #2 0x426e2591 in abort () from /lib/libc.so.6 #3 0x4271633b in __libc_message () from /lib/libc.so.6 #4 0x42799361 in __chk_fail () from /lib/libc.so.6 #5 0x42798b78 in _IO_str_chk_overflow () from /lib/libc.so.6 #6 0x4271a674 in _IO_default_xsputn_internal () from /lib/libc.so.6 #7 0x426f44ea in vfprintf () from /lib/libc.so.6 #8 0x42798c2d in __vsprintf_chk () from /lib/libc.so.6 #9 0x42798b60 in __sprintf_chk () from /lib/libc.so.6 #10 0x0806496b in eta_to_human_short (secs=1115623412, condensed=6) at progress.c:1059 #11 0x08064d8a in create_image (bp=0x9addf30, dl_total_time=30.584747448000002, done=false) at progress.c:942 #12 0x0806544b in bar_update (progress=0x9addf30, howmuch=0, dltime=30.584747448000002) at progress.c:631 #13 0x08068ed3 in fd_read_body (fd=7, out=0x9adddc8, toread=98948071, startpos=<value optimized out>, qtyread=0xbfaf2038, qtywritten=0xbfaf2148, elapsed=0xbfaf2300, flags=0) at retr.c:310 #14 0x0804fac9 in getftp (u=0x9adc928, len=0xbfaf2148, restval=0, con=0xbfaf22f4) at ftp.c:966 #15 0x08051631 in ftp_loop_internal (u=0x9adc928, f=0x0, con=0xbfaf22f4) at ftp.c:1173 ---Type <return> to continue, or q <return> to quit--- #16 0x080520d5 in ftp_loop (u=0x9adc928, dt=0xbfaf2484, proxy=0x0, recursive=false, glob=true) at ftp.c:1856 #17 0x080680e5 in retrieve_url ( origurl=0x9adc868 "ftp://203.16.234.86/pub/ubcd/3.4/ubcd34-basic.zip", file=0xbfaf248c, newloc=0xbfaf2488, refurl=0x0, dt=0xbfaf2484, recursive=false) at retr.c:691 #18 0x08063418 in main (argc=2, argv=0xbfaf2544) at main.c:961 #19 0x426cdf2c in __libc_start_main () from /lib/libc.so.6 #20 0x0804a8c1 in _start () (gdb) I guess this is related to the amount of time wget was forced to wait before the download started...
I forgot to mention - this problem exists in FC6 too. OK the problem appears to be that the eta can overflow. This is picked up by -D_FORTIFY_SOURCE checks and will also trigger a check an assert in wget if -D_FORTIFY_SOURCE is turned off. On line 935 of progress.c an estimate of time remaining is calculated. If a download stalls from the start then the calculation overflows and eta becomes negative causing all sorts of knock on effects: Breakpoint 2, create_image (bp=0x5561f0, dl_total_time=29.796212000000001, done=false) at progress.c:935 935 eta = (int) (dl_total_time * bytes_remaining / bp->count + 0.5); (gdb) print dl_total_time $5 = 29.796212000000001 (gdb) print bytes_remaining $6 = 98948070 (gdb) print bp->count $7 = 1 (gdb) print dl_total_time * bytes_remaining / bp->count + 0.5 $8 = 2948277671.2108397 (gdb) s 936 bp->last_eta_value = eta; (gdb) print eta $10 = -2147483648 -2147483648 then goes on to overflow the buf[10] string inside eta_to_human_short at line 1059: Breakpoint 1, eta_to_human_short (secs=-2147483648, condensed=false) at progress.c:1049 1049 const char *space = condensed ? "" : " "; (gdb) 1054 if (secs == last) (gdb) 1056 last = secs; (gdb) 1058 if (secs < 100) (gdb) 1059 sprintf (buf, "%ds", secs); (gdb) print buf $11 = "\000\000\000\000\000\000\000\000\000" (gdb) print secs $12 = -2147483648 (gdb) n 1070 return buf; (gdb) print buf $14 = "-214748364" (gdb) print /x buf $15 = {0x2d, 0x32, 0x31, 0x34, 0x37, 0x34, 0x38, 0x33, 0x36, 0x34} Perhaps it would have been better to have used snprintf to try and further contain damage (since buf is a fixed size)? However the main problem is going to be dealing with this negative number... Good catch Chris (and gcc/glibc)!
I've remove the to11 patch which caused this (and other failures). eta is now of type off_t and can't get negative. wget then checks how many hours eta is and prints an empty line if it is > 99. No chance of an overflow here afaiks.