Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
55 lines (32 sloc) 2.81 KB
_HEADER_HL1(`19-Apr-2016: Bug in LZHuf.c by Haruyasu Yoshizaki')
<p>There is a highly popular LZHuf compressor/decompressor written by Haruyasu Yoshizaki as early as in 1988.</p>
<p>Andrey "herm1t" Baranovich (owner of _HTML_LINK(`',`VX Heaven website')) _HTML_LINK(`',`found that many variations of this source code has a bug') (_HTML_LINK(`',`archived')):</p>
unsigned freq[T + 1]; /* frequency table */
void reconst(void)
l = (j - k) * 2; // "sizeof(unsigned)" should be instead of "2"
memmove(&freq[k + 1], &freq[k], l);
freq[k] = f;
memmove(&son[k + 1], &son[k], l);
<p>The <i>reconst()</i> function treats <i>freq[]</i> array's elements as 16-bit ones (notice <i>* 2</i> in expression, calculates address within <i>freq[]</i> array), and they really are if the code is compiled on 16-bit platform, but by C standard, <i>unsigned</i> type has size of 32 bit on any modern 32-bit and 64-bit architectures.</p>
<p>I tried to crash it, and found a very easy way to do so: just try to compress big enough file (I had success with 178KiB text file), and it crashes during compressing.
Now we can fix a bug (to set <i>unsigned short</i> type instead of <i>unsigned</i>), the program giving us compressed file, which is, in turn, can crash older unfixed LZHuf.c decompression function.</p>
<p>Input file (no matter, compressed or plain) must be big enough, so <i>reconst()</i> function will be called.</p>
<p>Probably (I'm not sure) this is a way to crash unfixed LZHuf.c program on a 32-bit or 64-bit system, just feed this file to it.
Unfixed LZHuf.c version has <i>unsigned</i> type for <i>freq[]</i> array, fixed has <i>unsigned short</i> type for it.</p>
<p>For example, this one is unfixed, but still very popular: _HTML_LINK_AS_IS(`')</p>
<p>This one is fixed: _HTML_LINK_AS_IS(`')</p>
<p>Crash happens in DecodePosition() function, when it attempts to read beyond <i>d_code[]</i> array.
Perhaps, someone else may check this and analyze further.</p>
<p>File I used as a plain text (~178KiB): _HTML_LINK_AS_IS(`').</p>
<p>Compressed file which crashes unfixed LZHuf.c (~45KiB): _HTML_LINK_AS_IS(`').</p>
<p>Unfixed LZHuf.c I used: _HTML_LINK_AS_IS(`').</p>