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

heap buffer out-of-bounds write in addMultirowsForm() #26

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

Comments

Projects
None yet
2 participants
@kcwu
Copy link
Contributor

commented Aug 28, 2016

input

00000000: 3c74 6162 6c65 3e30 3c62 7574 746f 6e20  <table>0<button
00000010: 7661 6c75 653d 2722 3e30 3030 3030 3030  value='">0000000
00000020: 3030 3027 3e30 3030 3030 3030 3030 3030  000'>00000000000
00000030: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000040: 3030 3030 3030 3030 3030 3030 3030 3030  0000000000000000
00000050: 3030 3030 3030 3030 3030 3030 3030 3c74  00000000000000<t
00000060: 6578 7461 7265 6120 726f 7773 3d32 3030  extarea rows=200
00000070: 3030 3e                                  00>
Program received signal SIGSEGV, Segmentation fault.
0x0000000000438b33 in calcPosition (l=0x9c1500 " ]          [         ", pr=0x5b009c7f60, len=22, pos=1, bpos=0, mode=0) at etc.c:515
515         if (pr[i] & PC_WCHAR2) {
(gdb) p pr
$1 = (Lineprop *) 0x5b009c7f60
(gdb) p i
$2 = 0
(gdb) p pr[i]
Cannot access memory at address 0x5b009c7f60

pr is corrupted. Note the correct address of pr is 0x9c7f60 but its highest byte is overwritten by 0x5b=='['

This is because buffer overflows earlier in addMultirowsForm (several times). With following assertion, it can catch the overflow easier.

diff --git a/anchor.c b/anchor.c
index 2d21bfa..3eb30d2 100644
--- a/anchor.c
+++ b/anchor.c
@@ -1,4 +1,5 @@
 /* $Id: anchor.c,v 1.33 2006/04/08 11:33:16 inu Exp $ */
+#include <assert.h>
 #include "fm.h"
 #include "myctype.h"
 #include "regex.h"
@@ -686,6 +687,7 @@ addMultirowsForm(Buffer *buf, AnchorList *al)
            a->y = a_form.y;
            a->end.pos = pos + ecol - col;
            l->lineBuf[pos - 1] = '[';
+           assert(a->end.pos < l->size);
            l->lineBuf[a->end.pos] = ']';
            for (k = pos; k < a->end.pos; k++)
                l->propBuf[k] |= PE_FORM;
w3m: anchor.c:690: addMultirowsForm: Assertion `a->end.pos < l->size' failed.

Program received signal SIGABRT, Aborted.
0x00007ffff6c75c37 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56      ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007ffff6c75c37 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff6c79028 in __GI_abort () at abort.c:89
#2  0x00007ffff6c6ebf6 in __assert_fail_base (fmt=0x7ffff6dbf3b8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n", assertion=assertion@entry=0x49cfc2 "a->end.pos < l->size",
    file=file@entry=0x49cfb9 "anchor.c", line=line@entry=690, function=function@entry=0x49d0f0 <__PRETTY_FUNCTION__.19282> "addMultirowsForm") at assert.c:92
#3  0x00007ffff6c6eca2 in __GI___assert_fail (assertion=0x49cfc2 "a->end.pos < l->size", file=0x49cfb9 "anchor.c", line=690,
    function=0x49d0f0 <__PRETTY_FUNCTION__.19282> "addMultirowsForm") at assert.c:101
#4  0x0000000000475a5c in addMultirowsForm (buf=0x7d3e00, al=0x7ea7c0) at anchor.c:690
#5  0x000000000042acde in HTMLlineproc2body (buf=0x7d3e00, feed=0x4282b8 <textlist_feed>, llimit=-1) at file.c:6142
#6  0x000000000042aeeb in HTMLlineproc2 (buf=0x7d3e00, tl=0x7cc2e0) at file.c:6195
#7  0x000000000042e0d5 in loadHTMLstream (f=0x7fffffffd130, newBuf=0x7d3e00, src=0x0, internal=0) at file.c:7281
#8  0x000000000042c8fe in loadHTMLBuffer (f=0x7fffffffd130, newBuf=0x7d3e00) at file.c:6778
#9  0x0000000000416ae0 in loadSomething (f=0x7fffffffd130, loadproc=0x42c7fc <loadHTMLBuffer>, defaultbuf=0x7d3e00) at file.c:224
#10 0x000000000041c8fe in loadGeneralFile (path=0x7bdf00 "triage.debug/min/3", current=0x0, referer=0xffffffffffffffff <error: Cannot access memory at address 0xffffffffffffffff>,
    flag=0, request=0x0) at file.c:2245
#11 0x0000000000407171 in main (argc=5, argv=0x7fffffffd458, envp=0x7fffffffd488) at main.c:1020
(gdb) frame 4
#4  0x0000000000475a5c in addMultirowsForm (buf=0x7d3e00, al=0x7ea7c0) at anchor.c:690
690                 assert(a->end.pos < l->size);
(gdb) p a->end.pos
$1 = 33
(gdb) p l->size
$2 = 22

This is found by afl-fuzz.

@kcwu kcwu changed the title heap buffer overflow write in addMultirowsForm() heap buffer out-of-bounds write in addMultirowsForm() Aug 28, 2016

tats added a commit that referenced this issue Aug 29, 2016

@tats

This comment has been minimized.

Copy link
Owner

commented Aug 29, 2016

A workaround patch has been applied. Thank you.

@tats tats closed this Aug 29, 2016

@kcwu

This comment has been minimized.

Copy link
Contributor Author

commented Aug 29, 2016

BTW, could you reproduce this issue with assert() ?

@tats

This comment has been minimized.

Copy link
Owner

commented Aug 29, 2016

BTW, could you reproduce this issue with assert() ?

Yes, reproducible.

Aborted with assert(), and Segmentation fault without assert(),
and the patch prevented this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.