Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

memory exhausted due to repeat appending "</table>" #23

Closed
kcwu opened this issue Aug 19, 2016 · 3 comments
Closed

memory exhausted due to repeat appending "</table>" #23

kcwu opened this issue Aug 19, 2016 · 3 comments

Comments

@kcwu
Copy link
Contributor

kcwu commented Aug 19, 2016

$ echo "<taBle><title><xmp><body><table><textarea><T<t='<v='>" | ./w3m -T text/html -dump > /dev/null
GC Warning: Repeated allocation of very large block (appr. size 25112576):
        May lead to memory leak and poor performance.
GC Warning: Repeated allocation of very large block (appr. size 107966464):
        May lead to memory leak and poor performance.
GC Warning: Repeated allocation of very large block (appr. size 268652544):
        May lead to memory leak and poor performance.
GC Warning: Out of Memory! Heap size: 2213 MiB. Returning NULL!
Out of memory: 18446744073314787007 bytes unavailable!

gdb

(gdb) b die_oom
Breakpoint 1 at 0x404e89: file main.c, line 390.
(gdb) r
Breakpoint 1, die_oom (bytes=18446744073314787007) at main.c:390
390         fprintf(stderr, "Out of memory: %lu bytes unavailable!\n", (unsigned long)bytes);
(gdb) bt
#0  die_oom (bytes=18446744073314787007) at main.c:390
#1  0x00007ffff787c489 in GC_core_malloc_atomic () from /usr/lib/x86_64-linux-gnu/libgc.so.1
#2  0x0000000000479adc in Strgrow (x=0x7ba660) at Str.c:238
#3  0x00000000004394fc in read_token (buf=0x7ba660, instr=0x7fffffffc198, status=0x7fffffffc504, pre=2048, append=1) at etc.c:858
#4  0x000000000042b1fd in HTMLlineproc0 (line=0x4953e9 "</table>", h_env=0x7fffffffc300, internal=1) at file.c:6336
#5  0x000000000042d330 in completeHTMLstream (h_env=0x7fffffffc300, obuf=0x7fffffffc490) at file.c:7012
#6  0x000000000044268b in do_refill (tbl=0x7bf000, row=0, col=0, maxlimit=79) at table.c:804
#7  0x00000000004464d1 in renderTable (t=0x7bf000, max_width=79, h_env=0x7fffffffcb10) at table.c:1800
#8  0x000000000042b782 in HTMLlineproc0 (line=0x4953f1 "", h_env=0x7fffffffcb10, internal=1) at file.c:6442
#9  0x000000000042d330 in completeHTMLstream (h_env=0x7fffffffcb10, obuf=0x7fffffffcca0) at file.c:7012
#10 0x000000000042dd3b in loadHTMLstream (f=0x7fffffffd130, newBuf=0x7d3e00, src=0x0, internal=0) at file.c:7244
#11 0x000000000042c71f in loadHTMLBuffer (f=0x7fffffffd130, newBuf=0x7d3e00) at file.c:6772
#12 0x0000000000416a90 in loadSomething (f=0x7fffffffd130, loadproc=0x42c61d <loadHTMLBuffer>, defaultbuf=0x7d3e00) at file.c:224
#13 0x000000000041c8ae in loadGeneralFile (path=0x7c3ae0 "/tmp/zshzsw6kF", current=0x0, referer=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>, flag=0, request=0x0) at file.c:2245
#14 0x0000000000407121 in main (argc=5, argv=0x7fffffffd458, envp=0x7fffffffd488) at main.c:1020
(gdb) up
#1  0x00007ffff787c489 in GC_core_malloc_atomic () from /usr/lib/x86_64-linux-gnu/libgc.so.1
(gdb)
#2  0x0000000000479adc in Strgrow (x=0x7ba660) at Str.c:238
238         x->ptr = GC_MALLOC_ATOMIC(newlen);
(gdb) p x[0]
$1 = {
  ptr = 0x7659c000 "<t='\n</table></table></table></table></table></table></table></table></table></table></table></table></table></table></table></table></table></table></table></table></table></table></table></table></t"...,
  length = 386857375,
  area_size = 386857376
}
(gdb) p newlen
$2 = -394764609

Two issues

  1. why w3m repeat appending "</table>" to the buffer
  2. newlen integer overflow in Strgrow and to allocate huge buffer.

found by afl-fuzz

@tats
Copy link
Owner

tats commented Aug 24, 2016

Reproducible, but not yet fixed. Patches welcome.

@yumkam
Copy link

yumkam commented Nov 3, 2016

on 2: pretty trivial; I have a patch, but it is a bit nasty (there are no way to return error from most/all Str* functions, so it simply makes all integer overflows in Str.c explicitly deadly).
on 1: completeHTMLstream tries to close all opened, but not closed HTML tables by repeatedly appending </table> string to input buffer until nesting level is zero. Unfortunately, above fuzzied/invalid HTML leaves reader in confused state, so all </table> are ignored, table nesting level remains same, and it ends up in infinite loop of growing buffer (fwiw, with my patch above, it would simply kill w3m, ensuring no buffer overflow happened; obviously, that's quite suboptimal solution; probably, completeHTMLstream should check if table nesting level actually decreases and bail out otherwise?).

tats added a commit that referenced this issue Nov 7, 2016
@tats
Copy link
Owner

tats commented Nov 7, 2016

probably, completeHTMLstream should check if table nesting level actually decreases

Check added. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants