This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
heap corruption vuln in fnmatch() (or blame gcc if you like..)
- From: Rich Felker <dalias at aerifal dot cx>
- To: libc-alpha at sources dot redhat dot com
- Date: Sat, 20 Jan 2007 18:53:04 -0500
- Subject: heap corruption vuln in fnmatch() (or blame gcc if you like..)
glibc's fnmatch() implementation performs alloca without any checks on
the size of the allocation:
wpatternÂ=Â(wchar_tÂ*)ÂallocaÂ((nÂ+Â1)Â*ÂsizeofÂ(wchar_t));
I am not familiar with every single gcc version, but on all versions I
have tested, gcc makes no effort to ensure that the resulting
adjustment to the stack actually leaves the stack pointer on the
stack, and in fact making such a test is rather difficult and probably
requires either additional OS-specific knowledge by the compiler or
performance penalties (or both).
Exploiting this bug is just a matter of passing an extremely long
pattern string (around 256M-1G on most OS) to fnmatch. Think of an
ftpd as an example. The alloca will result in a buffer somewhere in
mmapped or heap memory, which will then be overwritten by mbsrtowcs.
SIGSEGV should result immediately, but if a handler for SIGSEGV has
been installed it may use the newly corrupted heap data, resulting in
arbitrary code execution (e.g. when closing open FILEs).
As far as I know, the only safe way to use alloca/vla is to check that
the size is significantly smaller than the gap between the lower stack
limit and the upper heap/mmap area limit, or else perform a
reverse-memset (starting from the end) on the allocated area to ensure
that you get a fatal signal if the allocation runs off the bottom of
the stack. Simply using malloc would be a lot easier, I think.
Rich