|
From: Jeremy F. <je...@go...> - 2005-03-09 02:04:23
|
Nicholas Nethercote wrote:
> fdleak_creat is new. The diff is:
>
> ! at 0x........: creat (in /...libc...)
> ! by 0x........: __libc_start_main (in /...libc...)
> ! by 0x........: ...
> --- 6,7 ----
> ! at 0x........: open (in /...libc...)
> ! by 0x........: main (fdleak_creat.c:18)
>
> ie. it looks like something has changed on my system so that libc's
> creat() no calls open(). So probably not a problem.
What's the context? I presume it ends up calling the same syscall? It
doesn't look like anything more framepointer backtrace confusion.
> I'm not sure if this was a good thing to do -- IIRC I original put
> that restriction in because some of the memory allocation functions
> use 0 to represent failure, and so if a program did mmap(0x0, FIXED)
> various problems could occur.
Valgrind does a mmap(0, FIXED) as part of its address space padding; in
general this is a legitimate but unusual operation. We could make it a
clo which is off by default, but I'm not terribly keen on adding another
special case clo. I guess a client request is another option (please
let me mmap 0).
What problems are you thinking of? Other problems occurring within
Valgrind, or just that a program can get itself into a mess which we
would detect too late?
> Another problem... this program:
>
> int main(void)
> {
> read(0,0,1);
> }
>
> behaves differently under Valgrind compared to native -- it doesn't
> wait for user input.
>
> The problem also arises from January 15, when you changed almost every
> use of the PRE_MEM_WRITE macro to your new SYS_PRE_MEM_WRITE macro.
> Did you write these new macros to address a particular problem? I
> don't like like this macro, because it assumes that any unaddressable
> argument causes the syscall to fail, which is not necessarily the
> case. And I'm not keen on the obvious fix -- change sys_read to use
> PRE_MEM_WRITE -- because I imagine that this
> non-failure-on-unaddressable-memory behaviour is possible on any
> number of the syscalls.
The specific problem I was trying to solve is where Valgrind crashes
with a SIGSEGV if you pass bogus arguments to a syscall. This isn't so
much a problem for simple buffers like read(), but it is if the memory
points to a structure which Valgrind inspects.
In this case, the read will fail either way, but it blocks first when
run natively. I guess there is the possibility that someone will map
memory under it while it is blocked so that it won't end up failing.
Rather than setting EFAULT, the alternative is for SYS_PRE_MEM_* to
return some flag saying "bad memory" to prevent any further tests on
it. This would complicate things, since it means the PRE and POST
wrappers would need to be made aware of it if they touch syscall memory.
As it is, there are possible races where a thread will remove memory
under a syscall anyway, so touching memory in a POST() function isn't
strictly safe, even if it was present in the PRE().
Is this read(fd, 0, 1) example from a real program? Do you think this
will cause a real problem? This case isn't particularly well defined,
and I think older kernels would have failed it immediately. I don't
like having variences from native behaviour, but I don't think this is
too serious.
J
|