|
From: Steve G <lin...@ya...> - 2004-01-18 12:49:28
|
>Insure++ from ParaSoft in source-instrumentation mode is about >the only current tool that can detect stack and globals >overflow errors in C and C++. Flexelint/PC-Lint can find these sometimes. Then there's libsafe & propolice. Which brings up a point...couldn't valgrind find these, too? If there is a write to the return address on the stack, this could be emitted as a warning. It is rare to find trampoline code in applications. It is more common to find this as a programming error. -Steve Grubb __________________________________ Do you Yahoo!? Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes http://hotjobs.sweepstakes.yahoo.com/signingbonus |
|
From: Tom H. <th...@cy...> - 2004-01-18 13:19:20
|
In message <200...@we...>
Steve G <lin...@ya...> wrote:
> Which brings up a point...couldn't valgrind find these, too? If
> there is a write to the return address on the stack, this could
> be emitted as a warning. It is rare to find trampoline code in
> applications. It is more common to find this as a programming
> error.
The problem is that valgrind doesn't have a concept of write protected
memory. It has the idea of unadressable memory that you can't read from
or write to, and undefined memory that you can write to but not read
from but it has no concept of memory that can be read from but not
written to which is what is needed here.
One of my colleages did modify valgrind to mark the return address
on the stack as unadressable but the problem with that is that you
also have to make it spot valid reads so that it doesn't complain
about them - the ret instruction is easy, but things like alloca do
all sorts of wierd stunts with the stack that sometimes involves
moving the return address.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Steve G <lin...@ya...> - 2004-01-18 14:16:23
|
>The problem is that valgrind doesn't have a concept of >write protected memory. I don't think the solution is that complicated. Libsafe does this correctly. It has never killed a program that I know of doing something weird with alloca. Libsafe also is a LD_PRELOAD interceptor, which means it works with uninstrumented code just like valgrind. Whenever there is a mov in a loop (memcpy & strcpy) the current stackframe can be watched to see if it gets overwritten. read, recv, recvfrom, etc, can also be watched to see if their results overwrite a return address. If alloca does move the return address, I would think that a call to alloca can be identified and the "return address to watch" changed to the new address. Another approach that I might experiment with is to "valgrindify" libsafe with its macros (libsafe has a tendency to outright kill a program), modify the startup bash script to LD_PRELOAD libsafe too, and let valgrind collect the messages. I really believe its possible to detect these problems. The question is just how to do it. -Steve Grubb __________________________________ Do you Yahoo!? Yahoo! Hotjobs: Enter the "Signing Bonus" Sweepstakes http://hotjobs.sweepstakes.yahoo.com/signingbonus |
|
From: Tom H. <th...@cy...> - 2004-01-18 14:41:04
|
In message <200...@we...>
Steve G <lin...@ya...> wrote:
> >The problem is that valgrind doesn't have a concept of
> >write protected memory.
>
> I don't think the solution is that complicated. Libsafe does this
> correctly. It has never killed a program that I know of doing
> something weird with alloca. Libsafe also is a LD_PRELOAD
> interceptor, which means it works with uninstrumented code just
> like valgrind.
I'm sure valgrind could be made to do it, perhaps with a seperate
skin. What my colleague tried to do was to do it using the existing
functionality in the memcheck/addrcheck skins without adding any
significant additional space/time overhead.
> Whenever there is a mov in a loop (memcpy & strcpy) the current
> stackframe can be watched to see if it gets overwritten. read,
> recv, recvfrom, etc, can also be watched to see if their results
> overwrite a return address.
There's a lot of things other than memcpy/strcpy that would cause
a mov in a loop - in fact they might often be a string op rather
than a mov but I guess you can count that as well. Spotting such
a thing sounds rather non-trivial though - most mov's may appear
to be in a loop if the scope in which you search for the loop is
wide enough, so presumably you only look fairly close to the mov
for the loop.
It would probably be easier for valgrind just to keep a shadow
stack of return addresses which is added to on call and popped
from on ret with a check that the address on that shadow stack
matches the real stack. That has fairly low overhead.
What will cause problems with that is setjmp/longjmp and other
non local control mechanisms such as signals and exceptions.
> If alloca does move the return address, I would think that a call
> to alloca can be identified and the "return address to watch"
> changed to the new address.
I think alloca is often inlined so spotting the calls may not be
possible. In fact I have a feeling it was mainly the MSVC version
of alloca that caused a problem where we were valgrinding Windows
applications under Wine.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Sebastian <sc...@nb...> - 2004-01-18 15:15:29
|
Hi *, Following the discussion a bit I am not sure watching the return address is useful at all. The stackframes with local variables yes, but the return address? The thing is, if you clobber the return address in normal operation in your program you will notice soon enough (ie there is no way not to notice) and valgrind will be of little use telling you. If you want to instrument your program to watch the return address for security measures, then the solution is much easier than watching the return address getting overwritten: keep a second stack and instrument all call*/ret* variants to update/check that stack, too. If they differ, one address changed. Or did I miss a use to monitor the saved return address? ciao, Sebastian -- -. sc...@nb... -. + http://segfault.net/~scut/ `--------------------. -' segfault.net/~scut/pgp `' 5453 AC95 1E02 FDA7 50D2 A42D 427E 6DEF 745A 8E07 `- GBU-31 blueprints available. payment >500k$. hi echelon! -----------------' |
|
From: Tom H. <th...@cy...> - 2004-01-18 15:26:33
|
In message <200...@nb...>
Sebastian <sc...@nb...> wrote:
> Following the discussion a bit I am not sure watching the return address is
> useful at all. The stackframes with local variables yes, but the return
> address?
>
> The thing is, if you clobber the return address in normal operation in your
> program you will notice soon enough (ie there is no way not to notice) and
> valgrind will be of little use telling you.
You're quite right that you will find out about a return address
overwrite fairly quickly anyway. The advantage of having valgrind
spot it is that you will be able to get a proper stacktrace because
it will spot it before the overwrite happens.
It doesn't of course help with the broader problem of overrunning
a stack variable without trashing the return address. That requires
a red zone between each variable which is why it needs padding to
be inserted at compile time.
Tom
--
Tom Hughes (th...@cy...)
Software Engineer, Cyberscience Corporation
http://www.cyberscience.com/
|
|
From: Nicholas N. <nj...@ca...> - 2004-01-19 22:09:20
|
On Sun, 18 Jan 2004, Tom Hughes wrote: > It would probably be easier for valgrind just to keep a shadow > stack of return addresses which is added to on call and popped > from on ret with a check that the address on that shadow stack > matches the real stack. That has fairly low overhead. > > What will cause problems with that is setjmp/longjmp and other > non local control mechanisms such as signals and exceptions. Nope, not easy at all; as you mention, due to longjmps. Also tail calls and stack switching complicate things. Not being able to match up function entries and exits (and the corresponding frame builds/tear-downs) was why I haven't managed to get Annelid to do stack checking, which is a real shame. N |