User Stack Trace
Stone, Joshua I
joshua.i.stone@intel.com
Wed Apr 18 18:08:00 GMT 2007
grundy wrote:
> On Tue, Apr 17, 2007 at 03:39:58PM -0400, Frank Ch. Eigler wrote:
>> Or containing corrupt/malicious stack data?
> Now this is interesting. One would have to corrupt return address prior
> to the syscall we're tracing. They would have to know exactly what we're
> tracing (possible) because once that call started to return it would
> turn left into the lake (if we weren't probing that call).
The left turn can be avoided by simply not returning. :) A malicious
program might look something like:
int main() {
...
// Do whatever tricks to munge up the return address..
...
// Loop for a while, making calls that we hope get probed...
...
exit(0);
}
Then the stack walk is corrupted, but the program won't ever see it.
Or, for that matter, the program could just restore the correct return
address before it returns...
> I don't think there is an execution vulnerability, we just record the
> address. There is a chance of someone setting up a loop. Fake the second
> return address to point at the first return address which points at the
> second.
Are there checks to make sure the addresses are reasonable? I wonder if
a malicious program could also lead your stack walk astray -- perhaps
tricking you into printing a data value from some sensitive kernel area.
It looks like _stp_copy_from_user will make the right checks to make
sure that the address is within the user's address space. Your first
print in the loop reads head->ret directly though, where head =
nregs->ebp -- what if I faked my %ebp to point to kernel memory?
Or a more direct concern, even for non-malicious programs, what if the
memory at %ebp is paged out? This is unlikely, but it's still possible,
right? I think this first access to %ebp must be protected by a
_stp_copy_from_user as well.
I'm not sure how much this potential kernel-pointer problem needs to be
a concern though, as that compromised value is only returned to the
person running the script (who already has root access, and could
already write a script to access that value directly).
> In the jprobe code I based this on, I set an arbitrary depth limit of
> 20. Once you hit that bang out. So something like set a maximum depth
> variable to 20 or 30 and add this to the loop:
> while (--depth && head->ebp);
This is a must, to maintain our general SystemTap promise that scripts
will never get trapped in an infinite loop.
Josh
More information about the Systemtap
mailing list