-
Notifications
You must be signed in to change notification settings - Fork 429
tidy heap-buffer-overflow #217
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
Comments
Such debug is OFF by default, and only added by defining DEBUG_MEMORY. And is only available for the Debug configuration compiled with MSVC, but this could be easily extended...
Ok, found the problem and what seems like a suitable solution... This is a case where we effectively have So since there is no attribute value, len will be zero, which is ok... it is the truth - there is no attribute value length... Now the code has So added to the code in this block -
And even more, if len does have a value, then protect against len ever going negative with -
It was the first of these two that did the damage. start=4, len=0, and just coincidently lexer->lexbuf[3] contained an 0xa, thus len was decremented to -1 ;=((. That in itself is quite unique since there are only a few special cases where control chars are added to the lexer. But you guessed it, one is when parsing 'code', like Now when the code does In some cases this bug could exibit a different problem like parsing the snippet Now the lexer buffer will contain 2, or more IsWhite() chars and len would be reduced to -2, or less, which means the malloc buffer allocation would be a giant 4,294,967,295 byte allocation, a value lots of OSes will reject... And I can confirm this BUG exists in the 2008/9 libtidy.0.99.so last release, the sourceforge cvs tidy, which is still present in some distributions. Just the quite unique nature of using 'code' ending in spaces or a newline just before an attribute with a 'blank' value prevents it from being seens more often... Interestingly, it is NOT present in TidyAug2000, the earliest tidy source I have, since (a) it did not have that additional len decrement, and (b) used an int in wstrndup, the predecessor of tmbstrndup, so the code Anyway, now no more buffer corruption, or massive allocs, for this latest tidy ;=)). I love crushing such ancient bugs... Also bumped the version to 4.9.31 for this important fix. |
This fixes a security problem (heap-buffer-overflow): see htacg/tidy-html5#217 PR: ports/200631 Submitted by: Walter Hop Security: htacg/tidy-html5#217 git-svn-id: svn+ssh://svn.freebsd.org/ports/head@388845 35697150-7ecd-e111-bb59-0022644237b5
This fixes a security problem (heap-buffer-overflow): see htacg/tidy-html5#217 PR: ports/200631 Submitted by: Walter Hop Security: htacg/tidy-html5#217
Since no further comment for a few weeks will close this now... Please feel free to re-open, or open another issues... |
a heap-buffer overflow which also affects tidyp Written by: Stuart Henderson <sthen@openbsd.org>
a heap-buffer overflow which also affects tidyp Written by: Stuart Henderson <sthen@openbsd.org>
A note that this is CVE-2015-5522 and CVE-2015-5523 and that Ubuntu has fixed this particular bug in their version https://launchpad.net/ubuntu/+source/tidy/20091223cvs-1.5 in 'wily'. (Adding the CVE numbers here to make it clear when searching for that CVE that the bug has been fixed.) |
Fernando has found and reported a heap-buffer-overflow directly to me, the text so far is attached below, and I have now been able to REPEAT the event, and am now searching for a fix.
I do not know anything about Valgrind, but luckily the Windows MSVC Debug configuration does the same. It inserts a 'deb_malloc' which allocates much more than the user request, and fills the leading and trailing memory with a marker, and returns the appropriate pointer to the user.
Leading is 0xfd, and trailing is 0xab, Then on 'deb_free', it checks the leading marker for buffer under-run, and the trailing marker for buffer over-run.
This is a view of the memory as allocated in this case
fd fd fd fd fd fd fd fd ab ab ab ab ab ab ab ab ab ab ab ab ab ab ...
The event happens in ParseValue, where the length is held in an int len, which gets to contain a -1! MINUS ONE!! It is parsing the anchor href in this strange string
<a b=<a <?xm ?>b="c"G href="�"»
ParseValue then calls -
value = TY_(tmbstrndup)(doc->allocator, lexer->lexbuf + start, len);
to do the allocation...
Inexplicably tmpstrndup is decalared as -
tmbstr TY_(tmbstrndup)( TidyAllocator *allocator, ctmbstr str, uint len);
Notice the int has now become a uint, so can not test for less that zero... it does
if (len > 0)
, but of course len is now 4294967295, but like for all such allocations tmbstrndup does -Notice the plus 1, so it arrives at TidyAlloc with a ZERO!!!
Now it seems malloc does not mind a zero value, malloc(0), and dutifully returns a pointer!!!! But that is a pointer to what exactly?
Then tmbstrndup does the corruption, with -
while ( len-- > 0 && (*cp++ = *str++) ) /**/;
Of course
( len-- > 0 )
will be true until the 4294967295 expires ;=))But thankfully the corruption stops when a 0 is reached in the lexer with
(*cp++ = *str++)
. As indicated in this case it is storing the attribute "href", but that is 4+ bytes of corruption.Then a final corruption, the reason for the plus 1 -
*cp = 0;
This is a view of the memory after -
fd fd fd fd 68 72 65 66 00 00 ab ab ab ab ab ab ab ab
Note in this case, since the loop did not end when len became zero, so we end up with a double 0! But I get a big popup dialog when this memory is passed to 'deb_free'... advising me of possible heap corruption...
So that is a detailed desciption of the problem. Now to decide what would be the best fix! Ideas...
Since tmbstrndup does check is len > 0, could change the uint to an int, and then it would return a NULL memory. Probably not a good thing in all case...
I am still trying to understand exactly why the int len back in ParseValue went negative!
Will work on this... As indicated any ideas welcome...
And again thanks to Fernando for finding this case... What follows is our direct conversation to date...
Hey Geoff,
I believe I tried both versions, the old (which is the one that Debian
stable ships) and the new with HTML5 support from github.
Did you try to run it under valgrind? Valgrind reports the errors but
the app won't segfault.
I can give it a try later again and tell you the exact version I used.
Thanks
On 6/1/15 5:28 AM, Geoff McLane wrote:
The text was updated successfully, but these errors were encountered: