general mudflap question
Frank Ch. Eigler
fche@redhat.com
Wed Apr 9 18:00:00 GMT 2003
Eyal Lebedinsky <eyal@eyal.emu.id.au> writes:
> [...] I am now tracking a report that seems to come and go as I add
> debug printing. It also moves about as I change the value of
> -crumple-zone. This feels very much like a classic stack overwrite
> [...] If every pointer is checked then is it not the case that this
> should not happen? [...]
That's right, within instrumented modules. One limiting factor is the
availability of sufficient wrapper functions in libmudflap to let you
turn off the heuristics that make the system more permissive.
Uninstrumented routines like fread(), scanf(), gets() etc. all need
little wrappers in libmudflap to check their given pointers. (Or
perhaps you could make yourself an entirely mudflap-instrumented
executable, without those pesky uninstrumented system libraries).
> And for some light entertainment I will now offer a specific
> question that should demonstrate the limits of my current
> understanding of the situation...
>
> [...]
> *******
> mudflap violation 1 (check/read): time=1049877825.828932 ptr=09a4dfe8
> size=8 pc=409c4086 location=`queue.c:421 (skqupt)'
> [...]
> Nearby object 1: checked region begins 0B into and ends 7B into
> mudflap object 096d0788: name=`malloc region'
> bounds=[09a4dfe8,09a4e04f] size=104 area=heap check=1r/0w liveness=1
> watching=0
> alloc time=1049877825.826980 pc=40b48f42 [...]
This is the classic "uninitialized heap read" error we've discussed
several times. The piece "area=heap check=1r/0w" means that this
object is on the heap but hasn't been written to. (There is no
"dealloc" record, so this object is still alive, and the bounds are
okay too.)
> [...] my actual question is about the 'size=8' in the first
> line. The memory area in use here is 4 bytes long (actually
> confirmed), so what gives?
The mudflap instrumentation handles ptr->field checks specially, in
order to increase the likelihood of a hit in the lookup cache (which
is based on the base address only). Instead of checking the interval
& ptr->field ... ((char *) & ptr->field)+sizeof(ptr->field)-1
it checks a region starting at the plain pointer, to include all
prior fields too:
ptr ... ((char *) & ptr->field)+sizeof(ptr->field)-1
It may be that, if a more thorough initialization checking model is
later adopted in libmudflap, this optimization would need to go away.
You're getting into this stuff deeply enough for me to volunteer you
to review my draft paper for the GCC Summit :-). It goes into some
detail about the mechanisms.
- FChE
More information about the Gcc
mailing list